使用 Slick 创建单列 table
Creating a single column table with Slick
我很习惯像这样编写标准的光滑样板代码。
假设我正在创建一个名为 Foo 的 table,其中包含列 ID 和名称。我们可以写
case class Foo(id: Long, name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def id = column[Long]("id")
def name = column[String]("name")
def * = (id, name) <> (Foo.tupled, Foo.unapply)
}
但是如果我想要一个单独的列 table,其中 Foo 只有一个名称怎么办?下面的代码无法编译,因为 Now Foo 不再有元组方法。
case class Foo(name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def name = column[String]("name")
def * = (name) <> (Foo.tupled, Foo.unapply)
}
我在 SO
上找到了这个帖子
Scala projections in Slick for only one column
并将我的代码更改为
case class Foo(name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def name = column[String]("email_address")
def * = (name)
}
但仍然无法编译
在单个参数的情况下使用Foo.apply _
。你的代码变成如下
case class Foo(name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def name = column[String]("name")
def * = (name) <> ((Foo.apply _), Foo.unapply)
}
解释:
scala> case class Foo(name: String)
defined class Foo
scala> Foo.apply _
res0: String => Foo = <function1>
在单参数情况下 class Foo.apply _
returns 需要一个函数 1。
但是如果参数不止一个,这是不可能的,所以需要 .tupled
。
也找到了另一个答案
case class Foo(name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def name = column[String]("name")
def * = name <> (Foo, Foo.unapply)
}
我相信以前的答案已经解决了这个特定问题。不过,我认为这里有一件事值得补充。
Slick 中没有任何内容需要您将 case classes
用作 unpacked type
(unpacked type
是您的模型,在这种情况 Foo
).
在您的投影中:
def * = (id, name) <> (Foo.tupled, Foo.unapply)
你可以传递任何你想要的两个函数,假设:
第一个将从元组(投影中的 2+ 列)或值(1 列投影)
中创建您的 unpacked type
second 将创建元组(同样是在投影中有 2+ 列的情况下)或
值(1 列投影)。
只有 case classes
具有开箱即用的方法才方便 (tupled
, apply
, unapply
)。
我希望这可以澄清,即使您缺少此类方法,也总是有可能(在最坏的情况下)例如创建满足给定要求的函数。
我很习惯像这样编写标准的光滑样板代码。
假设我正在创建一个名为 Foo 的 table,其中包含列 ID 和名称。我们可以写
case class Foo(id: Long, name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def id = column[Long]("id")
def name = column[String]("name")
def * = (id, name) <> (Foo.tupled, Foo.unapply)
}
但是如果我想要一个单独的列 table,其中 Foo 只有一个名称怎么办?下面的代码无法编译,因为 Now Foo 不再有元组方法。
case class Foo(name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def name = column[String]("name")
def * = (name) <> (Foo.tupled, Foo.unapply)
}
我在 SO
上找到了这个帖子Scala projections in Slick for only one column
并将我的代码更改为
case class Foo(name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def name = column[String]("email_address")
def * = (name)
}
但仍然无法编译
在单个参数的情况下使用Foo.apply _
。你的代码变成如下
case class Foo(name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def name = column[String]("name")
def * = (name) <> ((Foo.apply _), Foo.unapply)
}
解释:
scala> case class Foo(name: String)
defined class Foo
scala> Foo.apply _
res0: String => Foo = <function1>
在单参数情况下 class Foo.apply _
returns 需要一个函数 1。
但是如果参数不止一个,这是不可能的,所以需要 .tupled
。
也找到了另一个答案
case class Foo(name: String)
final class FooTable(tag: Tag) extends Table[Foo](tag, "foo") {
def name = column[String]("name")
def * = name <> (Foo, Foo.unapply)
}
我相信以前的答案已经解决了这个特定问题。不过,我认为这里有一件事值得补充。
Slick 中没有任何内容需要您将 case classes
用作 unpacked type
(unpacked type
是您的模型,在这种情况 Foo
).
在您的投影中:
def * = (id, name) <> (Foo.tupled, Foo.unapply)
你可以传递任何你想要的两个函数,假设:
第一个将从元组(投影中的 2+ 列)或值(1 列投影)
中创建您的 second 将创建元组(同样是在投影中有 2+ 列的情况下)或
值(1 列投影)。
unpacked type
只有 case classes
具有开箱即用的方法才方便 (tupled
, apply
, unapply
)。
我希望这可以澄清,即使您缺少此类方法,也总是有可能(在最坏的情况下)例如创建满足给定要求的函数。