2016-09-14 11 views
1

私のマッピングのアノテーションがポイントしているテーブルを変更する必要があります。下記考えてみましょう:Datastax Object Mapper:オンザフライでテーブルを変更

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

私は名前必ずしもコンパイル時に知られていない名前付けパターン「measurementtable_ *」が複数のテーブルを持っている、と私はで動作する必要がある1つは、私のプログラムへの入力によって選択されています。これらのテーブルはすべて同一なので、テーブルごとに新しいクラスを作成する必要はありません。私は入力ごとに自分のプログラムを再コンパイルする必要はありません。

アノテーションに正確なテーブル名を指定することなく、オブジェクトマッピング機能を保持する方法はありますか?

答えて

1

従来の方法では、アノテーションは事実上定数なので、従来の方法で変更することはできません。 Datastaxオブジェクトマッパーは、マッピングされたオブジェクトのテーブルをオンザフライで切り替える方法を公開していないので、より暗い芸術を採用する必要があります:バイトコードの操作。

Measurementの注釈を直接操作している可能性がありますが、に変更する必要はありません。その結果、Measurementクラスは、その注釈を失うべきで、抽象行われる。

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

次に、実際のテーブル名が知られると、1は正しい注釈付きサブクラスを生成するために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(...)呼び出しに供給して、目的のテーブルを指すオブジェクトマッパーを作成することができます。

バイトコードの操作が必要だが、入力ごとに再コンパイルしたり、オブジェクトに対して同じクラスを作成したりするのを避けている限り、バイトコード操作が必要であるということを考えれば、それは最善の解決策ではない。

関連する問題