gpt4 book ai didi

java - Datastax 对象映射器 : change table on the fly

转载 作者:行者123 更新时间:2023-11-30 07:09:09 24 4
gpt4 key购买 nike

我需要动态更改我的映射注释指向的表。考虑以下因素:

@Table(name="measurementtable_one", keyspace="mykeyspace")
public class Measurement {/*...*/}

我有多个具有命名模式“measurementtable_*”的表,其名称在编译时不一定已知,而我需要使用的表是通过程序的输入来选择的。由于所有这些表都是相同的,我不想为每个表创建一个新类;我不想为每个输入重新编译我的程序。

有没有一种方法可以保留对象映射功能,而不必在注释中指定我的确切表名称?

最佳答案

按照传统方式,不会。由于注释实际上是常量,因此您无法通过常规方式更改它们。由于 Datastax 对象映射器不公开任何动态切换映射对象表的方法,因此必须采用更黑暗的技术:字节码操作。

虽然人们可以直接操纵测量的注释,但我不喜欢改变应该不变的内容。因此,Measurement 类应该失去其注释并变得抽象:

public class Measurement { /*...*/ }

然后,一旦知道真实的表名,就可以使用 javassist 生成带有正确注释的子类:

String modelname = getNameFromExternalSource(); //Replace with real external source.
String modelcleanname = modeldir.getName().replaceAll("\\W", "");
ClassPool pool = ClassPool.getDefault();
String measurementclassname = "measurementtable_" + modelcleanname;
CtClass stagingmeasurementclass = pool.makeClass(measurementclassname);
stagingmeasurementclass.setSuperclass(pool.get(StagingMeasurementRecord.class.getName()));
stagingmeasurementclass.setModifiers(Modifier.PUBLIC);
ClassFile stagingmeasurementclassfile = stagingmeasurementclass.getClassFile();
ConstPool constpool = stagingmeasurementclassfile.getConstPool();
AnnotationsAttribute attribute = new AnnotationsAttribute(constpool,
AnnotationsAttribute.visibleTag);
Annotation tableannotation = new Annotation(constpool, pool.get(Table.class.getName()));
tableannotation.addMemberValue("name", new StringMemberValue(measurementclassname, constpool));
tableannotation.addMemberValue("keyspace", new StringMemberValue("mykeyspace", constpool));
attribute.addAnnotation(tableannotation);
stagingmeasurementclassfile.addAttribute(attribute);
stagingmeasurementclass.addConstructor(
CtNewConstructor.make(new CtClass[0], new CtClass[0], stagingmeasurementclass));
Class<? super StagingMeasurementRecord> myoutputclass = stagingmeasurementclass.toClass();
LOGGER.info("Created custom measurementtable class with the name " + myoutputclass.getName());

然后,您可以将 myoutputclass 实例提供给 MappingManagerInstance.mapper(...) 调用,以生成指向所需表的对象映射器。

考虑到字节码操作是必要的,这不是最漂亮的解决方案,但它做了它需要做的事情,同时避免为每个输入重新编译或为您的对象创建一百万个相同的类。

关于java - Datastax 对象映射器 : change table on the fly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39498322/

24 4 0