我是一个冬眠学习者。当我在研究如何在仅提供表格和模式名称时制作动态POJO类时,我已经了解了 google-reflections 库,即
try {
sessionFactory = new StringUtil().getSessionFactory(className);
session = sessionFactory.openSession();
sessionImp = (SessionImpl) session;
System.out.println("Product name ["
+ sessionImp.connection().getMetaData()
.getDatabaseProductName() + "] table name "+tableName);
metadata = sessionImp.connection().getMetaData();
tables = metadata.getTables(null, "SDP", null,
new String[] { "TABLE" });
// tables = metadata.getTables( null, "public", null, new
// String[]{"TABLE"} );//Postgres
ResultSet rs = metadata.getExportedKeys("SDP", "SDP", tableName);
while (rs.next()) {
PojoGenerator.pkey = rs.getString("PKCOLUMN_NAME");
}
System.out.println("Primary key of Table is ["+PojoGenerator.pkey+"]");
while (tables.next()) {
tName = tables.getString(3);
if (tName.equalsIgnoreCase(tableName)) {
columns = metadata.getColumns("SDP", "SDP", tName, null);
// columns = metadata.getColumns("sdp", "public", tName,
// null);//Postgres
while (columns.next()) {
tableMetadata = new TableMetadata();
tableMetadata.setColumnName(columns.getString("COLUMN_NAME"));
tableMetadata.setPropertyName(new StringUtil().getWordCaseNames(columns.getString("COLUMN_NAME")));
//tableMetadata.setRealColumnName( columns.getString("COLUMN_NAME") );
tableMetadata.setColumnType(new StringUtil().dbToJavaDataType(
columns.getString("TYPE_NAME"),
columns.getInt("COLUMN_SIZE"),
columns.getString("DECIMAL_DIGITS")));
tableMetadata.setColumnLength(columns.getInt("COLUMN_SIZE"));
tableMetadata.setSession(session);
list.add(tableMetadata);
}
columns = null;
tName = null;
}
}
} catch (Exception e) {
e.printStackTrace();
}
这个元数据帮助我生成了POJO:
public static Class generate(String className, Map<String, Class<?>> properties, List tableDetails) throws NotFoundException, CannotCompileException {
boolean needToCreateClass = false;
Object obj = null;
Class<?> clazz = null;
CtMethod getterMethod = null;
TableMetadata tableMetadata = null;
int numberOfColumnsInTable = 0;
try {
clazz = Class.forName(className);
obj = clazz.newInstance();
if ( obj != null ){
needToCreateClass = false;
}else{
needToCreateClass = true;
}
}catch (Exception e){
needToCreateClass = true;
}
System.out.println("Need to create a class ["+needToCreateClass+"]");
if ( needToCreateClass ) {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass(className);
// add this to define a super class to extend
// cc.setSuperclass(resolveCtClass(MySuperClass.class));
// add this to define an interface to implement
cc.addInterface(resolveCtClass(Serializable.class));
ClassFile cf = cc.getClassFile();
ConstPool constpool = cf.getConstPool();
AnnotationsAttribute attrTable = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
AnnotationsAttribute attrColumn = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
Annotation [] tableAnnotations = new Annotation[]{new Annotation("javax.persistence.Entity", constpool), new Annotation("javax.persistence.Table", constpool) };
for (Entry<String, Class<?>> entry : properties.entrySet()) {
cc.addField(new CtField(resolveCtClass(entry.getValue()), entry.getKey(), cc));
// System.out.println("Key is ["+entry.getKey()+"]");
getterMethod = generateGetter(cc, entry.getKey(), entry.getValue());
// add getter
cc.addMethod(getterMethod);
if ( numberOfColumnsInTable == 0 ) {
tableAnnotations[1].addMemberValue("name", new StringMemberValue("CRBT_RBT", constpool));
tableAnnotations[1].addMemberValue("schema", new StringMemberValue("SDP", constpool));
attrTable.setAnnotations(tableAnnotations);
cc.getClassFile().addAttribute(attrTable);
attrTable = null;
}
attrColumn = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
Annotation annot1[] = {new Annotation("javax.persistence.Id", constpool),new Annotation("javax.persistence.Column", constpool)};
Annotation annot2[] = {new Annotation("javax.persistence.Column", constpool)};
tableMetadata = (TableMetadata)tableDetails.get( numberOfColumnsInTable );
if ( numberOfColumnsInTable < tableDetails.size() ) {
String realColumnName=new StringUtil().getRealName( entry.getKey());
if(realColumnName.equalsIgnoreCase(pkey)){
annot1[1].addMemberValue("name", new StringMemberValue( realColumnName , constpool ) );
attrColumn.setAnnotations(annot1);
}else{
annot2[0].addMemberValue("name", new StringMemberValue( realColumnName , constpool ) );
attrColumn.setAnnotations(annot2);
}
numberOfColumnsInTable++;
}
getterMethod.getMethodInfo().addAttribute(attrColumn);
// add setter
cc.addMethod(generateSetter(cc, entry.getKey(), entry.getValue()));
}
try {
cc.writeFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*
Validation for applied annotations
*/
try {
Object[] all = cc.getAnnotations();
int k = 0;
for (Object object : all) {
System.out.println(all[k]);
k++;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
/* Validation End */
return cc.toClass();
}else{
return clazz;
}
}
但现在我需要使用hibernate配置映射那些动态创建的POJO。所以我的问题来了: 1.我可以使用反射库吗? 怎么样? 3.如果没有,除了为每个类创建.hbm.xml文件之外还有其他解决方案吗?
请帮忙。提前谢谢。
更新:
我有一个想法,但我不知道它会如何运作。 理念: 我将动态地为每个类创建.hbm.xml文件,并将在hibernate.cfg.xml中映射这些类的包。
但是 1.我不知道如何通过包映射扫描映射文件。 2.我甚至不知道是否可能,如果可能的话怎么样?