1

我正在尝试用光滑的方式映射我的班级,这样我就可以坚持下去。我的业务对象是这样定义的

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)
                ^

这里有什么错误?我对光滑有什么误解?先感谢您!

4

2 回答 2

1

Ende Neu的答案与问题中描述的用例更加相关,并且可能是更正确和正确的答案。

以下只是我所做的一个观察,它可能通过回答问题对tmnd91有所帮助:

这里有什么错误?

我注意到:

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

不匹配:

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

它应该是:

def review = column[String]("REVIEW")
于 2014-09-21T10:45:08.677 回答
1

Slick 不是 ORM,因此没有从外键到实体的自动映射,这个问题已经在 SO 上被问过很多次(这里仅举两个例子)

让我们假设您尝试做的事情是可能的:

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

因此,您要告诉投影使用行 ID 并获取与该 ID 相关的实体,在您的情况下存在三个问题,首先您不处理故障(id.get),其次您的主键是可选的(不应该是)。

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

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

于 2014-09-21T11:11:50.217 回答