Phantom-DSL cassandra与冷冻类型

时间:2016-01-06 12:41:35

标签: scala cassandra phantom-dsl

我正在尝试映射一个列为冻结类型的列

我的专栏系列有一个字段

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列

的问题

1 个答案:

答案 0 :(得分:1)

我找到了一种使用幻像映射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"
}

编译时,将显示错误类击中没有原始

这是因为Phantom为String,Int等本机类型定义了Primitives。为了避免你必须为类Batting定义原语,如下所示(你必须在类中扩展CustomPrimitives特性,否则你会得到相同的错误)。

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 = ???
    }

此后会再显示一条错误,说明找不到请求操作的编解码器:[冻结&lt; - &gt;棉絮] 即可。这是因为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中使用反序列化功能,我们可以将字节映射到所需的对象。

这种方法运行正常。但我不确定这是使用Phantom实现UDT功能的理想方式