你的位置:首页 > 操作系统

[操作系统]Gradle实战:执行sql操作hive数据库


查看原文:http://blog.csdn.net/u010818425/article/details/52490628

Gradle实战系列文章: 
《Gradle基本知识点与常用配置》 
《Gradle实战:Android多渠道打包方案汇总》 
《Gradle实战:不同编译类型的包同设备共存》 
《Gradle实战:发布aar包到maven仓库》


本文将介绍使用groovy+sql的脚本,实现从hive抓取数据,为方便理解,重要语句有详细注释,关键处已标明“关键点”;在阅读本文过程中,如对groovy还不是很熟悉的读者可以查看《 Gradle基本知识点与常用配置》这篇文章


入门例子

Gradle简单操作mysql数据库


import groovy.sql.Sql class GroovySqlExample1{   static void main(args) {     sql = Sql.newInstance("jdbc:mysql://localhost:3306/tablename", "account", "password", "org.gjt.mm.mysql.Driver")     sql.eachRow("select * from tablename"){       row | println row.word_id + " " + row.spelling + " " + row.part_of_speech       //“row”表示查询到的每一行数据,“row.word_id”表示“word_id”这个字段的值    }   } }

这是一个使用Gradle操作mysql数据库的入门例子,配置好数据库地址、驱动、账号、密码就可以执行sql语句操作数据库了,但是现在越来越多的公司都转向使用分布式存储,以下我们来详细介绍一下Gradle操作hive数据库的实例(当然,你需要有这样一个数据库环境)。



实战例子

以获取udid(设备唯一识别码)为例,条件是:1、近两周内打开过我们app(即我们后台系统有其访问记录),我们认为这些是活跃用户;2、满足条件1的各城市用户中,各取20%的用户。以下分为5各部分来讲述我们的实现方案:sql脚本、配置文件、groovy代码、使用方法、数据产出。


1. getUdid.sql中的sql脚本:

首先,新建一个android工程,无需任何java代码;然后在module中新建一个名为“getUdid.sql“的文件,里面存放的就是我们用于查询数据库的sql脚本;但这个脚本还可以通过gradle运行过程中动态拼接一些参数,下文会有介绍。


SELECT count(DISTINCT udid) AS allCount FROM tablename WHERE dt>=date_sub(current_date,14);SELECT DISTINCT udid FROM tablename WHERE dt>=date_sub(current_date,14)

2. hive.properties中的配置数据

再在module中新建一个名为“hive.properties“的配置文件,用于存放连接数据库所需的相关参数。


HiveUrl=jdbc:hive2://host:port/basename?useUnicode=true&characterEncoding=utf8 Account=xxxPassword=xxxDriver=org.apache.hive.jdbc.HiveDriver //连接hive所用的驱动

注:上述的HiveUrl中,scheme使用的是hive2,因此与其配套的驱动是org.apache.hive.jdbc.HiveDriver,如果使用的是早期的hive,则scheme是hive,其配套的驱动是org.apache.hadoop.hive.jdbc.HiveDriver


3. groovy代码:


import groovy.sql.Sql  //关键点1apply plugin: 'java'apply plugin: 'groovy'apply plugin: 'maven'repositories {  mavenCentral()}configurations {  driver  //关键点2}dependencies {  driver 'org.apache.hive:hive-jdbc:2.1.0' //数据库连接驱动依赖,关键点3}//数据库连接驱动下载,关键点4URLClassLoader loader = GroovyObject.class.classLoaderconfigurations.driver.each { File file ->  loader.addURL(file.toURL()) }task run << {  def File propFile = new File('hive.properties') //“hive.properties”为自定义的配置文件,上文有介绍  if (propFile.canRead()) {    def Properties props = new Properties()    props.load(new FileInputStream(propFile))    if (props != null && props.containsKey('HiveUrl') && props.containsKey('Account')         && props.containsKey('Password') && props.containsKey('Driver')) {       //从配置文件中读取各参数      String hiveUrl = props['HiveUrl']//数据库地址      String account = props['Account']//访问数据库的账号      String password = props['Password']//密码      String driver = props['Driver'] //连接数据库的驱动类名      String os = System.properties['os'] //读取命令行设置的手机系统类型(设置见下文“使用方法”中的命令行)      String ver = System.properties['ver']//读取命令行设置的app版本号(设置见下文“使用方法”中的命令行)      def sql = Sql.newInstance(hiveUrl, account, password, driver)//建立数据库连接,关键点5      String udidName = "udid_" //存放udid的文件名      String summaryName = "summary_" //存放各城市概况的文件名      if (os.equals("Android")) {        udidName += "android.txt"        summaryName += "android.txt"      } else {        udidName += "ios.txt"        summaryName += "ios.txt"      }      String dirPath = getRootDir().toString() + '/result/' //结果存放路径      def dir = new File(dirPath)      if (!dir.exists()) {        dir.mkdirs()      }      String udidPath = dirPath + '/' + udidName //udid文件路径      String summaryPath = dirPath + '/' + summaryName //各城市概况文件路径      def udidFile = new File(udidPath)      def summaryFile = new File(summaryPath)      if (udidFile.exists()) {        udidFile.delete()      }      udidFile.createNewFile()      if (summaryFile.exists()) {        summaryFile.delete()      }      summaryFile.createNewFile()      def resultPrintWriter = udidFile.newPrintWriter()      def summaryPrintWriter = summaryFile.newPrintWriter()       //制表      summaryPrintWriter.write('\n')      summaryPrintWriter.write(os + "用户情况")      summaryPrintWriter.write('\n')      summaryPrintWriter.write('-------------------')      summaryPrintWriter.write('\n')      summaryPrintWriter.write(" 城市" + "  总数" + " 抽取")      summaryPrintWriter.write('\n')      summaryPrintWriter.write('-------------------')      summaryPrintWriter.write('\n')      def citys = ['北京市', '上海市', '广州市', '深圳市']      int allcount = 0 // 活跃用户总数      int allExtracted = 0 // 抽取20%的用户数      try {         //各个城市遍历        citys.each {          city ->            resultPrintWriter.write(city + ':')            resultPrintWriter.write('\n')            resultPrintWriter.write('--------------------------------------')            resultPrintWriter.write('\n')            boolean isGetCount = true            int num = 0             // 读取sql脚本,每句以分号分隔,下方还需动态拼接参数            new File('getUdid.sql').text.split(";").each { //“getUdid.sql”里面为查询udid的sql语句,下文有介绍              sqlTemp ->                 //动态拼接参数                String sqlString = sqlTemp +                    ' AND city=' + "'" + city + "'" +                    ' AND os=' + "'" + os + "'" +                    ' AND ver=' + "'" + ver + "'"                 if (isGetCount) { // 执行第一句sql,获取该城市总活跃用户中的20%                  println sqlString                  sql.eachRow(sqlString) { // 执行sql,关键点6                    num = it.allcount * 0.2 // 总数的20%                    allcount += it.allcount                    allExtracted += num                     //制表                    summaryPrintWriter.write(city + " " + it.allcount + getCount(it.allcount) + num)                    summaryPrintWriter.write('\n')                    summaryPrintWriter.write('-------------------')                    summaryPrintWriter.write('\n')                  }                  isGetCount = false                } else { // 执行第二句sql,获取该城市总活跃用户数前20%的udid                  sqlString = sqlString + " LIMIT " + num // 取前num个数据,动态拼接条件                  println sqlString                  sql.eachRow(sqlString) { // 执行sql                    if (it.udid != null && it.udid != '') {                      resultPrintWriter.write(it.udid + ",")                      resultPrintWriter.write('\n')                    }                  }                }            }            resultPrintWriter.write('--------------------------------------')            resultPrintWriter.write('\n')        }         //制表        summaryPrintWriter.write(" 累计 " + " " + allcount + getCount(allcount) + " " + allExtracted)        summaryPrintWriter.write('\n')        summaryPrintWriter.write('-------------------')        summaryPrintWriter.write('\n')        summaryPrintWriter.write("统计日期:" + releaseTime())        summaryPrintWriter.write('\n')      } catch (Exception e) {        println e.message      }       //关闭打印      resultPrintWriter.flush()      summaryPrintWriter.flush()      resultPrintWriter.close()      summaryPrintWriter.close()    }  }}//获取系统时间def releaseTime() {  return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))}//模拟制表符,用于summary文件里面制作表格String getCount(i) {  int temp = i  int count = 0  while (temp > 0) {    temp = temp / 10    count++  }  String space = ''  if (count == 1) {    space = "   "  } else if (count == 2) {    space = "  "  } else if (count == 3) {    space = "  "  } else if (count == 4) {    space = " "  }  return space}

4. 使用方法

本地需安装Gradle且配置环境变量;然后打开终端,按以下步骤输入命令(第一次执行会下载hive数据库驱动,耗时较长):

  • 进入到工程目录下(假设module名为executeSql):

    cd executeSql
  • 抓取android数据:

    gradle run -Dos='Android' -Dver='1.0.0'
  • 抓取iOS数据:

    gradle run -Dos='iPhone OS' -Dver='2.0.0'

    注:上述命令中,“-D”表示设置参数,在groovy代码中有接收参数的语句String os = System.properties['os']

以android为例,开始执行后,每个城市都会执行以下两句sql,即上述gradle脚本动态拼接成的sql:


SELECT count(DISTINCT udid) AS allCount FROM tablename WHERE dt>=date_sub(current_date,14) AND city='北京市' AND os='Android' AND ver='1.0.0';SELECT DISTINCT udid FROM tablename WHERE dt>=date_sub(current_date,14) AND city='北京市' AND os='Android' AND ver='1.1.0' LIMIT 2000

5. 数据产出

数据产出为两个文件,一个是各城市用户的总体情况,另一个是各城市用户z红20%的udid数据列表;

  • 各城市用户情况,summary_android.txt

    Android用户情况------------------- 城市  总数 抽取-------------------北京市 10000 2000-------------------上海市 20000 4000-------------------广州市 30000 6000-------------------深圳市 40000 8000------------------- 累计 100000 20000-------------------统计日期:2016-09-09
  • 各城市udid,udid_summary.txt(仅作示意)

    北京市:--------------------------------------00123456-2c9c-4ab7-a256-4b86a2490318,00234567-f9fb-4059-a1b8-49514fb17ac0,...--------------------------------------上海市:--------------------------------------00345678-4910-4db5-b82c-42f85450c85c,00456789-1047-470c-9bf2-af326fdac7f1,...--------------------------------------广州市:--------------------------------------01234567-d69f-40fa-aabd-88ac19f542cf,02345678-b1c2-4005-a418-f6d1704b7f81,...--------------------------------------深圳市:--------------------------------------03456789-0413-4cd1-9214-8544a07eecec,04567891-4ac2-49cd-a1c8-f49c5edd9d9b,...--------------------------------------

深入学习

  • Groovy 操作mysql数据库
  • 实战 Groovy: 用 Groovy 进行 JDBC 编程
  • Hive:用Java代码通过JDBC连接Hiveserver

查看原文:http://blog.csdn.net/u010818425/article/details/52490628





韩国特价旅游韩国旅游时间韩国旅游跟团现在去韩国旅游多少钱韩国旅游几月份最好2015南京圣诞节去哪玩?_2015南京圣诞节好去处推荐 畅游武安古武当山 兔屎茶“解酒?各国闻所未闻的奇葩解酒法(全文) 67450 海南欢乐节去玩吗?第15届海南欢乐节优惠景点有哪些? 67451 海南欢乐节有什么好玩的?第十五届海南欢乐节节目介绍? 67452 “新世界7大奇观城市”出炉 黎巴嫩首都居首(全文) 67453 看奇幻魔界 听野人传说 67454 2015南京冰雪奇缘圣诞主题展举办时间、地点、门票以及活动详情怎么样? 67455 海南欢乐节有什么活动?2015海南欢乐节活动介绍? 67456 禁止使用硬币购物?世界八国最奇葩规定(全文) 6745 “融和粤菜”取之于自然,食之于丽轩[三] 澳门有哪些美食 冰岛旅游花费及注意事项 国庆长假去西藏洗涤心灵吧 2015泰国购物全攻略 盘点中国三大死海 不只是国外才有死海 夏天去哪里旅游凉快 中国夏天哪里凉快 夏天哪里旅游好 盘点全球最美的25个人间仙境(图) 亚洲十大新兴旅行圣地介绍 这个夏天不容错过(图) 世界十处濒临消失的美景,必须马上出发 四川峨眉山红叶,满山彩林入仙境 新加坡旅游注意事项 韩国旅游签证注意事宜以及怎么样办理 TLRME17TP(T) Datasheet TLRME17TP(T) Datasheet TLRME20CP Datasheet TLRME20CP Datasheet TLRME20CP(F) Datasheet TLRME20CP(F) Datasheet 天津周边一日游 天津周边一日游 天津周边一日游 爱琴海在哪里 爱琴海在哪里 爱琴海在哪里 天津周边旅游 天津周边旅游 天津周边旅游