自定义注解

注解分类

1、代码注解
2、编译时注解
3、运行时注解

  • 注解范例
package com.alan.oa.biz.test;


import java.lang.annotation.*;

/**
 * 通过@interface关键字定义注解
 */
//源注解,@Target 说明此注解可以作用的相关区域,例如方法上类,接口上。
@Target({ElementType.METHOD,ElementType.FIELD})
/*
 * @Retention生命周期
 * 1、RetentionPolicy.SOURCE 只在源码显示,编译时会丢弃
 * 2、RetentionPolicy.CLASS  编译时会记录到class中,运行时忽略
 * 3、RetentionPolicy.RUNTIME 运行时存在,可以通过反射读取
 */
@Retention(RetentionPolicy.RUNTIME)
// 允许子类只注解来继承
@Inherited
// javadoc *.java 时会包含注解
@Documented
public @interface AnnotationDemo1 {

    // 成员的类型是受限的,合法的类型包括原始类型及String,Class,Annotation,Enumeration
    // 如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=)
    // 注解类可以没用成员,没有成员的注解成为标识注解
    // 成员以无参无异常方式声明
    String desc();
    String author();
    // 可以用default为成员指定一个默认值
    int age() default 18;
}
  • 使用注解的类
package com.alan.oa.biz.test;


@AnnotationDemo1("我是类注解")
public class Demo1 {

    // 使用刚才定义的注解
    @AnnotationDemo1("我是方法注解")
    public String eyeColor(){
        return "red";
    }

    // 使用刚才定义的注解
    @AnnotationDemo1("我是方法注解222")
    public String eyeColor1(){
        return "red";
    }
}
  • 注解解析类
package com.alan.oa.biz.test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * 对注解进行解析的类
 */
public class ParseAnn {

    public static void main(String[] args) {
        // 1、使用类加载器加载类
        try {
            Class  c  = Class.forName("com.alan.oa.biz.test.Demo1");
            // 2、找到类上面的注解 判断当前类是否存在AnnotationDemo1注解
            boolean annotationPresent = c.isAnnotationPresent(AnnotationDemo1.class);
            if(annotationPresent){
                //3、拿到注解实例
                AnnotationDemo1 annotation = (AnnotationDemo1) c.getAnnotation(AnnotationDemo1.class);
                System.out.println(annotation.value());
            }
            // 4、找到方法上的注解,注意这里是方法数组
            Method[] method = c.getMethods();
            for(Method m:method){
                boolean annotationPresent1 =m.isAnnotationPresent(AnnotationDemo1.class);
                if(annotationPresent1){
                    AnnotationDemo1 annotation = m.getAnnotation(AnnotationDemo1.class);
                    System.out.println(annotation.value());
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

注解实战

  • 需求
    1、有一张用户表,字段包括用户id,用户名,昵称,年龄,性别,所在城市,邮箱,手机号。
    2、方便的对每个字段或字段的组合条件进行检索,并打印出sql。
    3、使用方式足够简单。

  • 实体类

package com.alan.oa.biz.test;

/**
 * 通过自定义注解映射数据库表和字段
 */

@Table("user")
public class Fliter {

    @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;

    //getter和setter方法

    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 getEmail() {
        return email;
    }

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

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }
}
  • 注解类
package com.alan.oa.biz.test;


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();
}
package com.alan.oa.biz.test;


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();
}


  • 注解解析类
package com.alan.oa.biz.test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class FilterTest {


    public static void main(String[] args) {

        // 查询id为10的用户
        Fliter f1 = new Fliter();
        f1.setId(10);

        // 查询姓名为lucy的用户
        Fliter f2 = new Fliter();
        f2.setUserName("lucy");

        //查询邮箱为其中任意一个的用户
        Fliter f3 = new Fliter();
        f3.setEmail("[email protected],[email protected],[email protected]");

        String sql1 = query(f1);
        String sql2 = query(f2);
        String sql3 = query(f3);

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

    private static String query(Fliter f){

        StringBuilder sb = new StringBuilder();
        // 1、获取到class
        Class c = f.getClass();
        // 2、获取到table的名字
        boolean annotationPresent = c.isAnnotationPresent(Table.class);
        if(annotationPresent)
        {
            Table t = (Table) c.getAnnotation(Table.class );
            String tableName = t.value();
            sb.append("select * from ").append(tableName).append(" where 1=1");

        }
        // 3、遍历所有的字段
        Field[] fields = c.getDeclaredFields();
        for(Field field:fields){
            // 4、处理每个字段对应的sql
            // 4.1、拿到字段名
            boolean annotationPresent1 = field.isAnnotationPresent(Column.class);
            String columnValue = null;
            if(annotationPresent1){
                Column column = field.getAnnotation(Column.class);
                columnValue = column.value();
            }
            //4.2、拿到字段的值
            String filedName = field.getName();
            String getMethodName = "get" + filedName.substring(0,1).toUpperCase() + filedName.substring(1);
            Object fieldValue = null;
            try {
                Method getMethod = c.getMethod(getMethodName);
                //拿到了字段的值
                fieldValue =  getMethod.invoke(f);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }

            //4.3、拼装sql
            if(fieldValue == null || (fieldValue instanceof Integer && (Integer)fieldValue == 0)) {
                continue;
            }
            sb.append(" and ").append(columnValue);
            if(fieldValue instanceof String){
                if(((String) fieldValue).contains(",")){
                    String[] values = ((String) fieldValue).split(",");
                    sb.append(" in(");
                    for(String str:values){
                        sb.append("'").append(str).append("'").append(",");
                    }
                        sb.deleteCharAt(sb.length()-1);
                        sb.append(")");
                }else {
                    sb.append("=").append("'").append(fieldValue).append("'");
                }
            }else {
                sb.append("=").append(fieldValue);
            }

        }
        return sb.toString();
    }
}

你可能感兴趣的:(自定义注解)