码迷,mamicode.com
首页 > 其他好文 > 详细

动态修改类注解(赋值)

时间:2015-10-30 22:59:30      阅读:583      评论:0      收藏:0      [点我收藏+]

标签:

   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_ 

动态修改类注解(赋值)

标签:

原文地址:http://www.cnblogs.com/cunkouzh/p/4924504.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!