[英]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.