自定义映射到 Slick 中的嵌套案例类结构(超过 22 列) [英] Custom mapping to nested case class structure in Slick (more than 22 columns)

查看:53
本文介绍了自定义映射到 Slick 中的嵌套案例类结构(超过 22 列)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将超过 22 列的 DB 行映射到案例类树.我宁愿不使用 HList,因为我不想使用该 API,也不想使用我在某处读到的一些指数编译时间反馈......

I'm trying to map a DB row with more than 22 columns to a case class tree. I'd rather not using HList as I don't want to work with that API, and also for some exponential compilation time feedbacks that I've read somewhere...

我读过 Stefan Zeiger 回答的这个帖子:我如何处理 >使用嵌套元组或 HList 使用 Slick 的 22 列表?

I have read this thread answered by Stefan Zeiger: How can I handle a > 22 column table with Slick using nested tuples or HLists?

我看过这个测试,它展示了如何定义自定义映射函数,我想这样做:

I've seen this test which shows how to define a custom mapping function and I'd like to do that:

https://github.com/slick/slick/blob/2.1/slick-testkit/src/main/scala/com/typesafe/slick/testkit/tests/JdbcMapperTest.scala#L129-141

def * = (
        id,
        (p1i1, p1i2, p1i3, p1i4, p1i5, p1i6),
        (p2i1, p2i2, p2i3, p2i4, p2i5, p2i6),
        (p3i1, p3i2, p3i3, p3i4, p3i5, p3i6),
        (p4i1, p4i2, p4i3, p4i4, p4i5, p4i6)
      ).shaped <> ({ case (id, p1, p2, p3, p4) =>
        // We could do this without .shaped but then we'd have to write a type annotation for the parameters
        Whole(id, Part.tupled.apply(p1), Part.tupled.apply(p2), Part.tupled.apply(p3), Part.tupled.apply(p4))
      }, { w: Whole =>
        def f(p: Part) = Part.unapply(p).get
        Some((w.id, f(w.p1), f(w.p2), f(w.p3), f(w.p4)))
      })

问题是我做不到!

我已经尝试了更小的步骤.

I've tried by smaller steps.

class UserTable(tag: Tag) extends TableWithId[User](tag,"USER") {
  override def id = column[String]("id", O.PrimaryKey)
  def role = column[UserRole.Value]("role", O.NotNull)
  def login = column[String]("login", O.NotNull)
  def password = column[String]("password", O.NotNull)
  def firstName = column[String]("first_name", O.NotNull)
  def lastName = column[String]("last_name", O.NotNull)
  //
  def * = (id, role, login, password, firstName, lastName) <> (User.tupled,User.unapply)
  //
  def login_index = index("idx_user_login", login, unique = true)
}

好像我打电话的时候

(id, (firstName, lastName)).shaped

类型为 ShapedValue[(Column[String], (Column[String], Column[String])), Nothing]

虽然这个似乎工作正常

(id, firstName, lastName).shaped

U 类型参数不是 Nothing 而是预期的 (String, String, String)

The U type parameter is not Nothing but as expected (String, String, String)

我真的不明白所有 Slick 内部是如何工作的.有人可以解释我为什么我不能让我的代码工作吗?是缺少导入还是什么?

I don't really understand how all the Slick internals are working. Can someone explain me why I can't make my code work? Is there a missing import or something?

我想我需要获取一个

ShapedValue[(Column[String], (Column[String], Column[String])), (String, (String, String))]

但我不知道为什么它返回给我 Nothing 并且真的不明白这些隐含的 Shape 参数从何而来...

but I don't know why it returns me Nothing and don't really understand where these implicit Shape parameters come from...

我想要的只是能够轻松地将我的专栏分成 2 个案例类

What I want is just to be able to easily split my column into 2 case classes

谢谢

推荐答案

还有同样的问题,22 列限制,测试用例 非常有帮助.不知道为什么示例代码不适合你,下面的代码对我来说很好,

Also, have the same problem with the 22 columns limitation, the test case helps very much. Not sure why the example code not working for you, the following code works fine for me,

case class UserRole(var role: String, var extra: String)
case class UserInfo(var login: String, var password: String, var firstName: String, var lastName: String)

case class User(id: Option[String], var info: UserInfo, var role: UserRole)

class UserTable(tag: Tag) extends Table[User](tag, "USER") {

  def id = column[String]("id", O.PrimaryKey)
  def role = column[String]("role", O.NotNull)
  def extra = column[String]("extra", O.NotNull)
  def login = column[String]("login", O.NotNull)
  def password = column[String]("password", O.NotNull)
  def firstName = column[String]("first_name", O.NotNull)
  def lastName = column[String]("last_name", O.NotNull)

  /** Projection */
  def * = (
    id,
    (login, password, firstName, lastName),
    (role, extra)
  ).shaped <> (

  { case (id, userInfo, userRole) =>
    User(Option[id], UserInfo.tupled.apply(userInfo), UserRole.tupled.apply(userRole))
  },
  { u: User =>
      def f1(p: UserInfo) = UserInfo.unapply(p).get
      def f2(p: UserRole) = UserRole.unapply(p).get
      Some((u.id.get, f1(u.info), f2(u.role)))
  })

  def login_index = index("id_user_login", login, unique = true)
}

这篇关于自定义映射到 Slick 中的嵌套案例类结构(超过 22 列)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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