§Anorm
Anorm 已从 Play 的核心代码中分离出来,成为一个独立管理的项目,拥有自己的生命周期。要添加对它的依赖项,请使用
libraryDependencies += "org.playframework.anorm" %% "anorm" % "2.6.7"
完整的列表可以在此处找到:https://mvnrepository.com/artifact/org.playframework.anorm/anorm
Anorm 的 2.4.0 版本需要 Java 8。与 JDK 1.6 或 1.7 兼容的最后一个版本是 Anorm 2.3.9。
§变更
新的 Anorm 版本包含各种修复和改进。
根据 BatchSQL #3016,SqlQuery
案例类被重构为带有伴生对象的特征。
因此,BatchSql
现在通过传递一个原始语句来创建,该语句在内部进行验证。
import anorm.BatchSql
// Before
BatchSql(SqlQuery("SQL")) // No longer accepted (won't compile)
// Now
BatchSql("SQL")
// Simpler and safer, as SqlQuery is created&validated internally
§解析
现在可以使用列索引从 Row
中获取值。
val res: (String, String) = SQL("SELECT * FROM Test").map(row =>
row[String](1) -> row[String](2) // string columns #1 and #2
)
无论标签是名称还是别名,现在都统一了按标签解析列。
val res: (String, Int) = SQL"SELECT text, count AS i".map(row =>
row[String]("text") -> row[Int]("i")
)
新的 fold
和 foldWhile
函数用于处理结果流。
val countryCount: Either[List[Throwable], Long] =
SQL"Select count(*) as c from Country".fold(0l) { (c, _) => c + 1 }
val books: Either[List[Throwable], List[String]] =
SQL("Select name from Books").foldWhile(List[String]()) { (list, row) =>
foldWhile(List[String]()) { (list, row) =>
if (list.size == 100) (list -> false) // stop with `list`
else (list := row[String]("name")) -> true // continue with one more name
}
新的 withResult
函数用于提供自定义流解析器。
import anorm.{ Cursor, Row }
@annotation.tailrec
def go(c: Option[Cursor], l: List[String]): List[String] = c match {
case Some(cursor) => {
if (l.size == 100) l // custom limit, partial processing
else {
val row = it.next()
go(it, l :+ row[String]("name"))
}
}
case _ => l
}
val books: Either[List[Throwable], List[String]] =
SQL("Select name from Books").withResult(go(_, List.empty[String]))
§类型映射
提供了更多参数和列转换。
数组
如果列的类型是 JDBC 数组 (java.sql.Array
),则该列可以是多值。现在 Anorm 可以将其映射到数组或列表 (Array[T]
或 List[T]
),前提是元素类型 (T
) 也在列映射中支持。
import anorm.SQL
import anorm.SqlParser.{ scalar, * }
// array and element parser
import anorm.Column.{ columnToArray, stringToArray }
val res: List[Array[String]] =
SQL("SELECT str_arr FROM tbl").as(scalar[Array[String]].*)
还提供了用于数组的新便捷解析函数,例如 SqlParser.array[T](...)
和 SqlParser.list[T](...)
如果 JDBC 语句需要数组参数 (java.sql.Array
),则其值可以作为 Array[T]
传递,只要元素类型 T
是支持的类型。
val arr = Array("fr", "en", "ja")
SQL"UPDATE Test SET langs = $arr".execute()
多值参数
现在可以将 List[T]
、Set[T]
、SortedSet[T]
、Stream[T]
和 Vector[T]
作为多值参数传递。
SQL("SELECT * FROM Test WHERE cat IN ({categories})")
.on('categories -> List(1, 3, 4))
SQL("SELECT * FROM Test WHERE cat IN ({categories})")
.on('categories -> Set(1, 3, 4))
SQL("SELECT * FROM Test WHERE cat IN ({categories})")
.on('categories -> SortedSet("a", "b", "c"))
SQL("SELECT * FROM Test WHERE cat IN ({categories})")
.on('categories -> Stream(1, 3, 4))
SQL("SELECT * FROM Test WHERE cat IN ({categories})")
.on('categories -> Vector("a", "b", "c"))
数值和布尔类型
针对基本类型(如数值和布尔类型)的列转换已得到改进。
已删除一些无效的转换。
列(JDBC 类型) | (as) JVM/Scala 类型 |
---|---|
Double |
Boolean |
Int |
Boolean |
新增了一些转换,扩展了对列的支持。
列(JDBC 类型) | (as) JVM/Scala 类型 |
---|---|
BigDecimal |
BigInteger |
BigDecimal |
Int |
BigDecimal |
Long |
BigInteger |
BigDecimal |
BigInteger |
Int |
BigInteger |
Long |
Boolean |
Int |
Boolean |
Long |
Boolean |
Short |
Byte |
BigDecimal |
Float |
BigDecimal |
Int |
BigDecimal |
Long |
Int |
Short |
BigDecimal |
二进制和大型数据
为二进制列(字节、流、Blob)提供了新的列转换,可将其解析为 Array[Byte]
或 InputStream
。
↓JDBC / JVM➞ | Array[Byte] | InputStream1 |
---|---|---|
Array[Byte] | 是 | 是 |
Blob2 | 是 | 是 |
Clob3 | 否 | 否 |
InputStream4 | 是 | 是 |
Reader5 | 否 | 否 |
-
- 类型
java.io.InputStream
。
- 类型
-
- 类型
java.sql.Blob
。
- 类型
-
- 类型
java.sql.Clob
。
- 类型
-
- 类型
java.io.Reader
。
- 类型
二进制和大型数据也可以用作参数。
JVM | JDBC |
---|---|
Array[Byte] | Long varbinary |
Blob1 | Blob |
InputStream2 | Long varbinary |
Reader3 | Long varchar |
-
- 类型
java.sql.Blob
- 类型
-
- 类型
java.io.InputStream
- 类型
-
- 类型
java.io.Reader
- 类型
其他
- Joda Time:从
Long
、Date
或Timestamp
列中转换 JodaInstant
或DateTime
的新转换。 - 将文本列解析为
UUID
值:SQL("SELECT uuid_as_text").as(scalar[UUID].single)
。 - 传递
None
作为可空参数已弃用,必须使用类型安全的Option.empty[T]
代替。
下一步:将插件迁移到模块
发现此文档中的错误?此页面的源代码可以在 此处 找到。在阅读 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?请访问 我们的社区论坛,与社区开始对话。