java反射與注解結合使用(根據傳入對象輸出查詢sql)


博客已遷移到CSDN《https://blog.csdn.net/qq_33375499

 

  我們在項目開發中有很多地方使用到了注解,關於注解的定義與創建小伙伴可以參考我的文章《java注解》。有任何問題的小伙伴們可以在評論區指出哦,歡迎各位大佬指出問題。

  今天我要說的是使用注解與反射結合使用,來使我們代碼根據優雅,更加高大上(咳,裝逼神器啊)。

  注解使用@interface 來定義,辣么我們自定義的注解,該使用獲取到並且指明該注解的作用呢?java提供了反射機制,通過類的類類型我們可以根據自己需要老操作該類。有管反射的知識,可以參考我的上兩章博客。好了,廢話不多說,我們上代碼:

 需求:創建一個與數據庫表對應的實體類,通過使用注解的方式,來生成該實體類的查詢sql語句。

  1.創建Table類注解,用於標明該類對應數據庫的表名稱

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

  2.創建Column字段注解,用於標明該類中屬性與數據庫表字段的映射

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

  3.創建實體類,並使用注解Table、Column

/**
 * 數據庫 user表,對應表字段為 userid/username/age/addredd
 */
@Table("user")
public class User {
    @Column("userid")
    private String userid;
    @Column("username")
    private String username;
    @Column("age")
    private int age;
    @Column("sl")
    private double sl;
    @Column("address")
    private String address;
    // 添加一個不是數據庫的字段: 用於測試
    private String noField;

    public double getSl() {
        return sl;
    }

    public void setSl(double sl) {
        this.sl = sl;
    }

    public String getNoField() {
        return noField;
    }

    public void setNoField(String noField) {
        this.noField = noField;
    }

    public String getUserid() {
        return userid;
    }

    public void setUserid(String userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

  4.創建工具類,根據傳入該對象,來生成對應的查詢sql

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 注解
 */
public class AnnotationUtil {
    /**
     * 根據傳入的對象 來生成query sql
     *
     * @param object
     * @return
     */
    public static String getSqlByAnnotation(Object object) throws Exception {
        // 使用StringBuilder 線程安全
        StringBuilder sb = new StringBuilder();
        // 檢查參數是否為空
        Objects.requireNonNull(object, "該對象不能為空!");
        // 1.通過反射獲取該對象的類類型
        Class c = object.getClass();
        // 2.獲取該對象的 類注解: 標明表名
        boolean table_flag = c.isAnnotationPresent(Table.class);
        if (!table_flag) {
            throw new NullPointerException();
        }
        Table table = (Table) c.getDeclaredAnnotation(Table.class);
        sb.append("SELECT * FROM ").append(table.value()).append(" WHERE 1 = 1");
        // 3.獲取該對象的 字段注解:顯示查詢字段
        Field[] fields = c.getDeclaredFields();
        boolean field_flag;
        Column column;
        String field_name;
        Method menthod;
        Object val;
        for (Field field : fields) {
            // 首先得拿到字段名稱:通過字段上的注解標明該指定是數據庫表對應的字段
            field_flag = field.isAnnotationPresent(Column.class);
            if (!field_flag) {
                continue;
            }
            column = field.getDeclaredAnnotation(Column.class);
            // 其次得拿到字段值 : 通過反射調用類的getXxxx方法
            field_name = field.getName();
            menthod = c.getDeclaredMethod("get" + Character.toUpperCase(field_name.charAt(0)) + field_name.substring(1));
            val = menthod.invoke(object);
            // 判斷該字段是否為空,不為空,才進行append
            // 這里要注意:有些屬性不賦值時候,java會自動生成默認值,如Double默認為0.0
            // 還有其他類型,小伙伴們可以自行測試
            if (!Objects.isNull(val)) {
                if((val instanceof Double) && (double) val == 0.0){
                    continue;
                }
                sb.append(" AND ").append(column.value()).append(" = ");
                sb.append(val);
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        User user = new User();
        user.setUserid("0001");
        user.setAge(23);
        // 用於測試沒有帶Column注解的字段
        user.setNoField("field");
        try {
            System.out.println(AnnotationUtil.getSqlByAnnotation(user));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM