我发现play2的动画的行解析器取决于jdbc驱动程序返回的元数据。
所以在播放中提供的内置示例“zentasks”中,我可以找到这样的代码:
object Project { val simple = { get[Pk[Long]]("project.id") ~ get[String]("project.folder") ~ get[String]("project.name") map { case id~folder~name => Project(id,folder,name) } } }
请注意,这些字段都有一个项目。字首。
它在h2数据库上运行良好,但不适用于postgresql。如果我使用portgresql,我应该写成:
object Project { val simple = { get[Pk[Long]]("id") ~ get[String]("folder") ~ get[String]("name") map { case id~folder~name => Project(id,name) } } }
我问过this in play’s google group,而纪尧姆博特说:
Yes if you are using postgres it’s probably the cause. The postgresql
jdbc driver is broken and doesn’t return table names.
如果postgresql的jdbc驱动程序真的有这个问题,我认为anorm会有一个问题:
如果两个表具有相同名称的字段,并且我使用join来查询它们,则anorm将无法获取正确的值,因为它找不到哪个名称属于哪个表。
所以我写了一个测试。
1.在postgresql上创建表
create table a ( id text not null primary key,name text not null ); create table b ( id text not null primary key,name text not null,a_id text,foreign key(a_id) references a(id) on delete cascade );
2.创建anorm模型
case class A(id: Pk[String] = NotAssigned,name: String) case class B(id: Pk[String] = NotAssigned,name: String,aId: String) object A { val simple = { get[Pk[String]]("id") ~ get[String]("name") map { case id ~ name => A(id,name) } } def create(a: A): A = { DB.withConnection { implicit connection => val id = newId() sql(""" insert into a (id,name) values ( {id},{name} ) """).on('id -> id,'name -> a.name).executeUpdate() a.copy(id = Id(id)) } } def findAll(): Seq[(A,B)] = { DB.withConnection { implicit conn => sql(""" select a.*,b.* from a as a left join b as b on a.id=b.a_id """).as(A.simple ~ B.simple map { case a ~ b => a -> b } *) } } } object B { val simple = { get[Pk[String]]("id") ~ get[String]("name") ~ get[String]("a_id") map { case id ~ name ~ aId => B(id,name,aId) } } def create(b: B): B = { DB.withConnection { implicit conneciton => val id = UUID.randomUUID().toString sql(""" insert into b (id,a_id) values ( {id},{name},{aId} ) """).on('id -> id,'name -> b.name,'aId -> b.aId).executeUpdate() b.copy(id = Id(id)) } } }
3.测试用例
class ABTest extends DbSuite { "AB" should "get one-to-many" in { running(fakeApp) { val a = A.create(A(name = "AAA")) val b1 = B.create(B(name = "BBB1",aId = a.id.get)) val b2 = B.create(B(name = "BBB2",aId = a.id.get)) val ab = A.findAll() ab foreach { case (a,b) => { println("a: " + a) println("b: " + b) } } } } }
4.输出
a: A(dbc52793-0f6f-4910-a954-940e508aab26,BBB1) b: B(dbc52793-0f6f-4910-a954-940e508aab26,BBB1,4a66ebe7-536e-4bd5-b1bd-08f022650f1f) a: A(d1bc8520-b4d1-40f1-af92-52b3bfe50e9f,BBB2) b: B(d1bc8520-b4d1-40f1-af92-52b3bfe50e9f,BBB2,4a66ebe7-536e-4bd5-b1bd-08f022650f1f)
您可以看到“a”的名称为“BBB1 / BBB2”,但不是“AAA”。
我试图用前缀重新定义解析器:
val simple = { get[Pk[String]]("a.id") ~ get[String]("a.name") map { case id ~ name => A(id,name) } }
但是它会报告他们找不到指定字段的错误。
这是一个很大的问题吗?还是我想念的东西?