粗略的作一個簡單實踐,作一個ORM小方案,經過註解來實現java
對數據執行檢索,就要考慮怎麼和數據庫進行映射,數據對應有表名,字段名,人爲定義的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
-------------------------------------------------------------------對象