I/O ACTIONS
2015-06-17 21:55
246 查看
1.DB操作中的IO
Anything that you can execute on a database, whether it is a getting the result of a query (myQuery.result),
creating a table (myTable.schema.create), inserting data (myTable += item)
or something else, is an instance of DBIOAction,
parameterized by the result type it will produce when you execute it.
Database I/O Actions can be combined with several different combinators (see the DBIOAction
class andDBIO object for
details), but they will always be executed strictly sequentially and (at least conceptually) in a single database session.
In most cases you will want to use the type aliases :DBIO[R]]DBIO and :StreamingDBIO[R,T]]StreamingDBIO for
non-streaming and streaming Database I/O Actions. They omit the optional effect types supported by DBIOAction.
2.Database I/O Actions的执行结果
DBIOActions can be executed either with the goal of producing a fully materialized result or
streaming data back from the database.
3.执行过程
Tag:
Execution of the action starts when run is called, and the materialized
result is returned as a Futurewhich is completed asynchronously as soon as the result is available:
4.Streaming风格操作DB
Collection-valued queries also support streaming results. In this case, the actual collection type is ignored and elements are streamed directly from the result set through a Reactive
Streams Publisher, which can be processed and consumed by Akka
Streams.
Execution of the DBIOAction does not start until a Subscriber is
attached to the stream. Only a singleSubscriber is supported, and any further attempts
to subscribe again will fail. Stream elements are signaled as soon as they become available in the streaming part of the DBIOAction.
The end of the stream is signaled only after the entire action has completed. For example, when streaming inside a transaction and all elements have been delivered successfully, the stream can still fail afterwards if the transaction cannot be committed.
对于依赖结果集状态的类型可以使用mapResult进行处理,而不必wait
When streaming a JDBC result set, the next result page will be buffered in the background
5.Transactions and Pinned Sessions
When executing a DBIOAction which is composed of several smaller
actions, Slick acquires sessions from the connection pool and releases them again as needed so that a session is not kept in use unnecessarily while waiting for the result from a non-database computation (e.g. the function passed to ((R)⇒DBIOAction[R2,S2,E2])(ExecutionContext):DBIOAction[R2,S2,EwithE2]]flatMap that
determines the next Action to run). All DBIOAction
combinators which combine two database actions without any non-database computations in between (e.g. (DBIOAction[R2,S2,E2]):DBIOAction[R2,S2,EwithE2]]andThen or (DBIOAction[R2,NoStream,E2]):DBIOAction[(R,R2),NoStream,EwithE2]]zip)
can fuse these actions for more efficient execution, with the side-effect that the fused action runs inside a single session. You can use ]withPinnedSession to
force the use of a single session, keeping the existing session open even when waiting for non-database computations.
There is a similar combinator called ]transactionally to
force the use of a transaction. This guarantees that the entire DBIOAction that
is executed will either succeed or fail atomically.
Warning
Failure is not guaranteed to be atomic at the level of an individual DBIOAction that
is wrapped withtransactionally, so you should not apply error recovery combinators at that point.
An actual database transaction is inly created and committed / rolled back for the outermost transactionallyaction.
注意一下警告的内容:
在分开的DBIOACTION操作中,失败是无法保证完整性(会被分割),所以不能应用错误的连接符(即不能把错误通过连接符连接起来),一个事务务必在最外层的transactionally action
6.JDBC Interoperability
Anything that you can execute on a database, whether it is a getting the result of a query (myQuery.result),
creating a table (myTable.schema.create), inserting data (myTable += item)
or something else, is an instance of DBIOAction,
parameterized by the result type it will produce when you execute it.
Database I/O Actions can be combined with several different combinators (see the DBIOAction
class andDBIO object for
details), but they will always be executed strictly sequentially and (at least conceptually) in a single database session.
In most cases you will want to use the type aliases :DBIO[R]]DBIO and :StreamingDBIO[R,T]]StreamingDBIO for
non-streaming and streaming Database I/O Actions. They omit the optional effect types supported by DBIOAction.
2.Database I/O Actions的执行结果
DBIOActions can be executed either with the goal of producing a fully materialized result or
streaming data back from the database.
3.执行过程
val q = for (c <- coffees) yield c.name val a = q.result val f: Future[Seq[String]] = db.run(a) f.onSuccess { case s => println(s"Result: $s") }
Tag:
Execution of the action starts when run is called, and the materialized
result is returned as a Futurewhich is completed asynchronously as soon as the result is available:
4.Streaming风格操作DB
Collection-valued queries also support streaming results. In this case, the actual collection type is ignored and elements are streamed directly from the result set through a Reactive
Streams Publisher, which can be processed and consumed by Akka
Streams.
Execution of the DBIOAction does not start until a Subscriber is
attached to the stream. Only a singleSubscriber is supported, and any further attempts
to subscribe again will fail. Stream elements are signaled as soon as they become available in the streaming part of the DBIOAction.
The end of the stream is signaled only after the entire action has completed. For example, when streaming inside a transaction and all elements have been delivered successfully, the stream can still fail afterwards if the transaction cannot be committed.
val q = for (c <- coffees) yield c.name val a = q.result val p: DatabasePublisher[String] = db.stream(a) // .foreach is a convenience method on DatabasePublisher. // Use Akka Streams for more elaborate stream processing. p.foreach { s => println(s"Element: $s") }
对于依赖结果集状态的类型可以使用mapResult进行处理,而不必wait
When streaming a JDBC result set, the next result page will be buffered in the background
val q = for (c <- coffees) yield c.image val a = q.result val p1: DatabasePublisher[Blob] = db.stream(a) val p2: DatabasePublisher[Array[Byte]] = p1.mapResult { b => b.getBytes(0, b.length().toInt) }
5.Transactions and Pinned Sessions
When executing a DBIOAction which is composed of several smaller
actions, Slick acquires sessions from the connection pool and releases them again as needed so that a session is not kept in use unnecessarily while waiting for the result from a non-database computation (e.g. the function passed to ((R)⇒DBIOAction[R2,S2,E2])(ExecutionContext):DBIOAction[R2,S2,EwithE2]]flatMap that
determines the next Action to run). All DBIOAction
combinators which combine two database actions without any non-database computations in between (e.g. (DBIOAction[R2,S2,E2]):DBIOAction[R2,S2,EwithE2]]andThen or (DBIOAction[R2,NoStream,E2]):DBIOAction[(R,R2),NoStream,EwithE2]]zip)
can fuse these actions for more efficient execution, with the side-effect that the fused action runs inside a single session. You can use ]withPinnedSession to
force the use of a single session, keeping the existing session open even when waiting for non-database computations.
There is a similar combinator called ]transactionally to
force the use of a transaction. This guarantees that the entire DBIOAction that
is executed will either succeed or fail atomically.
Warning
Failure is not guaranteed to be atomic at the level of an individual DBIOAction that
is wrapped withtransactionally, so you should not apply error recovery combinators at that point.
An actual database transaction is inly created and committed / rolled back for the outermost transactionallyaction.
val a = (for { ns <- coffees.filter(_.name.startsWith("ESPRESSO")).map(_.name).result _ <- DBIO.seq(ns.map(n => coffees.filter(_.name === n).delete): _*) } yield ()).transactionally val f: Future[Unit] = db.run(a)
注意一下警告的内容:
在分开的DBIOACTION操作中,失败是无法保证完整性(会被分割),所以不能应用错误的连接符(即不能把错误通过连接符连接起来),一个事务务必在最外层的transactionally action
6.JDBC Interoperability
val getAutoCommit = SimpleDBIO[Boolean](_.connection.getAutoCommit)
In order to drop down to the JDBC level for functionality that is not available in Slick, you can use a SimpleDBIO action which is run on a database thread and gets access to the JDBC Connection:
相关文章推荐
- Linux 命令 wget
- Android开机广播android.intent.action.BOOT_COMPLETED
- poj 1141 Brackets Sequence(区间dp)
- 关于vs2010 error: LNK1123: failure during conversion to COFF: file invalid or corrupt 错误的解决...
- chrome内核浏览器缓存资源找回方法
- 一级二级域名设置测试txt记录(spf记录)pass
- 黑马程序员------File及IO流
- awk应用-支票簿的结算
- java tcp
- 第二次冲刺——第3天
- 易买网之smartupload实现文件上传
- Apache Phoenix开发实践(1)
- centos7设置IP
- 第二次冲刺——第2天
- 黑马程序员------内部类
- 推荐系统笔记
- 2015061704 - 方法返回值状态码
- HBase简述
- Spring 总结
- j2se学习笔记-IO_2 转换流