【问题标题】:Custom column (Object) type in SlickSlick 中的自定义列(对象)类型
【发布时间】:2018-03-29 15:26:21
【问题描述】:

似乎我在任何地方都找不到如何在 Slick 中正确使用自定义列类型,而且我已经苦苦挣扎了一段时间。光滑documentation 建议MappedColumnType,但我发现它仅适用于简单的用例,如原始类型包装器(或者可能只是我不知道如何正确使用它)。

假设我的数据库中有由JobsTableDef 类描述的 Jobs 表。在该表中,我有 companyIdresponsibleUserId 列,它们是 CompanyUser 各自表中对象的外键(CompaniesTableDefUsersTableDef)。

class JobsTableDef(tag: Tag) extends Table[Job] (tag, "jobs") {

  def id = column[Long]("id", O.AutoInc, O.PrimaryKey)
  def title = column[String]("title")
  def companyId = column[Long]("companyId")
  def responsibleUserId = column[Long]("responsibleUserId")

  def companyFK = foreignKey("COMPANY_ID_FK", companyId, companies)(i => i.id)
  def responsibleUserFK = foreignKey("RESPONSIBLE_USER_FK", responsibleUserId, users)(i => i.id)

  val companies = TableQuery[CompaniesTableDef]
  val users = TableQuery[UsersTableDef]

  override def * = (id, title, companyId, responsibleUserId) <> (Job.tupled, Job.unapply)
}

class CompaniesTableDef(tag: Tag) extends Table[Company] (tag, "companies") {

  def id = column[Long]("id", O.AutoInc, O.PrimaryKey)
  def name = column[String]("name")
  def about = column[String]("about")

  override def * = (id, name, about) <> (Company.tupled, Company.unapply)
}

class UsersTableDef(tag: Tag) extends Table[User] (tag, "users"){

  def id = column[Long]("id", O.AutoInc, O.PrimaryKey)
  def username = column[String]("username", O.Unique)

  override def * = (id, username) <> (User.tupled, User.unapply)
}

我想要实现的是自动“反序列化”CompanyUserJobs 表中由它们的 ID 表示。例如:

class JobsTableDef(tag: Tag) extends Table[Job] (tag, "jobs") {

  def id = column[Long]("id", O.AutoInc, O.PrimaryKey)
  def title = column[String]("title")
  def company = column[Company]("companyId")
  def responsibleUser = column[User]("responsibleUserId")

  def companyFK = foreignKey("COMPANY_ID_FK", companyId, companies)(i => i.id.?)
  def responsibleUserFK = foreignKey("RESPONSIBLE_USER_FK", responsibleUserId, users)(i => i.id.?)

  val companies = TableQuery[CompaniesTableDef]
  val users = TableQuery[UsersTableDef]

  override def * = (id, title, company, responsibleUser) <> (Job.tupled, Job.unapply)
}

鉴于我的Job 类是这样定义的:

case class Job(
    id: Long,
    title: String,
    company: Company,
    responsibleUser: User,
)

目前,我正在以老式的方式从数据库中获取Job,读取companyIdresponsibleUserId,然后再次查询数据库并手动构造另一个Job 对象(当然,我还可以连接表,将数据作为tuple 获取,然后构造Job 对象)。我严重怀疑这是要走的路。有没有更聪明、更优雅的方式来指示 Slick 自动从另一个表中获取链接对象?

编辑:我正在使用 Play 2.6.12 和 Slick 3.2.2

【问题讨论】:

  • 我认为加入表格并构造对象是更好的方法。没有其他更聪明的方法了。

标签: scala playframework slick


【解决方案1】:

经过几天的深入调查,我得出结论,目前在 Slick 中这是不可能的。我正在寻找的可以描述为通过自定义列类型描述的自动连接表。 Slick 确实支持自定义列类型(通过 MappedColumnType 体现,如 docs 中所述),但它仅适用于相对简单的类型,这些类型不是由从 DB 反序列化的另一个对象组成的(至少自动地,您总是可以尝试获取来自数据库的另一个对象,然后是Await.result() 生成的Future 对象,但我想这不是一个好习惯。

所以,回答我自己,Slick 中的“自动加入”是不可能的,回退到手动连接和手动对象构造。

【讨论】:

    猜你喜欢
    • 2013-10-10
    • 2014-04-21
    • 1970-01-01
    • 2015-08-09
    • 2012-06-07
    • 1970-01-01
    • 2014-08-12
    • 2023-03-24
    • 1970-01-01
    相关资源
    最近更新 更多