SparkSql将数据源Hive中数据导入MySql实例

6 篇文章 0 订阅
5 篇文章 0 订阅

背景:能看到这篇博客的伙计儿,应该是充分理解了[理想是丰满的 现实是骨感]  这句名言了吧。

为啥子这么说呢,那就是 不就是个SparkSql从hive导入到mysql吗!

有什么技术含量,但是呢 不断地踩坑ing填坑ing。

废话不多说,直接上硬菜。

package com.test
import java.sql.{Connection, DriverManager, PreparedStatement}
import java.text.{DateFormat, SimpleDateFormat}
import java.util.{Calendar, Properties}
import org.apache.spark.rdd.{JdbcRDD, RDD}
import org.apache.spark.sql.{Row, SQLContext, SaveMode}
import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.sql.types._
import org.apache.spark.{SparkConf, SparkContext}


object hiveToMysql {

   def main(args: Array[String]) {
      var list: List[String] = List[String]()
      //初始化SparkContext
      val conf = new SparkConf().setAppName("hiveToMysql")
      val sc: SparkContext = new SparkContext(conf)
      val hc=new HiveContext(sc)

      val scoreRdd = new JdbcRDD(sc, () => {
         Class.forName("com.mysql.jdbc.Driver").newInstance()
         DriverManager.getConnection("jdbc:mysql://ip:3306/databases", username, password)
      }, "select id,score from tables where is_delete=? and age=?", 0, 0, 15, r => r.getString(1) + "," + r.getString(2))
      val scoreStr:String=scoreRdd.map(_.split(",")(1)).collect().mkString(",")

      val threeSql="SELECT id,name,age,score,grades FROM db.hivetables " +
        "where score in (" + scoreStr + ")"
      val data=hc.sql(threeSql).map(line=>{
          Row(java.lang.Long.getLong("1"),
		  line.getLong(0),
		  stringUtil.filterOffUtf8Mb4(line.getString(1)),
		  Integer.valueOf(line.getString(2)), 
		  Integer.valueOf(line.getString(3)),
		  line.getByte(4))
      })

      val schema=StructType( List(
         StructField("mid", LongType, false),
         StructField("id", LongType, false),
         StructField("name", StringType, true),
         StructField("age", IntegerType, true),
         StructField("score", IntegerType, true),
         StructField("grades", ByteType, true),
      ))
      val url = "jdbc:mysql://ip:3306/databases?user=test&password=test&useUnicode=true"
      val table ="tables"
      val df=hc.createDataFrame(data,schema)
      df.insertIntoJDBC(url,table,true)

      println("导入数据完成!!!")
      sc.stop()
   }
}

一下是踩过的坑,以及解决方案:

1、jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '0' for key 'PRIMARY'错误
今天在运行写好的项目时报了这么一个错误(主键重复,0主键已经存在)。。。后来检查了一下数据库,数据库中表User的id属性已设置为自增,而我在HQL语句中把user.id(主键)写进去企图更新它?所以去掉对主键的更新语句后运行正常。
2、com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column "name" cannot be null,
引起这个的原因是表示,name主键的列不能为null值。
3、spark-数据类型
http://www.aboutyun.com/thread-11575-1-1.html
4、DataFrame类中提供了很多写数据库的操作,本例中的createJDBCTable就是可以创建表,它的函数原型如下:
def createJDBCTable(url: String, table: String, allowExisting: Boolean): Unit
table是表的名字,最后一个参数是如果表存在是否删除表的意思,false代表不删除。
DataFrame类中还有insertIntoJDBC方法,调用该函数必须保证表事先存在,它只用于插入数据,函数原型如下:
def insertIntoJDBC(url: String, table: String, overwrite: Boolean): Unit
前面两个参数和createJDBCTable一致,第三个参数如果设置为true,则在插入数据之前会调用mysql的TRUNCATE TABLE语句先清掉表中的数据。
5、Spark RDD写入RMDB(Mysql)方法二
6、java.lang.ClassCastException:java.lang.Byte cannot be cast to java.lang.Long
不能将Byte转换为Long类型
解决方法:java.lang.Long.getLong(String.valueOf(line.getByte(1)))
7、java.sql.SQLException: Incorrect string value: '\xF4\x80\xB3\x8A \xE6...' for column 'content' at row 1
https://blog.csdn.net/wangchangshuai0010/article/details/12714575
数据格式问题
8、java.sql.SQLException: Column count doesn't match value count at row 1
错误原因:在插入数据时,插入的字段个数跟数据库表字段个数不一致
insert into student(sno,sname,sage,ssex) values(1,'张三','man');
解决办法:保证插入数据字段个数跟数据库表中的字段个数一致
9、java过滤非汉字的utf8的字符
https://www.aliyun.com/jiaocheng/847138.html
 

好了。

愿世界和平 哈哈哈~

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用以下两种方法将Hive数据导入MySQL: 1. 使用Sqoop导出数据MySQL Sqoop是一个开源工具,用于在Hadoop和关系型数据库间进行数据传输。以下是导出数据MySQL的示例命令: ``` sqoop export \ --connect jdbc:mysql://mysql_host:port/mysql_database \ --username mysql_username \ --password mysql_password \ --table mysql_table \ --export-dir hive_table \ --input-fields-terminated-by ',' \ --input-lines-terminated-by '\n' \ --input-null-string '\\N' \ --input-null-non-string '\\N' ``` 其mysql_host是MySQL主机名或IP地址,port是MySQL端口号,mysql_database是MySQL数据库名称,mysql_username和mysql_password是MySQL登录凭据,mysql_table是要导入MySQL表名,hive_table是要导出的Hive表名。 2. 使用Hive自定义输出格式将数据导出到MySQL Hive支持自定义输出格式,可以将数据输出为文本文件,并使用LOAD DATA命令将其导入MySQL。以下是使用Hive自定义输出格式将数据导出到MySQL的示例命令: ``` INSERT OVERWRITE DIRECTORY '/tmp/hive_output' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' SELECT * FROM hive_table; LOAD DATA LOCAL INFILE '/tmp/hive_output' INTO TABLE mysql_table FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'; ``` 其hive_table是要导出的Hive表名,mysql_table是要导入MySQL表名。在第一条命令,将数据输出为以逗号分隔的文本文件,存储在/tmp/hive_output目录。在第二条命令,使用LOAD DATA命令将文本文件导入MySQL。请注意,LOAD DATA命令需要在MySQL客户端执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值