具有冻结类型的 Phantom-DSL cassandra
Phantom-DSL cassandra with frozen type
我正在尝试映射一个列,该列是冻结类型的地图
我的列族有一个字段
batsmen_data map<text, frozen<bat_card>>
bat_card 有两个字段
bat_id int,
bat_name text,
映射列字段
object batsmenData extends MapColumn[ScoreCardData, ScoreCard, String ,Batting](this) {
override lazy val name="batsmen_data"
}
这不是一个理想的方法。因为 MapColumn 只支持原始类型。任何人都可以帮助我了解如何创建 UDT 列
我找到了一种使用 phantom 映射 UDT 的方法。但不确定这是正确的方法。
我有一栏
batsmen_data map<text, frozen<bat_card>>
为了映射这个,我们写了下面的代码
object batsmenData extends MapColumn[ScoreCardData, ScoreCard, String, Batting](this) with CustomPrimitives {
override lazy val name="batsmen_data"
}
编译时会显示错误 未找到 class 击球 的原语
这是因为 Phantom 已经为 String、Int 等原生类型定义了 Primitives。为了避免你必须为 class Batting 定义原语,如下所示(你必须在 class, 否则你会得到同样的错误)。
trait CustomPrimitives extends Config {
implicit object BattingPrimitive extends Primitive[Batting]{
override type PrimitiveType = Batting
override def clz: Class[Batting] = classOf[Batting]
override def cassandraType: String = {
Connector.session.getCluster.getMetadata.getKeyspace(cassandraKeyspace).getUserType("bat_card").toString()
}
override def fromRow(column: String, row: dsl.Row): Try[Batting] = ???
override def fromString(value: String): Batting = ???
override def asCql(value: Batting): String = ???
}
在此之后,将显示另一个错误 找不到请求操作的编解码器:[frozen <-> Batting]。这是因为 cassandra 需要自定义 UDT 类型的编解码器来序列化和反序列化数据。为避免这种情况,您必须编写一个 CodecClass,这将有助于将 UDT 值反序列化(因为我只需要反序列化)到自定义对象中。
public class BattingCodec extends TypeCodec<Batting>{
protected BattingCodec(TypeCodec<UDTValue> innerCodec, Class<Batting> javaType) {
super(innerCodec.getCqlType(), javaType);
}
@Override
public ByteBuffer serialize(Batting value, ProtocolVersion protocolVersion) throws InvalidTypeException {
return null;
}
@Override
public Batting deserialize(ByteBuffer bytes, ProtocolVersion protocolVersion) throws InvalidTypeException {
return null;
}
@Override
public Batting parse(String value) throws InvalidTypeException {
return null;
}
@Override
public String format(Batting value) throws InvalidTypeException {
return null;
}
}
定义编解码器后,最后一步是将此编解码器注册到编解码器注册表中。
val codecRegistry = CodecRegistry.DEFAULT_INSTANCE
val bat_card = Connector.session.getCluster.getMetadata.getKeyspace(cassandraKeyspace).getUserType("bat_card")
val batCodec = new BattingCodec(TypeCodec.userType(bat_card), classOf[Batting])
codecRegistry.register(batCodec)
现在使用 BattingCodec 中的 deserialize 函数,我们可以将字节映射到所需的对象。
这个方法工作正常。但我不确定这是使用 Phantom
实现 UDT 功能的理想方式
我正在尝试映射一个列,该列是冻结类型的地图
我的列族有一个字段
batsmen_data map<text, frozen<bat_card>>
bat_card 有两个字段
bat_id int,
bat_name text,
映射列字段
object batsmenData extends MapColumn[ScoreCardData, ScoreCard, String ,Batting](this) {
override lazy val name="batsmen_data"
}
这不是一个理想的方法。因为 MapColumn 只支持原始类型。任何人都可以帮助我了解如何创建 UDT 列
我找到了一种使用 phantom 映射 UDT 的方法。但不确定这是正确的方法。
我有一栏
batsmen_data map<text, frozen<bat_card>>
为了映射这个,我们写了下面的代码
object batsmenData extends MapColumn[ScoreCardData, ScoreCard, String, Batting](this) with CustomPrimitives {
override lazy val name="batsmen_data"
}
编译时会显示错误 未找到 class 击球 的原语
这是因为 Phantom 已经为 String、Int 等原生类型定义了 Primitives。为了避免你必须为 class Batting 定义原语,如下所示(你必须在 class, 否则你会得到同样的错误)。
trait CustomPrimitives extends Config {
implicit object BattingPrimitive extends Primitive[Batting]{
override type PrimitiveType = Batting
override def clz: Class[Batting] = classOf[Batting]
override def cassandraType: String = {
Connector.session.getCluster.getMetadata.getKeyspace(cassandraKeyspace).getUserType("bat_card").toString()
}
override def fromRow(column: String, row: dsl.Row): Try[Batting] = ???
override def fromString(value: String): Batting = ???
override def asCql(value: Batting): String = ???
}
在此之后,将显示另一个错误 找不到请求操作的编解码器:[frozen <-> Batting]。这是因为 cassandra 需要自定义 UDT 类型的编解码器来序列化和反序列化数据。为避免这种情况,您必须编写一个 CodecClass,这将有助于将 UDT 值反序列化(因为我只需要反序列化)到自定义对象中。
public class BattingCodec extends TypeCodec<Batting>{
protected BattingCodec(TypeCodec<UDTValue> innerCodec, Class<Batting> javaType) {
super(innerCodec.getCqlType(), javaType);
}
@Override
public ByteBuffer serialize(Batting value, ProtocolVersion protocolVersion) throws InvalidTypeException {
return null;
}
@Override
public Batting deserialize(ByteBuffer bytes, ProtocolVersion protocolVersion) throws InvalidTypeException {
return null;
}
@Override
public Batting parse(String value) throws InvalidTypeException {
return null;
}
@Override
public String format(Batting value) throws InvalidTypeException {
return null;
}
}
定义编解码器后,最后一步是将此编解码器注册到编解码器注册表中。
val codecRegistry = CodecRegistry.DEFAULT_INSTANCE
val bat_card = Connector.session.getCluster.getMetadata.getKeyspace(cassandraKeyspace).getUserType("bat_card")
val batCodec = new BattingCodec(TypeCodec.userType(bat_card), classOf[Batting])
codecRegistry.register(batCodec)
现在使用 BattingCodec 中的 deserialize 函数,我们可以将字节映射到所需的对象。
这个方法工作正常。但我不确定这是使用 Phantom
实现 UDT 功能的理想方式