Cassandra Java 驱动程序获取 Java 类型的 TypeCodec
Cassandra Java Driver get TypeCodec for Java type
我有以下带有泛型参数的方法:
public <K> Store<K> createStore(final Class<K> keyType);
这只会在 cassandra 中为我创建一个具有给定类型的 table。
我想检查给定 keyType
是否已经有 TypeCodec
的默认实现。如果是,那么我只想使用这个编解码器,否则我将使用自己编写的通用编解码器。
Cassandra 的 CodecRegistry
class 提供了方法:
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);
事实是,none 这些方法适合我的用例。几乎所有方法都需要我无法提供的 DatatType cqlType
参数,因为我没有找到将我给定的 keyType
class 文字映射到可能匹配的 Cassandra Datatype
的方法。 (这可能吗?)
唯一接近我想要的是:
public <T> TypeCodec<T> codecFor(T value);
但它需要 class 的 实例 而不是 class 文字。
所以我想要的是:
public <T> TypeCodec<T> codecFor(Class<T> javaType);
这只会给我默认的 TypeCodec
用于给定类型,即如果我传入类型 "java.lang.Integer" 那么应该返回相应的整数的 cassandra TypeCodec。
有什么关于如何实现此行为的建议吗?
CodecRegistry
class 有两个字段存储所有 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));
您需要的功能已被请求但尚未实现,请参阅 JAVA-1015。请为这张票投上一票并说明您希望实施它的原因。
与此同时,我建议您重新设计您的 createStore
方法;您的应用程序可能知道 – 或者至少 应该知道 – 对于给定的 keyType
使用什么 CQL 类型。不知道使用哪种 CQL 类型通常是一种难闻的气味。
我有以下带有泛型参数的方法:
public <K> Store<K> createStore(final Class<K> keyType);
这只会在 cassandra 中为我创建一个具有给定类型的 table。
我想检查给定 keyType
是否已经有 TypeCodec
的默认实现。如果是,那么我只想使用这个编解码器,否则我将使用自己编写的通用编解码器。
Cassandra 的 CodecRegistry
class 提供了方法:
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);
事实是,none 这些方法适合我的用例。几乎所有方法都需要我无法提供的 DatatType cqlType
参数,因为我没有找到将我给定的 keyType
class 文字映射到可能匹配的 Cassandra Datatype
的方法。 (这可能吗?)
唯一接近我想要的是:
public <T> TypeCodec<T> codecFor(T value);
但它需要 class 的 实例 而不是 class 文字。
所以我想要的是:
public <T> TypeCodec<T> codecFor(Class<T> javaType);
这只会给我默认的 TypeCodec
用于给定类型,即如果我传入类型 "java.lang.Integer" 那么应该返回相应的整数的 cassandra TypeCodec。
有什么关于如何实现此行为的建议吗?
CodecRegistry
class 有两个字段存储所有 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));
您需要的功能已被请求但尚未实现,请参阅 JAVA-1015。请为这张票投上一票并说明您希望实施它的原因。
与此同时,我建议您重新设计您的 createStore
方法;您的应用程序可能知道 – 或者至少 应该知道 – 对于给定的 keyType
使用什么 CQL 类型。不知道使用哪种 CQL 类型通常是一种难闻的气味。