使用注解

1 篇文章 0 订阅

平常看到注解,比如@Override之类的,没当回事。最近又看了看spring之类的框架,发现有很多东西都是靠注解驱动的,这就使我有了点好奇。这篇博客写的还行

如果还是一点都不了解的,建议先看推荐的这篇博客。

提示:

元标签有 @Retention@Documented@Target@Inherited@Repeatable 5 种。
@Retention

Retention 的英文意为保留期的意思。当 @Retention 应用到一个注解上的时候,它解释说明了这个注解的的存活时间。

它的取值如下: 
- RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。 
- RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。 
- RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,
- 它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
@Documented

顾名思义,这个元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 Javadoc 中去。
@Target

Target 是目标的意思,@Target 指定了注解运用的地方。

你可以这样理解,当一个注解被 @Target 注解时,这个注解就被限定了运用的场景。

类比到标签,原本标签是你想张贴到哪个地方就到哪个地方,但是因为 @Target 的存在,
它张贴的地方就非常具体了,比如只能张贴到方法上、类上、方法参数上等等。@Target 有下面的取值

ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
ElementType.CONSTRUCTOR 可以给构造方法进行注解
ElementType.FIELD 可以给属性进行注解
ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
ElementType.METHOD 可以给方法进行注解
ElementType.PACKAGE 可以给一个包进行注解
ElementType.PARAMETER 可以给一个方法内的参数进行注解
ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
@Inherited

Inherited 是继承的意思,但是它并不是说注解本身可以继承,
而是说如果一个超类被 @Inherited 注解过的注解进行注解的话,
那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解。 
@Repeatable

Repeatable 自然是可重复的意思。@RepeatableJava 1.8 才加进来的,所以算是一个新的特性。

场景:利用注解自动生成sql语句
相关:

  1. 表名:t_user
  2. 主键:t_id
  3. 姓名:t_userName
  4. 号码:t_number

开始写代码

开始定义表的注解
该注解声明了智能作用在类上面
注解可以保留到程序运行的时候

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

开始定义字段的注解

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

实体类


@Table("t_user")
public class Filter {

    @Column("t_id")
    private int id ;

    @Column("t_userName")
    private String userName ;

    @Column("t_number")
    private String number ;

    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 getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    @Override
    public String toString() {
        return "Filter [id=" + id + ", userName=" + userName + ", number=" + number + "]";
    }

}

测试【不会反射的小伙伴自行补充知识吧】


package t3_02;

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

public class Test {
    public static void main(String[] args) {
        Filter filter = new Filter();
        filter.setId(1);
        filter.setUserName("Anne");
        String sql = getSql(filter);
        System.out.println(sql);
    }

    static private String getSql(Filter f) {
        StringBuilder sb = new StringBuilder();//拼接sql

        Class<?> c = f.getClass();
        boolean isExist = c.isAnnotationPresent(Table.class);//这个类是否有这个注解@Table
        if(!isExist) {//没有则停止
            return null ;
        }
        Table table = (Table) c.getAnnotation(Table.class);//获得这个注解的类
        String tableName = table.value();//获取注解的值 【与表的名字对应】
        sb.append("select * from ").append(tableName).append(" where 1=1");

        Field[] fArray = c.getDeclaredFields();//获取所有类型【共有、私有...】的字段 
        for(Field field : fArray) {
//          field.setAccessible(true);
            boolean isExist1 = field.isAnnotationPresent(Column.class);//这个字段是否有这个注解@Column
            if(!isExist1) {
                continue ;
            }
            Column 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);//拼接get方法
            Object fieldValue = null ;
            try {
                Method getMethod = c.getMethod(getMethodName);//获取get方法
                fieldValue = getMethod.invoke(f);//获取到方法后通过反射调用,获取我们设置的值
                if(fieldValue == null) {
                    continue;
                }
                if(fieldValue instanceof Integer && !fieldValue.equals(0)) {
                    sb.append(" and ").append(columnName).append("=").append(fieldValue);
                }else if(fieldValue instanceof String) {
                    sb.append(" and ").append(columnName).append("=").append("'"+fieldValue+"'");
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
        }

        return sb.toString();
    }
}

结果:select * from t_user where 1=1 and t_id=1 and t_userName = ‘Anne’

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值