版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/whgyxy/article/details/88740651
Scala 操作数据库(查询、插入、更新)
Scala操作数据库需要载入 java.sql.DriverManager ,我们分为查询和插入两个模块进行,每个模块也分为一条记录和多条记录来操作
首先,需要导入必须的信息,定义你要访问的JDBC地址和你的表名
import java.sql.DriverManager
import org.joda.time.DateTime
import scala.collection.mutable
object JDBCTest {
// 你要访问的表名
val cacheTable = "test_table" // table schema (create_time:bigint, key:text, result:text)
// 你的JDBC地址,这里以postgre数据库为例
val jdbcUrl = "jdbc:postgresql://ip:port/database_name?user=user_name&password=user_password"
def main(args: Array[String]): Unit = {
}
}
其中,joda模块是一个巨好用的时间模块,需要在pom文件中加入依赖
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.2</version>
</dependency>
joda时间模块非常友好,这是joda的官网地址 https://www.joda.org/joda-time/ ,因为本文中create_time需要用到时间戳,如果不想用joda,可以直接使用系统时间函数 System.currentTimeMillis() / 1000来写入时间戳。关于joda还有个比较完整的时间模块的封装,可以直接上手调用 Scala中时间处理org.joda.time.DateTime工具 ,下面开始正文
查询一条记录
/**
* 查询一条记录,根据key查询一条记录
*
* @param key 查询Key
* @return 没有记录-返回null,多条记录-返回最新的,一条记录-返回本条
*/
def getResult(key: String): String = {
val curJdbcUrl = jdbcUrl
val resultList = new mutable.ArrayBuffer[(Long, String)]
val conn = DriverManager.getConnection(curJdbcUrl)
try {
val statement = "select create_time, result from " + cacheTable + " where key=?"
val prep = conn.prepareStatement(statement)
prep.setString(1, key)
val rs = prep.executeQuery()
while (rs.next()) {
resultList.append((rs.getLong("create_time"), rs.getString("result")))
}
}
finally {
conn.close()
}
val resultListSorted = resultList.sortWith((x, y) => x._1 > y._1)
if (resultList.isEmpty) null else resultListSorted.head._2
}
插入一条记录
/**
* 插入一条记录
*
* @param key 插入的key
* @param result 插入的result
*/
def putResult(key: String, result: String): Unit = {
val curJdbcUrl = jdbcUrl
val fieldNum = 3
val placeholder = ("?" * fieldNum).mkString(",")
val indexTableSql = s"insert into $cacheTable values($placeholder)"
val conn = DriverManager.getConnection(curJdbcUrl)
try {
if (getResult(key) == null) {
val prep = conn.prepareStatement(indexTableSql)
prep.setLong(1, new DateTime().getMillis / 1000)
prep.setString(2, key)
prep.setString(3, result)
prep.executeUpdate()
}
}
finally {
conn.close()
}
}
更新一条记录
/**
* 更新库表中的一条记录
*
* @param key 更新的key
* @param result 更新的result
*/
def updateResult(key: String, result: String): Unit = {
val curJdbcUrl = jdbcUrl
val indexTableSql = s"update $cacheTable set result = ? where key = ?"
val conn = DriverManager.getConnection(curJdbcUrl)
try {
if (getResult(key) != null) {
val prep = conn.prepareStatement(indexTableSql)
prep.setString(1, result)
prep.setString(2, key)
prep.executeUpdate()
}
}
finally {
conn.close()
}
}
下面开始查询多个key,或者插入多个key的操作
批量查询
/**
* 查询多个secKey对应的结果
*
* @param keys 要查询的key数组
* @return Map[key, result],如果一个key对应多条记录,result为最新的记录
*/
def getBatchResult(keys: Array[String]): mutable.Map[String, String] = {
val curJdbcUrl = jdbcUrl
val resultList = new mutable.ArrayBuffer[(Long, String, String)]
val conn = DriverManager.getConnection(curJdbcUrl)
try {
val keysStr = "'" + keys.mkString("','") + "'"
val statement = "select create_time, result, key from " + cacheTable + " where key in (" + keysStr + ") order by create_time desc"
val prep = conn.prepareStatement(statement)
val rs = prep.executeQuery()
while (rs.next()) {
resultList.append((rs.getLong("create_time"), rs.getString("result"), rs.getString("key")))
}
}
finally {
conn.close()
}
val key2ResultMap = new mutable.HashMap[String, String]
for (record <- resultList) {
if (!key2ResultMap.contains(record._3))
key2ResultMap.put(record._3, record._2)
}
if (key2ResultMap.size < keys.length) {
val remain = keys.toSet -- key2ResultMap.keySet
remain.foreach(key => key2ResultMap.put(key, null))
}
key2ResultMap
}
插入多条记录
/**
* 插入多条记录
*
* @param keys 要插入的keys数组
* @param results 要插入的result数组
*/
def putBatchResult(keys: Array[String], results: Array[String]): Unit = {
val curJdbcUrl = jdbcUrl
val fieldNum = 3
val placeholder = ("?" * fieldNum).mkString(",")
val indexTableSql = s"insert into $cacheTable values($placeholder)"
val conn = DriverManager.getConnection(curJdbcUrl)
try {
for (i <- keys.indices) {
if (getResult(keys(i)) == null) {
val prep = conn.prepareStatement(indexTableSql)
prep.setLong(1, new DateTime().getMillis / 1000)
prep.setString(2, keys(i))
prep.setString(3, results(i))
prep.executeUpdate()
}
}
}
finally {
conn.close()
}
}