Java注解

2019-12-20  本文已影响0人  爱吃油果子

一、注解Annotation是什么?

简单讲它的作用是为某个成员,例如类、方法或参数附加上一些元数据,而在程序中则可以通过反射操作获取到这些数据,(搞过C#的应该知道,这个是JDK5.0借鉴的.NET中的Attribute特性)。

二、Java内置的注解

JDK自带注解3个
// 部分参数解释:
@SuppressWarnings("all") // 抑制全部类型的警告
@SuppressWarnings("unchecked")  // 告诉编译器忽略 unchecked 警告信息,如使用List,ArrayList等未进行参数化产生的警告信息
@SuppressWarnings("deprecation")  //   如果使用了使用@Deprecated注释的方法,编译器将出现警告信息,使用这个注解将警告信息去掉
@SuppressWarnings("unchecked", "deprecation") //告诉编译器同时忽略unchecked和deprecation的警告信息
@SuppressWarnings("unused") // 抑制未使用的变量的警告
@SuppressWarnings("serial")  // 抑制某类实现Serializable,但是没有定义serialVersionUID,这个需要但是不必须的字段的警告
@SuppressWarnings("rawtypes") // 抑制没有传递带有泛型的参数的警告
元注解4个(对注解的注解)
RetentionPolicy.SOURCE:当前注解编译期可见,不写入class文件
RetentionPolicy.CLASS:写入class文件,类加载运行时丢弃
RetentionPolicy.RUNTIME:永久保存,可以反射获取(常用)
ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上
ElementType.FIELD:允许作用在属性字段上
ElementType.METHOD:允许作用在方法上
ElementType.PARAMETER:允许作用在方法参数上
ElementType.CONSTRUCTOR:允许作用在构造器上
ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
ElementType.ANNOTATION_TYPE:允许作用在注解上
ElementType.PACKAGE:允许作用在包上
来个实例讲解上面的注解
@Target({ElementType.FIELD}) //或@Target(value = {ElementType.FIELD}),如果注解只有一个值约定值名称为value,故此时可省略

三、第三方注解

四、自定义注解

基于注解和反射实现Java ORM框架(大家都喜欢用这个举例),
废话少说上git代码:https://github.com/storyxiao/annotation-project

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    // 默认固定命名为value
    String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    // 数据表字段名
    String name();
    // 查询匹配条件:EQ、LIKE
    String value();
}
@Table("user")
public class User {

    @Column(name = "id", value = "EQ")
    private int id;

    @Column(name = "user_name", value = "LIKE")
    private String userName;

    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 class TestMain {
    private static String getQuerySql(User user) {
        StringBuilder sb = new StringBuilder();
        sb.append("select * from ");
        Class c = user.getClass();
        if (c.isAnnotationPresent(Table.class)) {
            // 获取表名
            Table table = (Table) c.getAnnotation(Table.class);
            String tableName = table.value();
            sb.append(tableName).append(" where 1=1 ");
            // 获取字段名
            Field[] fields = c.getDeclaredFields();
            for (Field f : fields) {
                if (f.isAnnotationPresent(Column.class)) {
                    Column column = (Column) f.getAnnotation(Column.class);
                    // 得到注解:user_name 数据库中字段名
                    String columnName = column.name();
                    String columnValue = column.value();
                    // 得到成员变量名:userName
                    String filedName = f.getName();
                    // 构造get方法名形如:getUserName
                    String getMethodName = "get" + filedName.substring(0, 1).toUpperCase() + filedName.substring(1);
                    Object filedValue = null;
                    try {
                        // 反射获取值
                        Method getMethod = c.getMethod(getMethodName);
                        filedValue = getMethod.invoke(user);
                        // 合成SQL,这里就不对每种数据类型做处理了
                        String conStr = String.format(" and %s = '%s'", columnName, filedValue);
                        if (f.getGenericType().toString().equals("class java.lang.String")) {
                            if (columnValue.toUpperCase().equals("LIKE")) {
                                conStr = String.format(" and %s LIKE '%s%s%s'", columnName, "%", filedValue, "%");
                            } else {
                                conStr = String.format(" and %s = '%s'", columnName, filedValue);
                            }
                        } else if (f.getGenericType().toString().equals("int")) {
                            conStr = String.format(" and %s = %s", columnName, filedValue);
                        }
                        //
                        sb.append(conStr);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        // 返回构造的SQL字符串
        return sb.toString();
    }

    public static void main(String[] args) throws ClassNotFoundException {
        User user = new User();
        user.setId(1);
        user.setUserName("xiao");
        String sql = getQuerySql(user);
        System.out.println(sql);
    }
}
上一篇 下一篇

猜你喜欢

热点阅读