ScalikeJDBC
Just write SQL and get things done!
http://scalikejdbc.org/ 를 보면 scalikejdbc는 ScalikeJDBC is a tidy SQL-based DB access library for Scala developers 라고 설명하고 있다.
즉, scala에서 JDBC를 쉽게 사용할 수 있도록 도와주는 Library 이다.
scalikejdbc는 다음의 Dependencies 가지고 있다.
- JDBC Drivers you need
- Commons DBCP
- Joda Time 2.x
- SLF4J API
내가 사용할 JDBC driver와 Commons DBCP를 기본 베이스로 하고 있다. 그리고 JodaTime, SLF4J를 사용한다.
1.Simple Sample
scalikejdbc를 사용해 가장 간단하게 코드를 작성해 볼 것이다.
우선 기본적으로 필요한 dependency는 아래와 같다.
libraryDependencies ++= Seq(
"org.scalikejdbc" % "scalikejdbc_2.11" % "2.5.0",
"mysql-connector-java" % "mysql" % "5.1.40"
)
scalikejdbc 버전은 2.5를 사용할 것이고 (scala 2.11) DB는 mysql을 사용한다.
import java.sql.DriverManager
import scalikejdbc._
object ScalikejdbcSample extends App {
// init JDBC driver
Class.forName("com.mysql.jdbc.Driver")
// Simple Connection
using(DB(DriverManager.getConnection(JDBCInfo.URL, JDBCInfo.ID, JDBCInfo.PW))) { db =>
val id: Option[String] = db readOnly { implicit session =>
SQL("SELECT id, age FROM user LIMIT 1").map(rs => rs.string("id")).single.apply()
}
println("id: " + id.get)
}
}
import scalikejdbc._
object ScalikejdbcSample extends App {
// init JDBC driver
Class.forName("com.mysql.jdbc.Driver")
// Simple Connection
using(DB(DriverManager.getConnection(JDBCInfo.URL, JDBCInfo.ID, JDBCInfo.PW))) { db =>
val id: Option[String] = db readOnly { implicit session =>
SQL("SELECT id, age FROM user LIMIT 1").map(rs => rs.string("id")).single.apply()
}
println("id: " + id.get)
}
}
가장 먼저 JDBC Driver를 등록하고 Connection Pool없이 driver에서 connection을 직접 가져와서 사용한 예제이다.
간단하다.
2.Connection pool
scalikejdbc는 Commons DBCP로 connection pool을 사용한다.
사용방법이 매우 간단하다.
ConnectionPool.singleton() 메소드를 호출하면 된다. 그리고 ConnectionPool에서 borrow()를 통해 가져다 사용하면 되는 구조다.
심지어 DB object를 통해 자동으로 borrow() 코드없이 사용이 가능하다.
Connection Pool 세팅 변경을 하고 싶다면 singleton 으로 생성할때 ConnectionPoolSettings를 생성해 파라미터로 추가하면된다.
물론 필수사항이 아니며 default값이 자동 세팅 된다.
import scalikejdbc._
object ScalikejdbcConnectionPool extends App {
val settings = ConnectionPoolSettings(
initialSize = 5,
maxSize = 20,
connectionTimeoutMillis = 3000L,
validationQuery = "SELECT 1"
)
Class.forName("com.mysql.jdbc.Driver")
ConnectionPool.singleton(JDBCInfo.URL, JDBCInfo.ID, JDBCInfo.PW, settings) // Apache Commons DBCP by default.
// borrow from pool
using(DB(ConnectionPool.borrow())) { db =>
val id: Option[String] = db readOnly { implicit session =>
SQL("SELECT id FROM user LIMIT 1").map(rs => rs.string("id")).single.apply()
}
println("id: " + id.get)
}
// simpler
val id: Option[String] = DB readOnly { implicit session =>
SQL("SELECT id FROM user LIMIT 1").map(rs => rs.string("id")).single.apply()
}
println("id: " + id.get)
}
object ScalikejdbcConnectionPool extends App {
val settings = ConnectionPoolSettings(
initialSize = 5,
maxSize = 20,
connectionTimeoutMillis = 3000L,
validationQuery = "SELECT 1"
)
Class.forName("com.mysql.jdbc.Driver")
ConnectionPool.singleton(JDBCInfo.URL, JDBCInfo.ID, JDBCInfo.PW, settings) // Apache Commons DBCP by default.
// borrow from pool
using(DB(ConnectionPool.borrow())) { db =>
val id: Option[String] = db readOnly { implicit session =>
SQL("SELECT id FROM user LIMIT 1").map(rs => rs.string("id")).single.apply()
}
println("id: " + id.get)
}
// simpler
val id: Option[String] = DB readOnly { implicit session =>
SQL("SELECT id FROM user LIMIT 1").map(rs => rs.string("id")).single.apply()
}
println("id: " + id.get)
}
3.Multiple DB
scalikejdbc는 물론 하나의 application에서 여러 DB를 사용할 수 있다.
방법은 ConnectionPool.add 를 통해 이름을 지정하여 connection pool을 만드는 것이다.
그리고 커넥션을 가져올 때 NamedDB("DB name")을 사용하여 어떤 pool에서 커넥션을 가져올 지 선택한다.
import scalikejdbc._
object ScalikejdbcMultiple extends App {
Class.forName("com.mysql.jdbc.Driver");
ConnectionPool.add("pro", JDBCInfo.URL, JDBCInfo.ID, JDBCInfo.PW)
ConnectionPool.add("dev", JDBCInfo.URL2, JDBCInfo.ID, JDBCInfo.PW)
val id: Option[String] = NamedDB("dev") readOnly { implicit session =>
SQL("SELECT id FROM user LIMIT 1").map(rs => rs.string("id")).single.apply()
}
println("id: " + id.get)
}
object ScalikejdbcMultiple extends App {
Class.forName("com.mysql.jdbc.Driver");
ConnectionPool.add("pro", JDBCInfo.URL, JDBCInfo.ID, JDBCInfo.PW)
ConnectionPool.add("dev", JDBCInfo.URL2, JDBCInfo.ID, JDBCInfo.PW)
val id: Option[String] = NamedDB("dev") readOnly { implicit session =>
SQL("SELECT id FROM user LIMIT 1").map(rs => rs.string("id")).single.apply()
}
println("id: " + id.get)
}
4.AutoSession
지금도 충분히 간단하지만 더 간단하게 사용할 수 있다.
위 구조를 보면 DB에서 readonly 커넥션을 가져와서 해당 세션을 가지고 SQL()로 쿼리를 실행하는 구조다
이 부분을 SQL()을 제외하고 모두 생략하는 방법이 가능하다.
import scalikejdbc._
object ScalikejdbcAutoSession extends App {
Class.forName("com.mysql.jdbc.Driver")
ConnectionPool.singleton(JDBCInfo.URL, JDBCInfo.ID, JDBCInfo.PW)
// simple auto session
implicit val session: DBSession = AutoSession
val id = SQL("SELECT id FROM user WHERE age=?").bind(20).map(rs => rs.string(1)).single.apply()
println("id: " + id.get)
// auto session by method
println("id: " + find(20).get)
// AutoSession: readOnly -> executeQuery(), autoCommit -> execute()
def find(age: Int)(implicit session: DBSession = AutoSession): Option[String] = {
SQL("SELECT id FROM user WHERE age=?").bind(age).map(rs => rs.string(1)).single.apply()
}
}
object ScalikejdbcAutoSession extends App {
Class.forName("com.mysql.jdbc.Driver")
ConnectionPool.singleton(JDBCInfo.URL, JDBCInfo.ID, JDBCInfo.PW)
// simple auto session
implicit val session: DBSession = AutoSession
val id = SQL("SELECT id FROM user WHERE age=?").bind(20).map(rs => rs.string(1)).single.apply()
println("id: " + id.get)
// auto session by method
println("id: " + find(20).get)
// AutoSession: readOnly -> executeQuery(), autoCommit -> execute()
def find(age: Int)(implicit session: DBSession = AutoSession): Option[String] = {
SQL("SELECT id FROM user WHERE age=?").bind(age).map(rs => rs.string(1)).single.apply()
}
}
implicit val session: DBSession = AutoSession 을 통해 Session을 implicit 시킨 후 SQL를 사용할 수 있다.
메소드 단위로 설정할 수 있고, object 전체 단위로 설정이 가능하다.
'Language > Scala' 카테고리의 다른 글
Mac OSX Brew 설치 & SBT 설치 (0) | 2017.01.28 |
---|---|
IntelliJ로 Scala Maven 프로젝트 만들기 (0) | 2016.11.13 |