JAVA笔记——自定义注解

  • 如何自定义注解
    • Target
    • Retention
    • Inherited
    • Documented
  • 如何使用自定义注解
    • 需求
    • 实现
    • 运行结果

如何自定义注解

这里是一个自定义的注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface AnnoDemo {

    public int value1();

    public String value2();

    public String value3() default "value3";
}

注解参数支持的数据类型:

  1. 所有基本数据类型(int,float,boolean,byte,double,char,long,short)
  2. String类型
  3. Class类型
  4. enum类型
  5. Annotation类型
  6. 以上所有类型的数组

如果只有一个属性,那么必须命名为value,如 public String value();

这里出现了四个注解:

  1. Target
  2. Retention
  3. Inherited
  4. Documented

Target

表示注解的作用域,它有以下几种值

  1. ElementType.TYPE : 类或者接口

  2. ElementType.FIELD : 类的属性

  3. ElementType.METHOD: 方法

  4. ElementType.PARAMETER : 参数

  5. ElementType.CONSTRUCTOR :构造函数

  6. ElementType.LOCAL_VARIABLE :局部变量

  7. ElementType.ANNOTATION_TYPE :注解

  8. ElementType.PACKAGE :包

Retention

表示注解的生命周期

  1. RetentionPolicy.SOURCE:注解将被编译器丢弃

  2. RetentionPolicy.CLASS:注解在class文件中可用,但会被VM丢弃

  3. RetentionPolicy.RUNTIME:将在运行期也保留注释,因此可以通过反射机制读取注解的信息

Inherited

表示该注解可以被子类继承

Documented

表示该注解会被生成javadoc文档

如何使用自定义注解

这里写个简单的例子

需求

  1. 编写一个实体类User
  2. 编写一个注解为Table,表示User对应的数据库表
  3. 编写一个注解为Column,表示User中属性对应的表字段
  4. 通过user实例自动生成查询sql语句(条件查询)

实现

Table注解

package com.anno.test;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Table {

    public String value();
}

Column注解

package com.anno.test;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Column {

    public String value();
}

User实体类,使用Table和Column注解

package com.anno.test;

@Table("USER")
public class User {

    @Column("ID")
    private Integer id;

    @Column("NAME")
    private String name;

    @Column("EMAIL")
    private String email;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }


}

通过注解生成sql语句

package com.anno.test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class TestMain {

    public static void main(String[] args) {

        User user1 = new User();
        user1.setId(1);

        User user2 = new User();
        user2.setId(2);
        user2.setName("peter");

        User user3 = new User();
        user3.setId(3);
        user3.setName("tom");
        user3.setEmail("[email protected]");

        String sql1 = createSql(user1);
        String sql2 = createSql(user2);
        String sql3 = createSql(user3);

        System.out.println(sql1);
        System.out.println(sql2);
        System.out.println(sql3);
    }

    /**
     * 自动生成条件查询sql
     * @param object
     * @return
     */
    public static String createSql(Object object){

        StringBuffer sb = new StringBuffer();

        Class c = object.getClass();
        //判断该类是否有Table注解
        boolean tExist = c.isAnnotationPresent(Table.class);
        if(!tExist){
            return null;
        }
        //获取Table注解
        Table table = (Table) c.getAnnotation(Table.class);
        //获取注解的value(数据库中对应的表明)
        String tableName = table.value();
        sb.append("SELECT * FROM ").append(tableName).append(" WHERE 1=1");

        //获取这个类的所有字段
        Field[] fields = c.getDeclaredFields();
        for(Field field: fields){
            //判断该属性是否有Column注解
            boolean fExist = field.isAnnotationPresent(Column.class);
            if(!fExist){
                continue;
            }
            //获取该字段的注解
            Column column = (Column)field.getAnnotation(Column.class);
            //获取注解的value(数据库中对应的字段名)
            String columnName = column.value();
            //通过get方法拿到该字段的值
            String fieldName = field.getName();
            //get方法 = get + 字段名(首字母大写)
            String getMethodName = "get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);

            try {
                //执行get方法
                Method m = c.getMethod(getMethodName);
                Object fieldValue =  m.invoke(object);
                //拼接sql语句
                if(fieldValue == null){
                    continue;
                }
                if(fieldValue instanceof Integer){
                    sb.append(" AND ").append(columnName).append("=").append(fieldValue);
                }else if(fieldValue instanceof String){
                    sb.append(" AND ").append(columnName).append("='").append(fieldValue).append("'");
                }

            } catch (Exception e) {
                e.printStackTrace();
            } 

        }
        return sb.toString();
    }
}

运行结果

JAVA笔记——自定义注解_第1张图片

你可能感兴趣的:(JAVA)