文档

§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 #3016SqlQuery 案例类被重构为带有伴生对象的特征。
因此,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")
)

新的 foldfoldWhile 函数用于处理结果流。

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

二进制和大型数据也可以用作参数。

JVM JDBC
Array[Byte] Long varbinary
Blob1 Blob
InputStream2 Long varbinary
Reader3 Long varchar

其他

下一步:将插件迁移到模块


发现此文档中的错误?此页面的源代码可以在 此处 找到。在阅读 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?请访问 我们的社区论坛,与社区开始对话。