使用ScalikeJDBC操作MySQL

目录

构建工程

连接池

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 ..
  }
}

Transaction

对DB对象有许多的Transacion操作:

1) readOnly

以只读模式执行查询。update只读模式下的操作会导致java.sql.SQLException

DB readOnly { implicit session =>
  sql"select name from emp".map { rs => rs.string("name") }.list.apply()
}

2)autoCommit

在自动提交模式下执行查询/更新。

val count = DB autoCommit { implicit session =>
  sql"update emp set name = ${name} where id = ${id}".update.apply()
}

3)localTx

在块范围的事务中执行查询/更新。如果在块中抛出异常,则事务将自动执行回滚。

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()

查询API

例:

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()
}

更新API(增删改)

直接用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()
}

执行API(增删改)

DB autoCommit { implicit session =>
  sql"create table emp (id integer primary key, name varchar(30))".execute.apply()
}

批处理API(batch)

//例子一
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()
}

 

你可能感兴趣的:(java/scala)