slick 2使用mappedColumn将多个映射到一种关系 [英] slick 2 mapping many to one relationship with mappedColumn

查看:107
本文介绍了slick 2使用mappedColumn将多个映射到一种关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

i'm trying to map my class with slick so i can persist them. My business objects are defined this way

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

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

Then I defined the "table" class for authors:

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

但是当我编译时会出现此错误

But when I compile i get this error

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

这是什么错误? 我对滑油没什么了解? 预先谢谢你!

What's the mistake here? What am I not getting about slick? Thank you in advance!

推荐答案

Slick不是ORM,因此没有从外键到实体的自动映射,因此在SO上已经问了很多遍了(此处仅举两个).

Slick is not an ORM so there's no auto mapping from a foreign key to an entity, the question has been asked many times on SO (here, here just to name two).

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

Let's assume for a moment that what you are trying to do is possible:

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

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

So you are telling the projection to use the row id and fetch the entity related to that id, there are three problems in your case, first you don't handle failures (id.get), second you primary key is optional (which shouldn't be).

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

The third problem is that slick will fetch each entity in a separate way, what I mean by this is, you execute some query and get 100 books, slick will make 100 other queries only to fetch the related entity, performance wise is suicide, you are completely bypassing the SQL layer (joins) which has the best performance only to have the possibility of shortening your DAOs.

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

Fortunately this doesn't seem to be possible, mappers are used for non supported types by slick (for example different date formats without having to explicitly using functions) or to inject format conversion when fetching/inserting rows, have a look at the documentation on how to use joins (depending on your version).

这篇关于slick 2使用mappedColumn将多个映射到一种关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆