// multiple connections in one process val jdbcUrl = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" val jdbcDriverClass = "org.h2.Driver" val db = Database.forURL(jdbcUrl, driver = jdbcDriverClass)
DB_CLOSE_DELAY=-1参数表明,直到虚拟机关闭位置,数据库的内容都将保留。
每一个数据库的操作,都会被包装成DBIO[T]操作,T是操作的返回类型
下面用裸的SQL演示了一个创建数据表的例子
1 2 3
val createAction: DBIO[Int] = sqlu"create table foo(name varchar)" val run: Future[Int] = db.run(createAction) Await.result(run, Duration(5, "seconds"))
// Creates DBIO actions using sqlu interpolator val createFoo: DBIO[Int] = sqlu"create table foo(name varchar)" val dropFoo: DBIO[Int] = sqlu"drop table foo"
// val selectFoo: DBIO[Seq[String]] = sql"select name from foo".as[String] definsertFoo(name: String): DBIO[Int] = sqlu"insert into foo values ($name)"
// Queries data from the database val selectFoo: DBIO[Seq[String]] = sql"select name from foo".as[String]
// Creates a composed action from other actions val composedAction: DBIO[Unit] = DBIO.seq( createFoo, insertFoo("air"), insertFoo("water"), selectFoo map { xs => xs foreach println }, dropFoo )
val jdbcUrl = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" val jdbcDriverClass = "org.h2.Driver" val db = Database.forURL(jdbcUrl, driver = jdbcDriverClass)
// Runs all statements of the composed action in a single transaction and waits for the result val run: Future[Unit] = db.run(composedAction)
import scala.concurrent.{Await, Future} import scala.concurrent.duration.Duration import scala.concurrent.ExecutionContext.Implicits.global import slick.jdbc.H2Profile.api._ objectDBextendsApp{ val jdbcUrl = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" val jdbcDriverClass = "org.h2.Driver" val db = Database.forURL(jdbcUrl, driver = jdbcDriverClass)
// Creates DBIO actions using sqlu interpolator val createFoo: DBIO[Int] = sqlu"create table foo(name varchar)" val dropFoo: DBIO[Int] = sqlu"drop table foo"
// val selectFoo: DBIO[Seq[String]] = sql"select name from foo".as[String] definsertFoo(name: String): DBIO[Int] = sqlu"insert into foo values ($name)"
// Queries data from the database val selectFoo: DBIO[Seq[String]] = sql"select name from foo".as[String]
importTables.{routes, areas} val createTables: DBIO[Unit] = (routes.schema ++ areas.schema).create val dropTables: DBIO[Unit] = (routes.schema ++ areas.schema).drop val insertArea: DBIO[Int] = { areas += Area(0, "Magic Wood", "Switzerland, Europe", 46.3347, 9.2612, "Hidden in the forest of the Avers valley there are some of the ...") // Same as INSERT INTO AREA(ID, NAME, LOCATION, LATITUDE, LONGTITUDE, DESCRIPTION) // VALUES (0, "Magic Wood", "Switzerland, Europe", 46.3347, 9.2612, "Hidden in the forest of the Avers valley there are some of the ...") }
默认情况下, 插入操作会返回收到影响的结果条数
当某列被设置成自增属性时,插入时会被忽略
下面是一个多行插入的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
definsertRoutes(areaId: Int): DBIO[Option[Int]] = { routes ++= Seq( Route(0, areaId, None, "Downunder", 46.3347, 9.2612, "Boulder, 7C+ at ..."), Route(0, areaId, None, "The Wizard", 46.3347, 9.2612, "Boulder, 7C at ..."), Route(0, areaId, None, "Master of a cow", 46.3347, 9.2612, "Boulder, 7C+ ...") ) }
val insertSampleData: DBIO[Int] = for { areaId <- insertAreaReturnId _ <- insertRoutes(areaId) } yield areaId
val res: Future[Int] = db.run(insertSampleData) res foreach println
执行DBIO操作时,返回的是Future,为了开启异步操作的支持,需要 mix in FutureSupport 这个trait
import org.scalatra._ import slick.jdbc.H2Profile.backend.Database importTables.allAreas import scala.concurrent.{ExecutionContext, Future} importDbSetup.createArea classMyScalatraServlet(db: Database) extendsScalatraServletwithFutureSupport{ //Mixes in the FutureSupport trait and defines an implicit ExecutionContext for handling the Futures overrideprotectedimplicitdefexecutor: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global
before("/*") { contentType = "text/html" }
get("/areas") {
newAsyncResult() { overrideval is: Future[_] = { db.run(allAreas map { areas => views.html.areas(areas) }) } } }
post("/areas") { val name = params.get("name").getOrElse(halt(BadRequest())) val location = params.get("location") getOrElse halt(BadRequest()) val latitude = params.getAs[Double]("latitude") getOrElse halt(BadRequest()) val longitude = params.getAs[Double]("longitude") getOrElse halt(BadRequest()) val description = params.get("description") getOrElse halt(BadRequest())
val trailAreasQuery = for { route <- routes if (route.routeName.toLowerCase like "%trail") area <- route.area } yield area
数据的修改
下面介绍的是更新和删除操作
使用也很简单
1 2 3 4 5 6 7
val updateAction = routes.filter(_.routeName === "Midnight Lightning") .map(r => r.description) .update("Midnight Lightning is a problem on the Columbia Boulder.")
val deleteAction = routes.filter(_.routeName === "Midnight Lightning").delete