我这里采用了两种方式:
第一种:java的jdbc
第二种:scalikejdbc
我都在代码中使用了,做了详细的解释
原始文件数据在前两篇的博客中:spark中将数据写进json文件
里可以看到,需求也能看到
import java.util
import java.util.Properties
import bean.BaobiaoSchema
import com.google.gson.Gson
import config.ConfigHelp
import org.apache.spark.SparkConf
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, Row, SaveMode, SparkSession}
import scalikejdbc.{DB, SQL}
import scalikejdbc.config.DBs
import utils.UtilsATPKpi
import scala.collection.mutable.ListBuffer
object Baobiao {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("bb").setMaster("local[*]")
val spark = SparkSession.builder().config(conf).getOrCreate()
import spark.implicits._
val rdd: RDD[String] = spark.sparkContext.textFile(args(0))
val rddall: RDD[Array[String]] = rdd.map(_.split("\\|",-1))
//val rddha: RDD[Array[String]] = rddall.filter(arr => arr(3).contains("哈"))
//这里面使用了自定义的工具类
val rddlist: RDD[(String, ListBuffer[Int])] = rddall.map(x => {
(x(3), UtilsATPKpi.makeKpi(x))
})
/*
不使用工具类代码如下:
val rddlist: RDD[(String, ListBuffer[Int])] = rddall.map(x => {
val list: ListBuffer[Int] = new ListBuffer[Int]
list.append(1)
if (x(17).contains("车载主机") || x(17).contains("无线传输单元")
|| x(17).contains("应答器信息接收单元") || x(17).contains("轨道电路信息读取器")
|| x(17).contains("测速测距单元") || x(17).contains("人机交互接口单元")
|| x(17).contains("列车接口单元") || x(17).contains("司法记录单元")) {
list.append(1)
} else {
list.append(0)
}
if (x(17).contains("车载主机")) {
list.append(1)
} else {
list.append(0)
}
if (x(17).contains("无线传输单元")) {
list.append(1)
} else {
list.append(0)
}
if (x(17).contains("应答器信息接收单元")) {
list.append(1)
} else {
list.append(0)
}
if (x(17).contains("轨道电路信息读取器")) {
list.append(1)
} else {
list.append(0)
}
if (x(17).contains("测速测距单元")) {
list.append(1)
} else {
list.append(0)
}
if (x(17).contains("人机交互接口单元")) {
list.append(1)
} else {
list.append(0)
}
if (x(17).contains("列车接口单元")) {
list.append(1)
} else {
list.append(0)
}
if (x(17).contains("司法记录单元")) {
list.append(1)
} else {
list.append(0)
}
list
(x(3), list))
})
*/
val rddresult: RDD[(String, ListBuffer[Int])] = rddlist.reduceByKey((x, y)=>x.zip(y).map(k=>k._1 + k._2))
//rddresult.foreach(println(_))
val rddrow: RDD[Row] = rddresult.map(x =>
Row(x._1, x._2(0), x._2(1), x._2(2), x._2(3), x._2(4), x._2(5), x._2(6), x._2(7), x._2(8), x._2(9))
)
//dataframe写入数据库 方式1:java中的jdbc,没有采用配置文件
//需要的配置信息是:url,user,password,表名,driver
val prop = new Properties()
val url = "jdbc:mysql://localhost:3306/baobiao?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf-8"
val table = "baobiaotest"
prop.setProperty("driver","com.mysql.cj.jdbc.Driver")
//prop.put("user","root")
//prop.put("password","123456")
prop.setProperty("user","root")
prop.setProperty("password","123456")
frame.write.mode(SaveMode.Overwrite).jdbc(url,table,prop)
//dataframe写入数据库,方式2:java中的jdbc,用到了配置文件
//要让配置文件起作用,必须写一个类,类中定义了属性的值必须是配置文件中的key(配置文件的内容是KV格式的)
//这个定义的类中主要起作用的是定义的Config对象,是通过ConfigFactory.load()方法获得的
//在被类中可以通过类名.属性,来获取配置文件的数据
val prop = new Properties()
prop.setProperty("user",ConfigHelp.user)
prop.setProperty("password",ConfigHelp.password)
prop.setProperty("driver",ConfigHelp.driver)
val table = "baobiaotest"
//第一个参数是:URL;第二个参数是:表名;第三个参数是properties对象,对象中带有:user,password,driver信息
frame.write.mode(SaveMode.Overwrite).jdbc(ConfigHelp.url,table,prop)
//dataframe写入数据库,方式3:使用scalikejdbc
DBs.setup()
rddresult.foreach(x=>{
DB.localTx{implicit sess=>
SQL("insert into baobiaotest values(?,?,?,?,?,?,?,?,?,?,?)")
.bind(x._1, x._2(0), x._2(1), x._2(2), x._2(3), x._2(4), x._2(5), x._2(6), x._2(7), x._2(8), x._2(9))
.update()
.apply()
}
})
spark.stop()
}
}