動態修改類注解(賦值)


   1. 動態修改注解元凶:

       

Java代碼 
/** 
 * 對象池工具類 
 *  
 * 目前提供ORM動態映射解決方案 
 *  
 * @author andy.zheng 
 * @since 2012.09.25 15:55 PM 
 * @vesion 1.0 
 *  
 */ 
public class ClassPoolUtils {  
      
      
    /** 
     * 運行時動態ORM表映射 
     *  
     *  
     * @param entityClassName   待映射的實體全限定類名 
     * @param tableName         待映射的表名 
     * @return                  映射后的類對象 
     */ 
    public static Class<?> tableMapping(String entityClassName, String tableName){  
        Class<?> c = null;  
          
        if(StringUtils.isEmpty(entityClassName) || StringUtils.isEmpty(tableName)){  
            throw new IllegalArgumentException("The mapping parameter is invalid!");  
        }  
          
        try {  
            ClassPool classPool = ClassPool.getDefault();  
            classPool.appendClassPath(new ClassClassPath(ClassPoolUtils.class));  
            classPool.importPackage("javax.persistence");  
            CtClass clazz = classPool.get(entityClassName);  
            clazz.defrost();  
            ClassFile classFile = clazz.getClassFile();  
             
            ConstPool constPool = classFile.getConstPool();  
            Annotation tableAnnotation = new Annotation("javax.persistence.Table", constPool);  
            tableAnnotation.addMemberValue("name", new StringMemberValue(tableName, constPool));  
            // 獲取運行時注解屬性  
            AnnotationsAttribute attribute = (AnnotationsAttribute)classFile.getAttribute(AnnotationsAttribute.visibleTag);  
            attribute.addAnnotation(tableAnnotation);  
            classFile.addAttribute(attribute);  
            classFile.setVersionToJava5();  
            //clazz.writeFile();  
              
            //TODO 當前ClassLoader中必須尚未加載該實體。(同一個ClassLoader加載同一個類只會加載一次)  
            //c = clazz.toClass();  
            EntityClassLoader loader = new EntityClassLoader(ClassPoolUtils.class.getClassLoader());  
            c = clazz.toClass(loader , null);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
     &nbsp;    
        return c;  
    }    
 
    public static void main(String[] args) {  
        Class<?> clazz = ClassPoolUtils.tableMapping("com.andy.model.order.Order", "order1");  
        System.out.println("修改后的@Table: " + clazz.getAnnotation(Table.class));  
    }  

 

 2. PO類加載器:

Java代碼 
/** 
 * 實體類加載器 *  
 * 該加載器主要用於運行時動態修改實體后,重新裝載實體 
 *  
 * @author andy.zheng 
 * @since 2012.09.25 16:18 PM 
 * @vesion 1.0 
 * 
 */ 
public class EntityClassLoader extends ClassLoader {  
      
    private ClassLoader parent;  
      
    public EntityClassLoader(ClassLoader parent){  
        this.parent = parent;  
    }  
       
    @Override 
    public Class<?> loadClass(String name) throws ClassNotFoundException {  
        return this.loadClass(name, false);  
    }  
      
    @Override 
    protected synchronized Class<?> loadClass(String name, boolean resolve)  
            throws ClassNotFoundException {  
        Class<?> clazz = this.findLoadedClass(name);  
        if(null != parent){  
            clazz = parent.loadClass(name);  
        }    
        if(null == clazz){  
            this.findSystemClass(name);  
        }  
          
        if(null == clazz){  
            throw new ClassNotFoundException();  
        }  
        if(null != clazz && resolve){  
            this.resolveClass(clazz);  
        }  
          
        return clazz;  
    }  

    /** 
     * @param args 
     */ 
    public static void main(String[] args) {  
 
    }  
 

   3. 將最新映射對象交給Hibernate吧~ 當然這個東東當然在Dao層哈,需要覆蓋hibernate初始化默認加載的映射對象。你可以把它正在諸如BaseHiberanteDao中,在需要動態映射表名的時候,先調它一把,然后再寫你的HQL.當然如果接口統一的話,你也可以玩高級一點的。(為需要動態映射的接口代理一下,悄無聲息的動態映射一把!!!可謂是神不知鬼不覺~),

    /**
     * 運行時動態ORM表映射
     *
     * @param tableMapping  映射集合
     *                      key - 待映射的表名 value - 待映射的實體對象
     */
    @SuppressWarnings("unused")
    protected void tableMapping(Map<String, Class<?>> tableMapping){
        Assert.notEmpty(tableMapping , "The mapping parameter is empty!");
        for (String tableName : tableMapping.keySet()) {
            Class<?> entityClass = tableMapping.get(tableName);
            String className = entityClass.getName();
            ClassMetadata metadata = this.getSessionFactory().getClassMetadata(className);
            Class<?> mappedClass = metadata.getMappedClass();
            mappedClass = ClassPoolUtils.tableMapping(className, tableName);
        }
    }

   調用例子:

  

Java代碼 
public Page<OrderDetail> getList(int currentPage , int pageSize){  
   this.tableMapping(new HashMap(){  
      {  
                this.put("orderdetail1", OrderDetail.class);  
       }  
   });  
  Page<OrderDetail> page = this.<OrderDetail>pagingList("", currentPage , pageSize);  
  Assert.notEmpty(page.getItems());  
  return page;  

 

   執行語句:

  

  

Sql代碼 
Hibernate: select count(*) as col_0_0_ from OrderDetail orderdetai0_  
Hibernate: select orderdetai0_.id as id15_, orderdetai0_.docid as docid15_, orderdetai0_.ErrorDesc as ErrorDesc15_, orderdetai0_.insertedtime as inserted3_15_, orderdetai0_.OrderID as OrderID15_, orderdetai0_.ordernum as ordernum15_, orderdetai0_.SegmentsIDs as Segments5_15_, orderdetai0_.selltype as selltype15_, orderdetai0_.status as status15_ from OrderDetail orderdetai0_ 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM