自定義註解例項實現SQL語句生成
阿新 • • 發佈:2018-12-09
GitHub
註解的老話題
首先我們要介紹一下註解是什麼,有什麼用?
java JDK中的幾個註解就可以幫助到我們去理解
@Override:重寫註解
@Deprecated: 使其無效
@SuppressWarnings: 忽略警告
通過以上幾種我們可以大致瞭解了註解的作用,方便開發,提高逼格,如果你能自定義註解來實現功能那就是又強又牛皮呀!
相關介紹
註解是Annotation,是由元註解定義出來的,元註解有以下幾種
- @Documented —— 指明擁有這個註解的元素可以被javadoc此類的工具文件化。這種型別應該用於註解那些影響客戶使用帶註釋的元素宣告的型別。如果一種宣告使用Documented進行註解,這種型別的註解被作為被標註的程式成員的公共API。
- @Target——指明該型別的註解可以註解的程式元素的範圍。該元註解的取值可以為TYPE,METHOD,CONSTRUCTOR,FIELD等。如果Target元註解沒有出現,那麼定義的註解可以應用於程式的任何元素。
- @Inherited——指明該註解型別被自動繼承。如果使用者在當前類中查詢這個元註解型別並且當前類的宣告中不包含這個元註解型別,那麼也將自動查詢當前類的父類是否存在Inherited元註解,這個動作將被重複執行知道這個標註型別被找到,或者是查詢到頂層的父類。
- @Retention——指明瞭該Annotation被保留的時間長短。RetentionPolicy取值為SOURCE,CLASS,RUNTIME。
程式碼演練
需求:
1、方便的對每個欄位或欄位組合條件進行檢索,並打印出sql
分別定義兩個註解類
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value();
}
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String value();
}
這時直接使用即可
@Data @NoArgsConstructor @AllArgsConstructor @Table("filter") class Filter { @Column("id") private int id; @Column("user_name") private String username; @Column("pass_word") private String password; @Column("age") private int age; @Column("city") private String city; @Column("email") private String email; @Column("mobile") private String mobile; }
主要在註解的反射處理,你需要按照自己的要求去處理業務
public static void main(String[] args) {
Filter f1 = new Filter();
f1.setId(10);
Filter f2 = new Filter();
f2.setUsername("小龍");
Filter f3 = new Filter();
f3.setEmail("[email protected],[email protected]");
String q1 = query(f1);
String q2 = query(f2);
String q3 = query(f3);
System.out.println(q1);
System.out.println(q2);
System.out.println(q3);
}
private static String query(Object filter){
StringBuilder sb = new StringBuilder();
//1、獲取到class
Class c = filter.getClass();
//2、獲取table的名字
boolean isexist = c.isAnnotationPresent(Table.class);
if (!isexist){
return null;
}
Table table = (Table) c.getAnnotation(Table.class);
String tableName = table.value();
sb.append("select * from ").append(tableName).append(" where 1=1");
//3、便利所有欄位
Field[] fields = c.getDeclaredFields();
for (Field field:fields){
//4、處理每個欄位對應的sql
//4.1、拿到欄位名
boolean fExist = field.isAnnotationPresent(Column.class);
if (!fExist){
continue;
}
Column column = field.getAnnotation(Column.class);
String columnName = column.value();
//4.2、拿到欄位值
String fieldName = field.getName();
String getMethodName = "get"+fieldName.substring(0,1).toUpperCase()+
fieldName.substring(1);
Object fieldValue = null;
try {
Method getMehtod = c.getMethod(getMethodName);
fieldValue = getMehtod.invoke(filter);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//4.3、拼裝sql
if (fieldValue==null || (fieldValue instanceof Integer && (Integer)fieldValue==0)){
continue;
}
sb.append(" and ").append(fieldName);
if (fieldValue instanceof String){
if (((String)fieldValue).contains(",")){
String[] values = ((String)fieldValue).split(",");
sb.append(" in( ");
for (String value:values){
sb.append("'").append(value).append("'").append(",");
}
sb.deleteCharAt(sb.length()-1);
sb.append(")");
}else{
sb.append(" = ").append("'").append(fieldValue).append("'");
}
}else if (fieldValue instanceof Integer){
sb.append(" = ").append(fieldValue);
}
}
return sb.toString();
}
效果
select * from filter where 1=1 and id = 10
select * from filter where 1=1 and username = '小龍'
select * from filter where 1=1 and email in( '[email protected]','[email protected]')
如果本文對你有所幫助,歡迎關注本人技術公眾號,或者點贊,謝謝。