一、原理
1. 注解的定义与约束
import java.lang.annotation.*; /* 作用域: CONSTRUCTOR构造方法, FIELD字段, LOCAL_VARIABLE局部变量, * METHOD方法, PACKAGE包, PARAMETER参数, TYPE接口类型 */ @Target({ElementType.METHOD, ElementType.TYPE}) /* 生命周期: SOURCE源代码级不保留到class文件, CLASS级保留到class运行时丢弃, * RUNTIME运行时存在可反射获取 */ @Retention(RetentionPolicy.RUNTIME) //允许子类继承注解(可选), 只支持继承class的注解不能继承interface的注解 @Inherited //生成javadoc时会包含注解(可选) @Deprecated public @interface DemoAnn { /* 注解成员参数必须以类型名加无参无异常方法名指定 * 如果只有一个成员参数必须名为value(), 没有成员参数的注解为标识注解 * 成员参数类型只能是基础类型或String或class或注解 */ String desc(); String author(); int age() default 29; }
2. 利用反射获取注解信息实例
import java.lang.annotation.Annotation; import java.lang.reflect.*; interface Action { @SuppressWarnings("deprecation") @DemoAnn(desc = "Method_Name Ann", author = "Athrun") String name(); @Deprecated String action(); } class Base { @SuppressWarnings("deprecation") @DemoAnn(desc = "BaseMethod1 Ann", author = "Athrun") public String fun1() { return "Base's fun1"; } @SuppressWarnings("deprecation") @DemoAnn(desc = "BaseMethod2 Ann", author = "Athrun") public String fun2() { return "Base's fun2"; } public String name() { return null; } } @DemoAnn(desc = "Class's Ann", author = "Athrun") class Person extends Base implements Action { @Override public String name() { // TODO Auto-generated method stub return "Ghost"; } @Override @SuppressWarnings("deprecation") @DemoAnn(desc = "Method_Action Ann", author = "Athrun") public String action() { // TODO Auto-generated method stub return null; } //重写Base的fun2去掉了注解,输出中就不会出现父类fun2()注释内容 @Override public String fun2() { return "Person's fun2"; } } public class AnnTest { @SuppressWarnings("rawtypes") public static void main(String[] args) { // TODO Auto-generated method stub //解析注解 try { //1. 使用类加载器加载类 Class cl = Class.forName("org.znufe.anns.Person"); //2. 寻找注解 boolean isExist = cl.isAnnotationPresent(DemoAnn.class); if(isExist) { //3. 获取类上的注解 DemoAnn demoAnn = (DemoAnn) cl.getAnnotation(DemoAnn.class); System.out.println("Ann's desc: " + demoAnn.desc() + ", author: " + demoAnn.author() + ", age: " + demoAnn.age()); } //4. 获取方法上的注解 //4.1 逐个方法查找 Method[] methods = cl.getMethods(); for(Method m : methods) { isExist = m.isAnnotationPresent(DemoAnn.class); if(isExist) { DemoAnn demoAnn = (DemoAnn) m.getAnnotation(DemoAnn.class); System.out.println("Ann's desc: " + demoAnn.desc() + ", author: " + demoAnn.author() + ", age: " + demoAnn.age()); } } //4.2 直接获取方法上的所有注解, 然后筛选出DemoAnn类型注解 for(Method m : methods) { Annotation[] annotations = m.getAnnotations(); for(Annotation a : annotations) { if(a instanceof DemoAnn) { DemoAnn demoAnn = (DemoAnn) a; System.out.println("Ann's desc: " + demoAnn.desc() + ", author: " + demoAnn.author() + ", age: " + demoAnn.age()); } } } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /* 输出如下: * Ann's desc: Class's Ann, author: Athrun, age: 29 * Ann's desc: Method_Action Ann, author: Athrun, age: 29 * Ann's desc: BaseMethod1 Ann, author: Athrun, age: 29 * Ann's desc: Method_Action Ann, author: Athrun, age: 29 * Ann's desc: BaseMethod1 Ann, author: Athrun, age: 29 * */
二、模拟数据表关系对象映射的查询(只获取sql语句,省略实际查询过程)
1. Entity
/** * @category Entity * @author Athrun * User实体类 */ @Table("user") public class User { @Column("user_name") private String userName; @Column("pass_word") private String passWord; @Column("age") private int age; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
/** * @category Entity * @author Null's * Depart实体类 */ @Table("depart") public class Depart { @Column("leader") private String leader; @Column("depart_name") private String departName; @Column("num") private int num; public String getLeader() { return leader; } public void setLeader(String leader) { this.leader = leader; } public String getDepartName() { return departName; } public void setDepartName(String departName) { this.departName = departName; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } }
2. Annotation
/** * @author Athrun * Table注解用于保存对象对应表名 */ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Table { String value(); }
/** * @author Athrun * Column注解用于标识对象属性在数据表中对应的字段 */ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Column { String value(); }
3. Impl
import java.lang.reflect.Field; import java.lang.reflect.Method; /** * @category Impl * @author Athrun * 用于创建初始数据并生成查询语句 */ public class AnnImpl { public static void main(String[] args) { // TODO Auto-generated method stub User u1 = new User(); u1.setUserName("aaa"); User u2 = new User(); u2.setPassWord("123456,654321"); User u3 = new User(); u3.setAge(29); User u4 = new User(); u4.setAge(25); u4.setPassWord("123456"); String sql1 = query(u1); String sql2 = query(u2); String sql3 = query(u3); String sql4 = query(u4); System.out.println(sql1); System.out.println(sql2); System.out.println(sql3); System.out.println(sql4); Depart depart = new Depart(); depart.setDepartName("Develop"); depart.setLeader("Athrun"); depart.setNum(10); String sql = query(depart); System.out.println(sql); } private static<T> String query(T t) { StringBuilder sb = new StringBuilder(); //1. 获取class Class cl = t.getClass(); //2. 获取table的名字 boolean exists = cl.isAnnotationPresent(Table.class); if(!exists) { return null; } Table table = (Table) cl.getAnnotation(Table.class); String tableName = table.value(); sb.append("select * from ").append(tableName).append(" where 1=1"); //3. 遍历所有字段 Field[] fields = cl.getDeclaredFields(); //4. 处理每个字段对应sql //只关心被注解的属性 for(Field f : fields) { //4.1 寻找注解 boolean fieldExists = f.isAnnotationPresent(Column.class); if(!fieldExists) { continue; } //4.2 获取字段名 Column column = f.getAnnotation(Column.class); //获取注解 String columnName = column.value(); //获取注解里保存的字段值 //4.3 获取字段值 String fieldName = f.getName(); String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Object fieldValue = null; //因为变量有各种类型, 用Object最为保险 try { Method getMethod = cl.getMethod(getMethodName); fieldValue = getMethod.invoke(t); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } //4.4 拼装sql //只关心有实际值的属性 if(fieldValue == null || (fieldValue instanceof Integer && (Integer) fieldValue == 0)) { continue; } sb.append(" and ").append(columnName); if(fieldValue instanceof String) { if(((String) fieldValue).contains(",")) { String[] values = ((String) fieldValue).split(","); sb.append(" in("); for(String v : values) { sb.append("'").append(v).append("'").append(", "); } sb.deleteCharAt(sb.length() - 1); sb.deleteCharAt(sb.length() - 1); sb.append(")"); }else { sb.append(" = ").append("'").append(fieldValue).append("'"); } }else if(fieldValue instanceof Integer){ sb.append(" = ").append(fieldValue); } } return sb.toString(); } } /* * 输出如下: * select * from user where 1=1 and user_name = 'aaa' * select * from user where 1=1 and pass_word in('123456', '654321') * select * from user where 1=1 and age = 29 * select * from user where 1=1 and pass_word = '123456' and age = 25 * select * from depart where 1=1 and leader = 'Athrun' and depart_name = 'Develop' and num = 10 */