美文网首页
注解的简单使用

注解的简单使用

作者: 一只在时光里流浪的大懒猫 | 来源:发表于2019-03-21 22:02 被阅读0次

    一、基本认识

    我们知道,注释是给人看的,那么注解,其实就是给“程序”看的。

    jdk内部注解(1.5之后):

    • @Deprecated 意思是“废弃的,过时的”
    • @Override 意思是“重写、覆盖”
    • @SuppressWarnings 意思是“压缩警告”

    自定义注解,需要使用元注解,其为“注解的注解”,并在运行时通过反射获取并处理。

    元注解:

    • @Target:注解的作用目标
      作用域:
      CONSTRUCTOR:构造器的声明
      FIELD:域声明(包括enum实例)
      LOCAL_VARIABLE:局部变量声明
      METHOD:方法声明
      PACKAGE:包声明
      PARAMETER:参数声明
      TYPE:类、接口(包括注解类型)或enum声明
    • @Retention:注解的生命周期
    • @Documented:注解是否应当被包含在 JavaDoc 文档中
    • @Inherited:是否允许子类继承该注解

    二、简单使用

    一个例子:

    @Target({ElementType.FIELD}) // 使用范围:属性域
    @Retention(RetentionPolicy.RUNTIME) // 运行时
    public @interface Level {
        String value () default "one"; // value默认为one
    }
    

    使用:

    public class ColorLevel{
      @Level // 这里取默认值,one
      private String green;
    
      @Level(value="two") // 正常设置,为two
      private String yellow;
    
      @Level("three") // 这里要注意,如果自定义注解中,第一个属性名称为value,则其可省略简写
      private String red;
    }
    

    利用反射获取:

        public static void main(String[] args){
    
            ColorLevel colorLevel = new ColorLevel();
            Field[] fields = colorLevel.getClass().getDeclaredFields();
            for (Field field:fields) {
                field.setAccessible(true);
                // 获取属性上的注解
                Level level = field.getAnnotation(Level.class);
                if(level != null){
                    System.out.println("颜色:"+field.getName()+" 对应级别为:"+level.value());
                }
            }
        }
    

    输出结果:

    颜色:green 对应级别为:one
    颜色:yellow 对应级别为:two
    颜色:red 对应级别为:three
    

    三、使用场景

    在实体类上标注解,用以拼接sql。
    Column注解

    @Inherited
    @Target({ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Column {
        String value() default "";
    }
    

    Table注解

    @Inherited
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Table {
        String value() default "";
    }
    

    实体类 user.java

    @Table("user")
    public class User {
    
        @Query
        @Column("id")
        private String id;
    
        @Column("name")
        private String name;
    
        private String address;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    }
    

    解析注解,组装sql

        public static String assembleSelSQL(Object obj) throws Exception{
    
            StringBuffer sql = new StringBuffer();
            sql.append("select ");
    
            StringBuffer sqlWhere = new StringBuffer();
            sqlWhere.append(" where 1=1 ");
    
            // 获取类上的注解
            boolean isTable = obj.getClass().isAnnotationPresent(Table.class);
            if (isTable) {
                Field[] fields = obj.getClass().getDeclaredFields();
                for (Field field:fields){
                    field.setAccessible(true);
                    // 获取属性上的注解
                    Column column = field.getAnnotation(Column.class);
                    if(column != null){
                        sql.append(field.getName()+",");
                    }
                    Query query = field.getAnnotation(Query.class);
                    if(query != null){
                        sqlWhere.append(" and "+field.getName()+"='"+field.get(obj)+"'");
                    }
                }
    
                Table table = obj.getClass().getAnnotation(Table.class);
                sqlWhere.insert(0," from "+table.value()).insert(0,sql.substring(0,sql.length()-1));
            }
    
            return sqlWhere.toString();
        }
    

    使用

       public static void main(String[] args){
    
            User user = new User();
            user.setId("001");
            user.setName("nep");
    
            try {
                String sql = assembleSelSQL(user);
                System.out.println(sql);
            }catch (Exception e){
                e.printStackTrace();
            }
    
    
        }
    

    输出

    select id,name from user where 1=1  and id='001'
    

    总结:
    从上面的例子可以看出来,通过注解,可以告诉程序,(类、方法、字段)可以做什么,如:组装sql;但是没有告诉我们,哪里可以做?试想,如果结合aop(动态代理)技术,来告诉我们哪里可以做,那么,我们是不是可以“为所欲为”了呢?

    比如:
    1.自定义简化版orm框架;
    2.自定义简化版日志框架;
    3.参数校验、过滤等。

    下一篇,我们结合 注解+AOP技术,来一一实现。

    相关文章

      网友评论

          本文标题:注解的简单使用

          本文链接:https://www.haomeiwen.com/subject/gcxtuqtx.html