您的位置:首页 > 编程语言 > Java开发

java注解,@,注解有什么用?

2017-03-07 16:35 162 查看
本例子旨在使用自定义注解为实体打上标记,为自动生成 sql 提供依据,模拟
hibernate 的注解,至于注解的原理自己搜吧

1.定义 Table 注解

package 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;  
  
@Inherited  
@Target({ElementType.TYPE})  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface Table {  
    String value() default "";  
}  

2.定义 Column 注解

package 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;  
  
@Inherited  
@Target({ElementType.FIELD})  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface Column {  
    String value() default "";  
}  

3.定义使用注解的实体

package test;  
  
  
@Table("tb_test")  
public class TestDto {  
      
    @Deprecated  
    private String tt;  
      
    @Column("_id")  
    private String id;  
      
    @Column("username")  
    private String name;  
      
    public TestDto(String id, String name) {  
        super();  
        this.id = id;  
        this.name = name;  
    }  
  
    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;  
    }  
      
      
}  

4.测试注解

package test;  
  
import java.lang.reflect.Field;  
import java.lang.reflect.Method;  
  
public class Test {  
    public static void main(String[] args) {  
        TestDto testDto = new TestDto("123", "34");  
        TestDto testDto1 = new TestDto("123", "test1");  
        TestDto testDto2 = new TestDto("", "test1,test2,test3,test4");  
        String sql = assembleSqlFromObj(testDto);  
        String sql1 = assembleSqlFromObj(testDto1);  
        String sql2 = assembleSqlFromObj(testDto2);  
        System.out.println(sql);  
        System.out.println(sql1);  
        System.out.println(sql2);  
    }  
  
    /** 
     * 通过注解来组装查询条件,生成查询语句 
     *  
     * @param obj 
     * @return 
     */  
    public static String assembleSqlFromObj(Object obj) {  
        Table table = obj.getClass().getAnnotation(Table.class);  
        StringBuffer sbSql = new StringBuffer();  
        String tableName = table.value();  
        sbSql.append("select * from " + tableName + " where 1=1 ");  
        Field[] fileds = obj.getClass().getDeclaredFields();  
        for (Field f : fileds) {  
            String fieldName = f.getName();  
            String methodName = "get" + fieldName.substring(0, 1).toUpperCase()  
                    + fieldName.substring(1);  
            try {  
                Column column = f.getAnnotation(Column.class);  
                if (column != null) {  
                    Method method = obj.getClass().getMethod(methodName);  
                    String value = (String) method.invoke(obj);  
                    if (value != null && !value.equals("")) {  
                        if (!isNum(column.value()) && !isNum(value)) {  
                            // 判断参数是不是 in 类型参数 1,2,3  
                            if (value.contains(",")) {  
                                sbSql.append(" and " + column.value() + " in (" + value + ") ");  
                            } else {  
                                sbSql.append(" and " + column.value() + " like '%" + value + "%' ");  
                            }  
                        } else {  
                            sbSql.append(" and " + column.value() + "=" + value + " ");  
                        }  
                    }  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
        return sbSql.toString();  
    }  
  
    /** 
     * 检查给定的值是不是 id 类型 1.检查字段名称 2.检查字段值 
     *  
     * @param target 
     * @return 
     */  
    public static boolean isNum(String target) {  
        boolean isNum = false;  
        if (target.toLowerCase().contains("id")) {  
            isNum = true;  
        }  
        if (target.matches("\\d+")) {  
            isNum = true;  
        }  
        return isNum;  
    }  
}  

测试结果:select * from tb_test where 1=1  and _id=123  and username=34

select * from tb_test where 1=1  and _id=123  and username like '%test1%'
select * from tb_test where 1=1  and username in (test1,test2,test3,test4)

该例子解析:

1本例子是编写了一个简单的类似于hibernate的框架,框架的作用是,通过对象的操作的方式,替代写sql语句。

2本例用到了映射机制,什么是java映射?我理解就是:通过类的对象,获取该对象的类的相关信息。obj.getClass().getAnnotation(Table.class)

3注解起到配置文件的作用:



@Table("tb_test")  

public class TestDto { 

意思是,我想将TestDto类和tb_test表绑定起来。

首先new了一个TestDto对象如testDto1,然后进入我的框架(说白了就是文中的assembleSqlFromObj方法)对testDto1进行处理,通过testDto1获取该对象的类即TestDto.Class,然后获取该类的名为“Table”的注解,获取注解类的成员变量(即value)的值,即“tb_test”。

总结:

1java的反射机制就是,通过类的对象,获取该对象的类的相关信息。类的相关信息包括:①用了什么注解
②类的名称 ③各成员变量的名称等。

2什么时候用到注解?我们一般用不到自定义注解,我们平时别人开发好的框架如Hibernate、spring、Struts等时,只需要按照框架的规则在代码里定义注解即可,而不会在代码里调用和操作注解。只有在自己动手写类似于Hibernate框架的时候,会用到自定义注解。这也是为什么我们一般用不到java反射,因为只有在使用自定义注解的时候,才会用到java反射,而我们平时连自定义注解都用不到
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: