6

如何使用 Anorm 将 a 传递JsObjectjsonPostgreSQL 9.3 数据库中的数据类型字段,而不必将其转换为字符串?

给定一个 PostgreSQL 9.3 表,例如:

create table profiles
(
  id serial primary key,
  profile json null
);

使用 Play 2.2,此测试成功:

package helpers

import anorm._
import org.specs2.mutable._
import org.specs2.runner._
import org.junit.runner._
import play.api.db.DB
import play.api.libs.json._
import play.api.test._

@RunWith(classOf[JUnitRunner])
class AnormTest extends Specification {
  "AnormTest" should {
    "insert a JSON object" in new WithApplication {
      val profile = Json.obj("language" -> "en")
      val sql = SQL("insert into profiles (profile) values (CAST({profile} AS json))")
        .on("profile" -> profile.toString)
      DB.withConnection { implicit c => sql.execute() }
    }
  }
}

但是随着这些行的改变:

      val sql = SQL("insert into profiles (profile) values ({profile})")
        .on("profile" -> profile)

它会产生此错误:

org.postgresql.util.PSQLException: 
Can't infer the SQL type to use for an instance of play.api.libs.json.JsObject. 
Use setObject() with an explicit Types value to specify the type to use.

由于使用 Anorm 我们通常传递适当的数据类型而不是文本(例如,数据类型UUID列的对象),因此必须将其转换为字符串并将其转换回SQL 语句中的数据类型uuid并不是最佳选择。JsObjectjson

有关此问题及其解决方法的示例,请参阅在 Play Framework 2.1-RC1 中使用 PostgreSQL 的原生 JSON 支持

JsObject为了将直接作为json数据类型传递,如何使用 Anorm 避免这种情况?

4

1 回答 1

8

对于 Play 2.4 及更高版本,请直接使用 anorm.Object(value: org.postgresql.util.PGobject) 类而不是 value:

val pgObject = new org.postgresql.util.PGobject();
pgObject.setType("json");
pgObject.setValue(profile);
val sql = SQL("insert into profiles (profile) values ({profile})")
    .on("profile" -> anorm.Object(pgObject))
于 2014-09-10T19:33:37.117 回答