简体   繁体   English

Cassandra Java驱动程序获取Java类型的TypeCodec

[英]Cassandra Java Driver get TypeCodec for Java type

I have the following method with generic parameter: 我有以下带有通用参数的方法:

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

which will just create a table in cassandra with the given type for me. 它将为我在cassandra中创建一个具有给定类型的表。

I want to check whether there is already a default implementation of a TypeCodec for the given keyType . 我想检查给定keyType是否已经存在TypeCodec的默认实现。 If yes then I just want to use this codec otherwise I'll use a generic codec written by myself. 如果是,那么我只想使用此编解码器,否则我将使用自己编写的通用编解码器。

Cassandra's CodecRegistry class provides the methods: 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);

The thing is, none of these methods fits for my use case. 问题是,这些方法都不适合我的用例。 Almost all methods require DatatType cqlType parameter which I cannot provide because I did not find a way to map the my given keyType class literal to a possible matching Cassandra Datatype . 几乎所有方法都需要DatatType cqlType参数,我无法提供它,因为我没有找到将给定的keyType类文字映射到可能匹配的Cassandra Datatype (is this possible?) (这可能吗?)

The only one that comes close for what I want, is: public <T> TypeCodec<T> codecFor(T value); 唯一public <T> TypeCodec<T> codecFor(T value);我需要的是: public <T> TypeCodec<T> codecFor(T value); but it requires an instance of the the class and not a class literal. 但它需要类的实例 ,而不是类文字。 So what I want is: 所以我想要的是:

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

which would give me just the default TypeCodec to use for the given type, ie if i pass in the type "java.lang.Integer" then the corresponding cassandra TypeCodec for Integers shoud be returned. 这将只给我用于给定类型的默认TypeCodec ,即,如果我传入类型“ java.lang.Integer”,则应返回相应的cassandra TypeCodec for Integers。

Any suggestions how to implement this behavior? 有什么建议如何实现这种行为?

CodecRegistry class have two fields that store all TypeCodec 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;

You can see that both are private. 您可以看到两者都是私人的。 We can access them with java reflection 我们可以使用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));

The feature you need has been already requested but not implemented, see JAVA-1015 . 您所需的功能已被请求但尚未实现,请参阅JAVA-1015 Please vote for this ticket and explain why you would like to have it implemented. 请为这张票投票,并说明为什么要实施它。

In the meanwhile, I would suggest you to redesign your createStore method; 同时,我建议您重新设计createStore方法。 your application probably knows – or at least should know – what CQL type to use for a given keyType . 您的应用程序可能知道(或至少应该知道)给定keyType使用哪种CQL类型。 Not knowing which CQL type to use is generally a bad smell. 不知道使用哪种CQL类型通常是难闻的气味。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM