slick 2使用mappedColumn映射多个到一个关系

时间:2014-09-21 09:10:50

标签: scala slick-2.0

我试图用光滑的方式映射我的课程,所以我可以坚持下去。 我的业务对象以这种方式定义

case class Book(id : Option[Long], author : Author, title : String, readDate : Date, review : String){}
case class Author(id : Option[Long], name : String, surname : String) {}

然后我定义了"表"作者类:

class Authors(tag : Tag) extends Table[Author](tag,"AUTHORS") {
    def id = column[Option[Long]]("AUTHOR_ID", O.PrimaryKey, O.AutoInc)
    def name = column[String]("NAME")
    def surname = column[String]("SURNAME")
    def * = (id, name, surname) <> ((Author.apply _).tupled , Author.unapply)
}

对于书籍:

class Books (tag : Tag) extends Table[Book](tag, "BOOKS") {
    implicit val authorMapper = MappedColumnType.base[Author, Long](_.id.get, AuthorDAO.DAO.findById(_))

    def id = column[Option[Long]]("BOOK_ID", O.PrimaryKey, O.AutoInc)
    def author = column[Author]("FK_AUTHOR")
    def title = column[String]("TITLE")
    def readDate = column[Date]("DATE")
    def review = column[Option[String]]("REVIEW")

    def * = (id, author, title, readDate, review) <> ((Book.apply _).tupled , Book.unapply)
}

但是当我编译时我得到了这个错误

Error:(24, 51) No matching Shape found.
Slick does not know how to map the given types.
Possible causes: T in Table[T] does not match your * projection. Or you use an unsupported type in a Query (e.g. scala List).
Required level: scala.slick.lifted.FlatShapeLevel
Source type: (scala.slick.lifted.Column[Option[Long]], scala.slick.lifted.Column[model.Author], scala.slick.lifted.Column[String], scala.slick.lifted.Column[java.sql.Date], scala.slick.lifted.Column[Option[String]])
Unpacked type: (Option[Long], model.Author, String, java.sql.Date, String)
Packed type: Any
def * = (id, author, title, readDate, review) <> ((Book.apply _).tupled , Book.unapply)
                                              ^

还有这一个:

Error:(24, 51) not enough arguments for method <>: (implicit evidence$2: scala.reflect.ClassTag[model.Book], implicit shape: scala.slick.lifted.Shape[_ <: scala.slick.lifted.FlatShapeLevel, (scala.slick.lifted.Column[Option[Long]], scala.slick.lifted.Column[model.Author], scala.slick.lifted.Column[String], scala.slick.lifted.Column[java.sql.Date], scala.slick.lifted.Column[Option[String]]), (Option[Long], model.Author, String, java.sql.Date, String), _])scala.slick.lifted.MappedProjection[model.Book,(Option[Long], model.Author, String, java.sql.Date, String)].
Unspecified value parameter shape.
def * = (id, author, title, readDate, review) <> ((Book.apply _).tupled , Book.unapply)
                ^

这里的错误是什么? 我没有得到什么光滑的东西? 提前谢谢!

2 个答案:

答案 0 :(得分:1)

Ende Neu 的答案比问题中描述的用例更具知识性和相关性,可能是更正确和正确的答案。

以下仅仅是我所做的一个观察,可能通过回答这个问题来帮助 tmnd91

  

这里的错误是什么?

我注意到了:

case class Book( ... review : String){}

与:

不匹配
def review = column[Option[String]]("REVIEW")

应该是:

def review = column[String]("REVIEW")

答案 1 :(得分:1)

Slick不是ORM,因此没有从外键到实体的自动映射,问题已多次询问SO(herehere只是为了命名两个)。

让我们暂时假设你想要做的事情是可能的:

implicit val authorMapper = 
  MappedColumnType.base[Author, Long](_.id.get, AuthorDAO.DAO.findById(_))

所以你告诉投影使用行id并获取与该id相关的实体,在你的情况下有三个问题,首先你不处理失败(id.get),其次是你的主键是可选的(不应该是)。

第三个问题是光滑将以一种单独的方式获取每个实体,我的意思是,你执行一些查询并获得100本书,光滑将使100个其他查询只获取相关实体,性能明智是自杀,你完全绕过了具有最佳性能的SQL层(连接),只能缩短你的DAO。

幸运的是,这似乎不可能,映射器通过光滑用于非支持类型(例如,不必显式使用函数的不同日期格式)或者在获取/插入行时注入格式转换,请查看有关如何使用joins的文档(取决于您的版本)。