Java 註解 實踐

註解實踐

粗略的作一個簡單實踐,作一個ORM小方案,經過註解來實現java

  • 一張user表信息,字段: id、用戶名、暱稱、年齡、性別、地址、郵箱、手機號
  • 簡單的對每一個字段或組合條件進行檢索,打印SQL方式來顯示結果

對數據執行檢索,就要考慮怎麼和數據庫進行映射,數據對應有表名,字段名,人爲定義的user也最類似於數據庫表,好比JPA或其餘,在user對象上能夠加@Table、@Entry、@Column等註解標識,以對應數據庫的表信息sql

下面建立註解@MyTable,應用在類上,而且能夠指定表名,只有一個值,以下: 數據庫

import java.lang.annotation.*;

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

再來定義一個@MyColumn註解,用在字段上,也須要一個值,以下:app

import java.lang.annotation.*;

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

在實體對象加上註解ui

@Data
@MyTable("user_info")
public class User {
    @MyColumn("id")
    private Integer id;
    @MyColumn("user_name")
    private String userName;
    @MyColumn("nick_name")
    private String nickName;
    @MyColumn("age")
    private Integer age;
    @MyColumn("address")
    private String address;
    @MyColumn("email")
    private String email;
}

基本對象有了,那麼接下來,須要建立SQL,定義一個query方法,下面粗略的實現,返回字符串便可spa

package com.cloud.eureka.Practice;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class UserMain {

    public static void main(String[] args) throws Exception {
        User user = new User();
        user.setId(9527);
        user.setNickName("華安");
        user.setAddress("下沙");
        user.setEmail("hello@163.com,hi@qq.com,biu@sina.com");
        user.setUserName("HaHaHa");
        String sql = query(user);
        System.out.println(sql);
    }

    public static String query(User user) throws Exception {
        String SQL_MODEL = "select %s from %s where 1=1%s";
        //1. 獲取class試驗,直接獲取User對象,也能夠Class.forName()方式
        Class c = user.getClass();

        //2. 獲取Table的名字
        boolean b = c.isAnnotationPresent(MyTable.class);
        if (!b) {
            return "Not Exist Table!";
        }
        MyTable myTable = (MyTable) c.getAnnotation(MyTable.class);
        String tableName = myTable.value();

        //3. 獲取全部字段
        StringBuilder sbField = new StringBuilder();
        StringBuilder sbWhere = new StringBuilder();
        Field[] fields = c.getDeclaredFields();
        for (Field field : fields) {
            boolean b1 = field.isAnnotationPresent(MyColumn.class);
            if (!b1) {
                return "Not Exist Field!";
            }

            //4. 拼接字段
            MyColumn myColumn = field.getAnnotation(MyColumn.class);
            String columnName = myColumn.value();
            sbField.append(columnName).append(",");

            //4.1 獲取字段的值,先獲取get方法,再獲取值
            String getMethodName = "get" + field.getName().substring(0, 1).toUpperCase() + 
                                   field.getName().substring(1);
            Method getMethod = c.getMethod(getMethodName);
            Object getValue = getMethod.invoke(user);

            //5. 拼接where後面的條件
            //int基本類型判斷
            if (getValue == null || (getValue instanceof Integer) && (Integer) getValue == 0) {
                continue;
            }

            sbWhere.append(" and ").append(columnName);

            if (getValue instanceof String) {
                //in 查詢
                if (((String) getValue).contains(",")) {
                    String[] strings = ((String) getValue).split(",");
                    sbWhere.append(" in(");
                    for (String str : strings) {
                        sbWhere.append("'").append(str).append("',");
                    }
                    //刪除最後一個逗號
                    sbWhere.deleteCharAt(sbWhere.length() - 1);
                    sbWhere.append(")");
                } else {
                    //普通查詢
                    sbWhere.append("=").append("'").append(getValue).append("'");
                }
            } else if (getValue instanceof Integer) {
                sbWhere.append("=").append(getValue);
            }

        }

        //拼接完整sql輸出
        String sql = String.format(SQL_MODEL, sbField.deleteCharAt(sbField.length() - 1), 
                                   tableName, sbWhere);
        return sql;
    }
}

以上針對User作一個試驗,字段類型也比較少,能夠將入參改爲Object或者範型,條件也只加了=與in查詢,JDBC就不寫了,主要對註解的實踐.net

 

最後輸出: select id,user_name,nick_name,age,address,email from user_info where 1=1 and id=9527 and user_name='HaHaHa' and nick_name='華安' and address='下沙' and email in('hello@163.com','hi@qq.com','biu@sina.com')code

 

總結: 看到一個註解,如今就能夠認識註解,知道註解的做用域,應用的場景範圍,最後其功能所在,若是在開發中,能實際簡化程序,那就再好不過的了orm

-------------------------------------------------------------------對象

相關文章
相關標籤/搜索