如何将具有非默认字段类型的案例类映射到SLICK中的表? [英] How can I map a case class with non-default field types to a table in Slick?
本文介绍了如何将具有非默认字段类型的案例类映射到SLICK中的表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我可以将案例类映射到精巧的数据库表:-
case class SomeTimeStamp(id: Option[Long], timestamp: java.sql.Timestamp )
class TimeStampTable(tag: Tag) extends Table[SomeTimeStamp](tag, "TSTAMP_TABLE") {
def id = column[Long]("ID", O.AutoInc, O.PrimaryKey)
def time = column[java.sql.Timestamp]("TIME")
def * = (id.?, time) <> (SomeTimeStamp.tupled, SomeTimeStamp.unapply)
}
Case类包含默认情况下由SLICK转换为数据库类型的字段,因此一切正常。
但是,如果我的Case类中的某个字段不是默认数据库类型,则此操作不起作用。SLICK允许我使用MappdColumnType提供与有效数据库类型之间的隐式转换,因此我尝试了这个方法,请注意,我现在使用的是Java LocalDatetime,而不是SQL时间戳。case class SomeLocalDate(id: Option[Long], timestamp: java.time.LocalDateTime )
class LocalDateTable(tag: Tag) extends Table[SomeLocalDate](tag, "TLDATE_TABLE") {
import LocalDateTable._
def id = column[Long]("ID", O.AutoInc, O.PrimaryKey)
def time = column[java.time.LocalDateTime]("TIME")
def * = (id.?, time) <> (SomeLocalDate.tupled, SomeLocalDate.unapply)
}
object LocalDateTable {
implicit val localDateTimeToTimestamp = MappedColumnType.base[LocalDateTime, Timestamp](
{ Timestamp.valueOf(_) } ,
{ ts => ts.toLocalDateTime }
)
}
我已经添加了隐式映射列,但在投影和隐式解析中仍会遇到编译错误
编译错误为:-
[info] Compiling 1 Scala source to ...target/scala-2.11/classes...
[error] db/Tables.scala:92: could not find implicit value for parameter tt: slick.ast.TypedType[java.time.LocalDateTime]
[error] def time: Rep[LocalDateTime] = column[java.time.LocalDateTime]("TIME")
如果我修改了def time并添加了类型归属,则会收到不同的错误,请参见下面的内容。
case class SomeLocalDate(id: Option[Long], timestamp: java.time.LocalDateTime )
class LocalDateTable(tag: Tag) extends Table[SomeLocalDate](tag, "TLDATE_TABLE") {
import LocalDateTable._
def id = column[Long]("ID", O.AutoInc, O.PrimaryKey)
def time: Rep[LocalDateTime] = column[java.time.LocalDateTime]("TIME")
def * = (id.?, time) <> (SomeLocalDate.tupled, SomeLocalDate.unapply)
}
object LocalDateTable {
implicit val localDateTimeToTimestamp = MappedColumnType.base[LocalDateTime, Timestamp](
{ Timestamp.valueOf(_) } ,
{ ts => ts.toLocalDateTime }
)
}
显示此错误:-
[info] Compiling 1 Scala source to ...target/scala-2.11/classes...
[error] db/Tables.scala:92: could not find implicit value for parameter tt: slick.ast.TypedType[java.time.LocalDateTime]
[error] def time: Rep[LocalDateTime] = column[java.time.LocalDateTime]("TIME")
[error] ^
[error]db/Tables.scala:94: No matching Shape found.
[error] Slick does not know how to map the given types.
[error] Possible causes: T in Table[T] does not match your * projection. Or you use an unsupported type in a Query (e.g. scala List).
[error] Required level: slick.lifted.FlatShapeLevel
[error] Source type: (slick.lifted.Rep[Option[Long]], slick.lifted.Rep[java.time.LocalDateTime])
[error] Unpacked type: (Option[Long], java.time.LocalDateTime)
[error] Packed type: Any
[error] def * = (id.?, time) <> (SomeLocalDate.tupled, SomeLocalDate.unapply)
[error] ^
[error] two errors found
如果案例类不具有默认支持的数据库类型(例如LocalDateTime),则必须执行什么操作才能将案例类映射到表?
干杯
推荐答案
经过几天的挣扎,我找到了答案:-/
问题是隐式MappdColumnType是在Table类之后声明的。由于某种原因,这打乱了隐式解析,即使我在表上导入了它。
当我删除Case类并简单地使用Tuples时,我找到了答案。当我这样做时,出现了以下错误
[info] Compiling 1 Scala source to target/scala-2.11/classes...
[error] /db/Tables.scala:100: could not find implicit value for parameter tt: slick.ast.TypedType[java.time.LocalDateTime]
[error] def time: Rep[LocalDateTime] = column[java.time.LocalDateTime]("TIME")
[error] ^
[error] /db/Tables.scala:102: type mismatch;
[error] found : (slick.lifted.Rep[Option[Long]], slick.driver.H2Driver.api.Rep[java.time.LocalDateTime])
[error] (which expands to) (slick.lifted.Rep[Option[Long]], slick.lifted.Rep[java.time.LocalDateTime])
[error] required: slick.lifted.ProvenShape[(Option[Long], java.time.LocalDateTime)]
[error] Note: implicit value localDateTimeToTimestamp is not applicable here because it comes after the application point and it lacks an explicit result type
[error] def * : ProvenShape[(Option[Long], LocalDateTime)] = (id.?, time)
[error] ^
因此,清楚地说,解决方案是将隐式转换放在表定义之上(如果在同一文件中),或者将其放在另一个文件中并导入,请参阅下面的工作解决方案。谢谢。
case class SomeLocalDate(id: Option[Long], timestamp: java.time.LocalDateTime )
object LocalDateTableConversions {
implicit val localDateTimeToTimestamp = MappedColumnType.base[LocalDateTime, Timestamp](
{ Timestamp.valueOf(_) } ,
{ ts => ts.toLocalDateTime }
)
}
import LocalDateTableConversions._
class LocalDateTable(tag: Tag) extends Table[SomeLocalDate](tag, "TLDATE_TABLE") {
def id = column[Long]("ID", O.AutoInc, O.PrimaryKey)
def time: Rep[LocalDateTime] = column[java.time.LocalDateTime]("TIME")
def * = (id.?, time) <> (SomeLocalDate.tupled, SomeLocalDate.unapply)
}
这篇关于如何将具有非默认字段类型的案例类映射到SLICK中的表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文