2. Anorm のコンセプト
ドキュメントに明確に宣言されている
Anorm は ORM ではない
生 JDBC はつらい、よりよい API としての Anorm API
DB アクセスの DSL は SQL がベスト
SQL を生成する type safe DSL は誤った方向性だ
ORM と格闘するより SQL 書いた方がコスト小さい
3. Anorm API 利用例 1
import anorm._
implicit val conn: java.sql.Connection = ...
// insert
SQL(“insert into emp values ({id},{name},{age})”)
.on(‘id -> 1, ‘name -> “Andy”, ‘age -> 19)
.executeUpdate()
// update
SQL(“update emp set name = {name} where id = {id}”)
.on(‘id -> 1, ‘name -> “Brian”)
.executeUpdate()
4. Anorm API 利用例 2
// select
case class Emp(id: Pk[Int], name: String, age: Option[Int])
import anorm.SqlParser._
val emp: RowParser[Emp] = get[Pk[Int]](“id”)
~ get[String](“name”)
~ get[Option[Int]](“age”) map {
case id ~ name ~ age => Emp(id, name, age)
}
val emps: List[Emp] = SQL(“select * from emp”).as(emp.*)
val emp: Option[Emp] = SQL(“select * from emp where id = {id}”)
.on(‘id -> 1).as(emp.singleOpt)
5. Anorm は Play 非依存
JDBC を隠蔽した使いやすい API を提供することを目的にし
ていて Play 本体に依存していない
コネクションやトランザクションの管理はスコープ外
拙作の実例(scalikejdbc-with-anorm20.g8)
Play アプリだけでなく、ちょっとした DB アクセスが必要な
場合にも便利に使える
10. Anorm API 利用例 3
case class Emp(id: Pk[Int], name: String, age: Option[Int])
val sql: SqlQuery = SQL(“select * from emp where id = {id}”)
val query: SimpleSql[Row] = sql.on(‘id -> 1)
val stream: Stream[Row] = query.apply()
stream map { row =>
Emp(row[Pk[Int]]("id"), row[String]("name"), row[Option[Int]]("age"))
}
11. SqlParser.scala
SqlParser の API が RowParser を返すので、それを「 」
メソッドの呼び出しで結合して使う感じ
SqlParser.get[T](String): RowParser[T]
SqlParser.str(String): RowParser[String]
中置型 case class [+A, +B](_1: A, _2: B)
RowParser[A]# [B](RowParser[B]): RowParser[A B]
12. Anorm API 利用例 4
case class Emp(id: Pk[Int], name: String, age: Option[Int])
import anorm.SqlParser._
val rp: RowParser[Pk[Int] ~ String ~ Option[Int]]
= get[Pk[Int]](“id”) ~ get[String](“name”) ~ get[Option[Int]](“age”)
val emp: RowParser[Emp] = rp map {
case id ~ name ~ age => Emp(id, name, age)
}
val opt: ResultSetParser[Option[Emp]] = emp.singleOpt
val list: ResultSetParser[List[Emp]] = emp.*
13. SqlStatementParser.scala
JavaTokenParsers を extends したパーザーコンビネータ
な実装クラス
select id,name,age from emp where id = {id} and name
= {name} のような SQL からバインド変数名({id}、
{name})を順序付きで取り出す処理
2.0 時点では Sql.sql(String) でのみ使用