Cassandra Java Driver获取TypeCodec for Java类型

时间:2017-05-21 09:50:53

标签: java cassandra datastax-java-driver

我使用以下方法使用泛型参数:

public <K> Store<K> createStore(final Class<K> keyType);

只会在cassandra中为我创建一个给定类型的表。

我想检查给定TypeCodec是否已存在keyType的默认实现。如果是,那么我只想使用这个编解码器,否则我将使用自己编写的通用编解码器。

Cassandra的CodecRegistry类提供了方法:

public <T> TypeCodec<T> codecFor(DataType cqlType, Class<T> javaType);
public <T> TypeCodec<T> codecFor(DataType cqlType);
public <T> TypeCodec<T> codecFor(T value);
public <T> TypeCodec<T> codecFor(DataType cqlType, TypeToken<T> javaType);
public <T> TypeCodec<T> codecFor(DataType cqlType, T value);

问题是,这些方法都不适合我的用例。几乎所有方法都需要DatatType cqlType参数,这是我无法提供的,因为我没有找到将我给定的keyType类文字映射到可能匹配的Cassandra Datatype的方法。 (这可能吗?)

唯一接近我想要的是: public <T> TypeCodec<T> codecFor(T value); 但它需要类的实例而不是类文字。 所以我想要的是:

public <T> TypeCodec<T> codecFor(Class<T> javaType);

这将给出我用于给定类型的默认TypeCodec,即如果我传入“java.lang.Integer”类型,则返回相应的cassandra TypeCodec for Integers。

有关如何实现此行为的任何建议吗?

2 个答案:

答案 0 :(得分:0)

CodecRegistry类有两个字段存储所有TypeCodec

/**
 * List of Built in Codec
 */
private static final TypeCodec<?>[] BUILT_IN_CODECS;    

/**
 * The list of user-registered codecs.
 */
private final CopyOnWriteArrayList<TypeCodec<?>> codecs;

你可以看到两者都是私人的。我们可以使用java反射访问它们

CodecRegistry codecRegistry = CodecRegistry.DEFAULT_INSTANCE;

Map<Class, TypeCodec> javaTypeCodecMap = new HashMap<>();

try {
    Field field = codecRegistry.getClass().getDeclaredField("BUILT_IN_CODECS");
    field.setAccessible(true);
    TypeCodec<?>[] builtInCodecs = (TypeCodec<?>[]) field.get(codecRegistry);
    for (TypeCodec<?> typeCodec : builtInCodecs) {
        javaTypeCodecMap.put(typeCodec.getJavaType().getRawType(), typeCodec);
    }
} catch (NoSuchFieldException | IllegalAccessException e) {
    e.printStackTrace();
}

try {
    Field field = codecRegistry.getClass().getDeclaredField("codecs");
    field.setAccessible(true);
    CopyOnWriteArrayList<TypeCodec<?>> codecs = (CopyOnWriteArrayList<TypeCodec<?>>) field.get(codecRegistry);
    for (TypeCodec<?> typeCodec : codecs) {
        javaTypeCodecMap.put(typeCodec.getJavaType().getRawType(), typeCodec);
    }
} catch (NoSuchFieldException | IllegalAccessException e) {
    e.printStackTrace();
}

//You have the map, now you can get TypeCodec from class name
System.out.println(javaTypeCodecMap.get(String.class));

答案 1 :(得分:0)

您已经请求但未实现所需的功能,请参阅JAVA-1015。请为此票投票,并解释您希望如何实施该票。

同时,我建议你重新设计createStore方法;您的应用程序可能知道 - 或者至少应该知道 - 用于给定keyType的CQL类型。不知道使用哪种CQL类型通常是难闻的气味。