例如,我有
type MapColumn[Owner <: com.websudos.phantom.dsl.CassandraTable[Owner, Record], Record, K, V] =
com.websudos.phantom.column.MapColumn[Owner, Record, K, V]
K
并且V
很明显,但所有者和记录?我应该在那里输入什么?
例如,我有
type MapColumn[Owner <: com.websudos.phantom.dsl.CassandraTable[Owner, Record], Record, K, V] =
com.websudos.phantom.column.MapColumn[Owner, Record, K, V]
K
并且V
很明显,但所有者和记录?我应该在那里输入什么?
phantom 的全部力量在于它能够映射您的数据模型并为您返回类型安全的结果,或者我在编写它时就想到了。type 参数是用户编写的表的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)
}
所以这就是为什么所有的查询构建器都是从 atable: Owner
到其他东西的函数。甚至以上只是以下的简写符号:
select.where(table => table.id eqs id)
Record
类型是使 Cassandra 结果类型安全的原因。通过告诉您的表它包含什么案例类,phantom 能够使用隐式 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
or的类型BooleanColumn
,因此您需要手动键入它们。
在 phantom 1.26.0+ 中,这已被更改,额外的类型参数现在也不可见,因此您将能够键入以下内容,而无需指定Owner
and Record
。
object map extends MapColumn[String, String](this)