码迷,mamicode.com
首页 > 编程语言 > 详细

Java专题十八:注解

时间:2020-04-25 23:23:01      阅读:64      评论:0      收藏:0      [点我收藏+]

标签:stringbu   set   element   重写   rri   retention   source   access   constant   

Java专题十八:注解

18.1. 元注解

所在包 类名 描述
java.lang Override 表示此方法是重写的,如果父类或接口中不含该方法,则编译报错
java.lang Deprecated 表示方法已过时,不鼓励使用,因为方法是危险的或者有其它更好的方法选择,在程序中使用该方法,会报编译警告
java.lang SuppressWarnings 告诉编译器忽略掉注解中声明的警告
java.lang.annotation Documented 表示可以包含在javadoc等工具生成的文档中
java.lang.annotation Inherited 表示注解类型会被继承到子类中
java.lang.annotation Retention 表示注解类型要保留多久,取值于枚举类java.lang.annotation.RetentionPolicy
java.lang.annotation Target 表示注解适用那种Java成员,取值于枚举类java.lang.annotation.ElementType
java.lang.annotation Native 表示一个字段定义常量值引用自native代码,1.8新增
java.lang.annotation Repeatable 表示注解可以声明多次的,1.8新增

枚举类java.lang.annotation.RetentionPolicy

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

枚举类java.lang.annotation.ElementType

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

18.2. 自定义注解

假设我们设计一个数据库Helper类,用于JDBC插入数据,实现类似mybatis的ORM模型

首先定义2个注解,注解Table标识数据库中表,适用于TYPE类上,注解Column标识数据库中的列,适用于FIELD字段上

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Table {
    String value();
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
    String value();
}

现在有2个javabean类,Student类和Book
因为数据库中的字段与我们实体类中字段名字可能不一致,因此我们使用注解标识实体类与数据库中相关字段的对应关系

@Table("student")
public class Student {
    @Column(value = "std_id")
    int id;
    @Column(value = "std_name")
    String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

@Table("book")
public class Book {
    @Column("book_name")
    String name;
    @Column("book_author")
    String author;
    @Column("price")
    int price;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

使用反射获取字段的值,使用注解获取数据库中字段的名字,拼接SQL语句

import java.lang.reflect.Field;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SQLHelper<T> {
    final Logger logger = Logger.getLogger(SQLHelper.class.getName());

    public int insert(T t){
        if (null == t){
            throw new NullPointerException();
        }
        StringBuilder builder = new StringBuilder();
        Class cls = t.getClass();
        Table table = (Table)cls.getAnnotation(Table.class);
        String tableName = table.value();

        Field[] fields = cls.getDeclaredFields();
        if (0 == fields.length) {
            throw new NullPointerException("No Field");
        } else if (1 == fields.length) {
            String columnName = fields[0].getAnnotation(Column.class).value();
            Object columnValue = null;
            try{
                columnValue = fields[0].get(t);
                if (columnValue instanceof String){
                    columnValue = "\"" + columnValue + "\"";
                }
            }catch (IllegalAccessException e){
                columnValue = "NULL";
            }
            builder.append("INSERT INTO ").append(tableName)
                    .append(" (").append(columnName).append(") ")
                    .append("VALUES(").append(columnValue).append(");");
        } else {
            StringBuilder columnNames = new StringBuilder();
            StringBuilder columnValues = new StringBuilder();
            for (int i = 0; i < fields.length; i++) {
                Column column = fields[i].getAnnotation(Column.class);
                if (null == column)
                    throw new NullPointerException("Unknown Column");
                if (i != fields.length - 1) {
                    columnNames.append(column.value()).append(", ");
                    Object columnValue = null;
                    try{
                        columnValue = fields[i].get(t);
                        if (columnValue instanceof String){
                            columnValue = "\"" + columnValue + "\"";
                        }
                    }catch (IllegalAccessException e){
                        columnValue = "NULL";
                    }
                    columnValues.append(columnValue).append(", ");
                }
                else {
                    columnNames.append(column.value());
                    Object columnValue = null;
                    try{
                        columnValue = fields[i].get(t);
                        if (columnValue instanceof String){
                            columnValue = "\"" + columnValue + "\"";
                        }
                    }catch (IllegalAccessException e){
                        columnValue = "NULL";
                    }
                    columnValues.append(columnValue);
                }
            }
            builder.append("INSERT INTO ").append(tableName)
                    .append("(").append(columnNames).append(") ")
                    .append("VALUES(").append(columnValues).append(");");
        }

        return insert0(builder.toString());
    }
    private int insert0(String sql){
        logger.log(Level.INFO, sql);
        //System.out.println(sql);
        return 1;
    }
}

使用如下代码验证:

Book book0 = new Book();
book0.setName("Thinking in java");
book0.setAuthor("Json");
book0.setPrice(80);
new SQLHelper<Book>().insert(book0);

Student student = new Student();
student.setId(1637);
student.setName("Tom");
new SQLHelper<Student>().insert(student);

输出:

四月 14, 2020 1:24:08 上午 SQLHelper insert0
信息: INSERT INTO book(book_name, book_author, price) VALUES("Thinking in java", "Json", 80);
四月 14, 2020 1:24:08 上午 SQLHelper insert0
信息: INSERT INTO student(std_id, std_name) VALUES(1637, "Tom");

Java专题十八:注解

标签:stringbu   set   element   重写   rri   retention   source   access   constant   

原文地址:https://www.cnblogs.com/myibu/p/12775709.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!