例如,我有
type MapColumn[Owner <: com.websudos.phantom.dsl.CassandraTable[Owner, Record], Record, K, V] =
com.websudos.phantom.column.MapColumn[Owner, Record, K, V]
K
和V
很明显,但是所有者和记录?我应该在那里输入什么?
答案 0 :(得分:1)
幻像的全部功能在于它能够映射您的数据模型并为您提供类型安全的结果,或者在我编写它时考虑到这一点。 Owner
类型参数是用户编写的表的类型及其所需的,因此您可以执行以下操作:
select.where(_.id eqs id)
看起来很简单,但诀窍在于没有精炼类型参数,编译器可以通过它“记住”你在表中任意定义的列,你将永远无法在DSL代码中“知道”哪些列用户写道。
因此,DSL必须通过扩展CassandraTable
来了解您将创建的表的最终类型。
case class MyRecord(id: UUID, name: String)
class MyTable extends CassandraTable[MyTable, MyRecord] {
object id extends UUIDColumn(this) with PartitionKey[UUID]
// MyTable is Owner and MyRecord is Record.
object mapColumn extends MapColumn[MyTable, MyRecord, String, String](this)
}
这就是为什么所有查询构建器都是从table: Owner
到其他东西的函数。即便如此,也只是简写符号:
select.where(table => table.id eqs id)
Record
类型是使Cassandra结果类型安全的原因。通过告诉你的表它包含什么案例类,幻像能够使用隐式api方法将所有结果映射回这个案例类,所以不必处理类似的事情:
res.getString("mystring")
这些东西在引擎盖下是不可见的,并且幻像“知道”返回的Cassandra行的结果属于case class
内的哪个字段。它非常简洁,效率更高,因为您并不真正关心驱动程序如何处理客户端与数据库之间的Netty缓冲区和CQL消息交换的内部解析,您只需要记录回来。
因此需要将Record
与fromRow
方法结合使用,并且它们不仅会传递到这些列中,还会传递到每个列中。唯一的区别是使用StringColumn
,编译器可以为您推断T
和R
的类型,因此您无需键入它。
这是因为:
type StringColumn[
Owner <: CassandraTable[Owner, Record],
Record
] = com.websudos.phantom.column.PrimitiveColumn[Owner, Record, String]
所以实际上所有列都需要这个。集合需要一个额外的参数(或者在地图的情况下为两个),由用户提供,因此编译器无法推断类型与StringColumn
或BooleanColumn
一样,所以你需要手工打字。
在幻像1.26.0+中,这已经更改,并且额外的类型参数现在也不可见,因此您可以输入以下内容,而无需指定Owner
和Record
object map extends MapColumn[String, String](this)