在上一篇文章中我们简单的说了怎样自定义注解。那么我们自定义的注解到底有什么用呢?绝不可能只是一个标记吧,是可以解析出来的吧。
接下来就模仿数据库映射写个例子。
下面来说说如何解析自定义注解:
解析自定义注解
首先我们来自定义一个注解Table也就是数据库里面的表:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
public String value();
}
可以看到这个自定义的注解的作用域是类或接口,而且是一个运行时注解。
有一个String类型的注解成员,当只有一个注解成员的时候,该注解成员名称必须为value。
现在已经有了表名,那么接下来就写关于数据库字段的注解。
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String value();
}
可以看到这个注解的作用域是:ElementType.FIELD也就是字段
是一个运行时注解,同样也有一个注解成员。
下面就开始写数据库的具体字段:
就简单写几个字段~~
@Table("student")
public class Student {
@Column("num")
private int stuNum;
@Column("name")
private String stuName;
@Column("age")
private String stuAge;
public int getStuNum() {
return stuNum;
}
public void setStuNum(int stuNum) {
this.stuNum = stuNum;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public String getStuAge() {
return stuAge;
}
public void setStuAge(String stuAge) {
this.stuAge = stuAge;
}
}
在类的最上面写着@Table("student") 表明了这是一个表,而且表名就叫做student。下面有三个变量每个上面都有@Column的注解,表明这是一个表的字段,具体字段名就看
@Column(“”)括号里面的字符串了。
好了这些都写好我们就开始解析它们。
最后上一张图:
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
Student s1 = new Student();
s1.setStuNum(20);
Student s2 = new Student();
s2.setStuAge(18);
s2.setStuName("gougou");
try {
resolve(s1);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// resolve(s2);
}
@SuppressWarnings("unchecked")
private static void resolve(Student stu) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class c=stu.getClass();
boolean isExist=c.isAnnotationPresent(Table.class);//判断c类是否被Table注解标注
if(!isExist){
return;
}
Table table=(Table) c.getAnnotation(Table.class);//获取注解table
String tableName=table.value();//获取注解的值,也就是这个表的名称
System.out.println("该数据表名:"+tableName);
Field[] fields=c.getDeclaredFields();
// 遍历所有字段
for (Field field : fields) {
//判断字段是否被Column注解标注
if(field.isAnnotationPresent(Column.class)){
Column column= field.getAnnotation(Column.class);
String columnName=column.value();//字段名
String fieldName=field.getName();//变量名称,也就是我们刚才在Student定义的变量名称
//根据我们的getter与setter的命名习惯一般是这样的:getStuNum,所以我们根据这个规则来生成getter的方法名
String methodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
Method getMethod =c.getMethod(methodName);
Object fieldValue = getMethod.invoke(stu);
System.out.println("字段名:"+columnName);
System.out.println("变量名称:"+fieldName);
System.out.println(columnName+" "+fieldValue);//最后输出字段名与相应的值
}
}
}
}
最后上一张图: