我需要更改我的映射annoatation指向的表格。请考虑以下内容:
@Table(name="measurementtable_one", keyspace="mykeyspace")
public class Measurement {/*...*/}
我有多个带有命名模式的表格' measurementtable _ *'其名称在编译时不一定是已知的,我需要使用的名称由我的程序的输入选择。由于所有这些表都是相同的,我不想为每个表创建一个新类;我不想为每个输入重新编译我的程序。
有没有办法保留对象映射功能,而无需在注释中指定我的确切表名?
答案 0 :(得分:1)
通过传统方式,没有。由于注释是有效常量,因此无法通过常规方法更改它们。由于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(...)
调用,以生成指向所需表格的对象映射器。
这不是最漂亮的解决方案,因为字节码操作是必要的,但是它做了它需要做的事情,同时避免重新编译每个输入或为你的对象创建一百万个相同的类。