因为当前项目采用了分表策略,故一个实体会对应多个相同结构的表。只是映射的表名不同而已~项目又使用憨包儿呢特(Hibernate),让我采用原生SQL总感受不是那么爽,咋办呢?!第一念头就是若是可以动态映射就好啦,也就是如今想查table1只需将实体对应的 table映射为table1便可。咋个实现动态映射呢?!也就是须要动态改变类的注解。又咋个可以动态改变类的注解呢?!本质上修改字节码,从新加载类便可,也就是所谓的字节码加强功能~ 看都看不懂字节码咋个修改呢?!仍是须要站在巨人的肩上才行。ASM以及JDK自带的字节码加强都不用,立刻想到CGlib,javassist。。。仍是痛苦的折腾了良久,为了你们不走个人弯路~ 直接上代码先~css
动态映射代码以下:html
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: }
执行结果:java
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)