目录
构建工程
连接池
Transaction
1) readOnly
2)autoCommit
3)localTx
查询API
更新API(增删改)
执行API(增删改)
批处理API(batch)
ScalikeJDBC是为Scala开发人员所打造的一款基于访问数据库的工具。提供易于使用且非常灵活的API。
ScalikeJDBC是一个实用且适合生产的产品。它在JDBC层上工作,由于大多数RDBMS都支持JDBC接口,因此我们可以以相同的方式访问RDBMS。本文初步介绍如果使用ScalikeJDBC操作MySQL。
官网 : http://scalikejdbc.org/
本文使用版本: jdk1.8
scala: 2.11.8
ScalikeJDBC : 3.3.2
使用Maven构建scala工程 ,导入依赖:
org.scalikejdbc
scalikejdbc_2.11
3.3.2
org.scalikejdbc
scalikejdbc-config_2.11
3.3.2
mysql
mysql-connector-java
5.1.47
根据需要写配置文件( src/main/resources/application.conf ):
# JDBC settings
db.default.driver="com.mysql.jdbc.Driver"
db.default.url="jdbc:mysql://localhost:3306/test"
db.default.user="root"
db.default.password="123"
# Connection Pool settings
db.default.poolInitialSize=10
db.default.poolMaxSize=20
db.default.connectionTimeoutMillis=1000
配置完之后 ,直接通过 import scalikejdbc._ 导入 。 并通过 scalikejdbc.config.DBs.setupAll() 方法载入配置,即可开始业务的编写了。
scalikeJDBC 默认的连接池实现是Apache Commons DBCP,使用连接只需调用 borrow()方法即可。
import scalikejdbc._
// 默认获取db.default配置的数据库的连接
val conn: java.sql.Connection = ConnectionPool.borrow()
// 获取db.named 配置的数据库的连接
val conn: java.sql.Connection = ConnectionPool('named).borrow()
最好通过借贷模式来操作连接池对象, ScalikeJDBC会把连接池对象封装成 scalikejdbc.DB 对象。DB对象会对每个操作分配一个session。 于是可以这样写:
using(DB(ConnectionPool.borrow())) { db =>
db.readOnly { implicit session =>
//TODO...
}
}
scalikeJDBC提供了更简便的写法(作用和上面的一模一样):
//调用default.db
DB.readOnly{implicit session =>
//TODO...
}
// 调用named.db
NamedDB('named).readOnly{implicit session =>
//TODO...
}
操作多个session :
using(DB(connectionPool.borrow())) { db =>
db.localTx { implicit session =>
//TODO ..
}
db.localTx { implicit session =>
//TODO ..
}
}
对DB对象有许多的Transacion操作:
以只读模式执行查询。update
只读模式下的操作会导致java.sql.SQLException
。
DB readOnly { implicit session =>
sql"select name from emp".map { rs => rs.string("name") }.list.apply()
}
在自动提交模式下执行查询/更新。
val count = DB autoCommit { implicit session =>
sql"update emp set name = ${name} where id = ${id}".update.apply()
}
在块范围的事务中执行查询/更新。如果在块中抛出异常,则事务将自动执行回滚。
val count = DB localTx { implicit session =>
// --- transcation scope start ---
sql"update emp set name = ${name1} where id = ${id1}".update.apply()
sql"update emp set name = ${name2} where id = ${id2}".update.apply()
// --- transaction scope end ---
}
注:在事务中不能调用其他 session 的方法时,若需要调用,应该在定义方法的时候使用AutoSession (namedDB则是NamedAutoSession):
def findById(id: Long)(implicit session: DBSession = AutoSession) =
sql"select id, name from members where id = ${id}"
.map(rs => rs.string("name")).single.apply()
例:
val name: Option[String] = DB readOnly { implicit session =>
sql"select name from emp where id = ${id}".map(rs => rs.string("name")).single.apply()
}
single:
返回匹配的单行作为Option
值。如果意外地返回多行,则将抛出运行时异常。
first:
返回匹配行的第一行作为Option
值。
list:
返回匹配的多行为scala.collection.immutable.List
。
foreach: 对返回的ResultSet做一定的操作:
DB readOnly { implicit session =>
sql"select name from emp".foreach { rs =>
println(rs.string("name"))
}
}
注: 查询返回的类为WrappedResultSet,可以自定义map中的函数, 在map中将取到的值封装成对象:
// 定义一个map的函数
def nameOnly(rs: WrappedResultSet)={
rs.string("name")
}
val name: Option[String] = DB readOnly { implicit session =>
sql"select name from emp where id = ${id}".map(nameOnly).single.apply()
}
// 建一个样例类来接收map的结果
case class Emp(id: String, name: String)
val emp: Option[Emp] = DB readOnly { implicit session =>
sql"select id, name from emp where id = ${id}"
.map(rs => Emp(rs.string("id"), rs.string("name"))).single.apply()
}
直接用update就行了
DB localTx { implicit session =>
sql"""insert into emp (id, name, created_at) values (${id}, ${name}, current_timestamp)"""
.update.apply()
val newId = sql"insert into emp (name, created_at) values (${name}, current_timestamp)"
.updateAndReturnGeneratedKey.apply()
sql"update emp set name = ${newName} where id = ${newId}".update.apply()
sql"delete emp where id = ${newId}".update.apply()
}
DB autoCommit { implicit session =>
sql"create table emp (id integer primary key, name varchar(30))".execute.apply()
}
//例子一
DB localTx { implicit session =>
val batchParams: Seq[Seq[Any]] = (2001 to 3000).map(i => Seq(i, "name" + i))
sql"insert into emp (id, name) values (?, ?)".batch(batchParams: _*).apply()
}
//例子二
DB localTx { implicit session =>
sql"insert into emp (id, name) values ({id}, {name})"
.batchByName(Seq(Seq('id -> 1, 'name -> "Alice"), Seq('id -> 2, 'name -> "Bob")):_*)
.apply()
}
//例子三
case class User(name:String,age:Int)
DB autoCommit { implicit session =>
val batchParams = user.map(u => Seq(u.name,u.age))
sql"insert into user(name , age) values (?, ?)".batch(batchParams: _*).apply()
}