Google-Reflections:什么时候应该使用反射库?以及如何从表元数据创建动态POJO?

时间:2016-05-13 13:43:50

标签: java hibernate annotations google-reflections

我是一个冬眠学习者。当我在研究如何在仅提供表格和模式名称时制作动态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.我甚至不知道是否可能,如果可能的话怎么样?

0 个答案:

没有答案