最近有所了解到自定义注解的应用,因此学习了一下,在项目后台接口开发中,数据的传输经常有对数据内容格式及一些信息规则的校验,应用注解在数据进入后台的开始使用自定义注解是一种比较可靠的方案。
一、注解的概念及分类
1.首先我们来看一下什么是注解:
注解就是某种注解类型的一个实例,我们可以用它在某个类上进行标注,这样编译器在编译我们的文件时,会根据我们自己设定的方法来编译类。
2.注解的分类
注解大体上分为三种:标记注解,一般注解,元注解,@Override用于标识,该方法是继承自超类的。这样,当超类的方法修改后,实现类就可以直接看到了。而@Deprecated注解,则是标识当前方法或者类已经不推荐使用,如果用户还是要使用,会生成编译的警告。
二、自定义注解
1.自定义注解的概念:
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
定义注解格式:
public @interface 注解名 {定义体}
注解参数的可支持数据类型:
1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
2.String类型
3.Class类型
4.enum类型
5.Annotation类型
6.以上所有类型的数组
Annotation类型里面的参数该怎么设定:
第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;
第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;
第三,如果只有一个参数成员,最好把参数名称设为"value",后加小括号.例:下面的例子FruitName注解就只有一个参数成员。
2.三个关键参数
*1、指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS
*2、有三种取值(代表三个阶段):
* RetentionPolicy.SOURCE:保留注解到java源文件阶段,例如Override、SuppressWarnings
* RetentionPolicy.CLASS:保留注解到class文件阶段,例如
* RetentionPolicy.RUNTIME:保留注解到运行时阶段即内存中的字节码,例如Deprecated
*/
//元注解:表示的是注解的注解,(同义词有元信息、元数据)
//如果不加,javac会把这无用的注解丢掉
@Retention(RetentionPolicy.RUNTIME)
*3.@Target({ElementType.TYPE,ElementType.METHOD})//指定该注解使用的用处:用在class上和用在方法体上。
三、代码示例
下面我们模拟一下Hibernatez@Column和@Table 注解的自定义
首先我们自定义两个注解类:
1.@Column注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by Tanyunlong on 2016/12/3.
* 数据库表中 字段 的注解映射
*/
@Target({ElementType.FIELD})//作用域是类或者接口
@Retention(RetentionPolicy.RUNTIME)//注解类型:运行时注解
public @interface Column {
String value();//注解只有一个变量时 变量名必须为value
}
2.@Table注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by Tanyunlong on 2016/12/3.
* 数据库名 @Table 映射注解
*/
@Target({ElementType.TYPE})//作用域是类或者接口
@Retention(RetentionPolicy.RUNTIME)//注解类型:运行时注解
public @interface Table {
String value();//注解只有一个变量时 变量名必须为value
}
3.定义表映射实体类
/**
* Created by Tanyunlong on 2016/12/3.
* 映射注解类
*/
@Table("user")
public class Filter {
@Column("id")
private int id;
@Column("user_name")
private String userName;
@Column("nick_name")
private String nickName;
@Column("age")
private int age;
@Column("city")
private String city;
@Column("email")
private String email;
@Column("mobile")
private String mobile;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
4.解析注解类,编写规则及测试类
import javafx.scene.control.Tab;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Objects;
/**
* Created by Tanyunlong on 2016/12/3.
*/
public class Test {
public static void main(String[] args){
Filter f1=new Filter();
f1.setId(10);
Filter f2=new Filter();
f2.setUserName("tanyunlong");
Filter f3=new Filter();
f3.setEmail("1234567@qq.com,xiaoming@163.com");
String sql1=query(f1);
String sql2=query(f1);
String sql3=query(f1);
}
public static String query(Filter filter){
StringBuffer sb=new StringBuffer();
//1.获取到Class
Class c= filter.getClass();
//2.获取到table的名字
boolean exists= c.isAnnotationPresent(Table.class);
if (!exists){
return null;
}
Table t=(Table)c.getAnnotation(Table.class);
String tableName= t.value();
sb.append("select * from").append(tableName).append("where 1=1");
//3.遍历所有字段
Field[] fArray=c.getDeclaredFields();
for (Field field:fArray){
/**
* 4.处理每个字段对应的sql
* 拿到字段名 字段值 拼装sql
*/
boolean fExists=field.isAnnotationPresent(Column.class);
if (!fExists){
continue;
}
Column column= field.getAnnotation(Column.class);
String columnName=column.value();//字段名
String fieldName=field.getName();
String getMethodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
Object fieldValue=null;
try {
Method getMethod=c.getMethod(getMethodName);
fieldValue=getMethod.invoke(filter);//字段值
} catch (Exception e) {
e.printStackTrace();
}
//拼装sql
if (fieldValue==null||(fieldValue instanceof Integer&&(Integer)fieldValue==0)){
continue;
}
sb.append("and").append(field).append("=").append(fieldValue);
}
System.out.println(sb.toString());
return sb.toString();
}
}