Phantom-DSL cassandra与冻结类型 [英] Phantom-DSL cassandra with frozen type

查看:95
本文介绍了Phantom-DSL cassandra与冻结类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要映射的列是冻结类型的地图

I'm trying to map a column which is a Map with frozen type

我的列族有一个字段

batsmen_data map<文本,冻结的< bat_card>>

bat_card有两个字段

bat_card has two fields

 bat_id int,
 bat_name text,

映射列字段

object batsmenData extends MapColumn[ScoreCardData, ScoreCard, String ,Batting](this) {
    override lazy val name="batsmen_data"
}   

这不是理想的方法。因为MapColumn仅支持原始类型。谁能帮我解决如何创建UDT列

This is not an ideal way to do it. Because MapColumn Supports only primitive types. Can any one help me out on how to create a UDT Columns

推荐答案

我找到了一种使用以下方法映射UDT的方法:幻影。

I've figured out a way to map the UDT using phantom. But not sure this is right way.

我有一个列

batsmen_data map<text, frozen<bat_card>>

要对此进行映射,我们编写以下代码

To map this, we write the below code

object batsmenData extends  MapColumn[ScoreCardData, ScoreCard, String, Batting](this) with CustomPrimitives {
        override lazy val name="batsmen_data"
}

编译时,将显示错误未找到击球类的基元

这是因为Phantom为本机类型(例如String,Int等)定义了基本体。为避免您必须为Batter类定义基本体,如下所示(您必须在中扩展CustomPrimitives特质该类,否则您将收到相同的错误。)

This is because Phantom has defined Primitives for native types like String, Int etc. To avoid you have to define primitive for class Batting as shown below(You have to extend CustomPrimitives trait in the class, else you will get the same error).

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

在此之后,将显示另一个错误,指出未找到编解码器要求的操作:[冻结<->击球] 。这是因为cassandra希望自定义UDT类型的编解码器可以序列化和反序列化数据。为了避免这种情况,您必须编写一个CodecClass,这将有助于将UDT值反序列化(因为我只需要反序列化)到自定义对象中即可。

After this one more error will be shown saying Codec not found for requested operation: [frozen <-> Batting]. This is because cassandra expects a codec for the custom UDT type to serialize and deserialze the data. To Avoid this you have to write a CodecClass which will help to deserialize(as i need only deserializing) the UDT value into custom object.

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;
    }
}

一旦定义了编解码器,最后一步就是注册

Once the codec is defined last step is to register this codec into codec registry.

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中的反序列化函数,我们可以将字节映射到所需的对象。

Now using deserialize function in BattingCodec, we can map the bytes to required object.

此方法运行良好。但是我不确定这是否是使用Phantom

This method is working fine. But i'm not sure this is the ideal way to achieve the UDT functionality using Phantom

这篇关于Phantom-DSL cassandra与冻结类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆