【原创】基于注解运行时动态ORM映射

由于当前项目采用了分表策略,故一个实体会对应多个相同结构的表。只是映射的表名不一样而已~项目又使用憨包儿呢特(Hibernate),让我采用原生SQL总感觉不是那么爽,咋办呢?!第一念头就是如果能够动态映射就好啦,也就是现在想查table1只需将实体对应的 table映射为table1即可。咋个实现动态映射呢?!也就是需要动态改变类的注解。又咋个能够动态改变类的注解呢?!本质上修改字节码,重新加载类即可,也就是所谓的字节码增强功能~  看都看不懂字节码咋个修改呢?!还是需要站在巨人的肩上才行。ASM以及JDK自带的字节码增强都不用,马上想到CGlib,javassist。。。还是痛苦的折腾了良久,为了大家不走我的弯路~ 直接上代码先~

动态映射代码如下:

   1:  public class ClassPoolUtils {
   2:  
   3:  
   4:      /**
   5:       * 动态ORM映射
   6:       * 
   7:       * @param entityClassName   待映射的实体全限定类名
   8:       * @param tableName         待映射的表名
   9:       * @return                  映射后的类对象
  10:       */
  11:      public static Class<?> tableMapping(String entityClassName, String tableName){
  12:          Class<?> c = null;
  13:          try {
  14:              ClassPool classPool = ClassPool.getDefault();
  15:              classPool.appendClassPath(new ClassClassPath(ClassPoolUtils.class));
  16:              classPool.importPackage("javax.persistence");
  17:              CtClass clazz = classPool.get(entityClassName);
  18:              ClassFile classFile = clazz.getClassFile();
  19:  
  20:              System.out.println("增强前Entity01:" + clazz.getAnnotation(Entity.class));
  21:              System.out.println("增强前Table02:" + clazz.getAnnotation(Table.class));
  22:  
  23:              ConstPool constPool = classFile.getConstPool();
  24:              Annotation tableAnnotation = new Annotation("javax.persistence.Table", constPool);
  25:              tableAnnotation.addMemberValue("name", new StringMemberValue(tableName, constPool));
  26:              // 获取运行时注解属性
  27:              AnnotationsAttribute attribute = (AnnotationsAttribute)classFile.getAttribute(AnnotationsAttribute.visibleTag);
  28:              attribute.addAnnotation(tableAnnotation);
  29:              classFile.addAttribute(attribute);
  30:              classFile.setVersionToJava5();
  31:              //clazz.writeFile();
  32:  
  33:              System.out.println("增强后Entity001:" + clazz.getAnnotation(Entity.class));
  34:              System.out.println("增强后Table002:" + clazz.getAnnotation(Table.class));
  35:              //TODO 当前ClassLoader中必须尚未加载该实体。(同一个ClassLoader加载同一个类只会加载一次)
  36:              c = clazz.toClass();
  37:              System.out.println("增强后toClass-Entity0001:" + c.getAnnotation(Entity.class));
  38:              System.out.println("增强后toClass-Table0002:" + c.getAnnotation(Table.class));
  39:          } catch (Exception e) {
  40:              e.printStackTrace();
  41:          }
  42:  
  43:          return c;
  44:      }
  45:   
  46:      public static void main(String[] args) {
  47:            ClassPoolUtils.tableMapping("com.andy.model.Order", "order1");
  48:      }

执行结果:

   1:  增强前Entity01:@javax.persistence.Entity
   2:  增强前Table02:null
   3:  增强后Entity001:@javax.persistence.Entity
   4:  增强后Table002:@javax.persistence.Table(name="order1")
   5:  增强后toClass-Entity0001:@javax.persistence.Entity(name=)
   6:  增强后toClass-Table0002:@javax.persistence.Table(schema=, catalog=, uniqueConstraints=[], name=order1)

转载于:https://my.oschina.net/andy0807/blog/88585

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值