周邊有許多同事只會使用註解,並不瞭解註解的原理。於是隨手寫一個小Demo,普及下註解的使用原理,順便加深自己的理解。如有錯誤,歡迎大牛指正。 1 註解類基本樣式 2 註解類的元素解析 元註解: 總共有四個元註解,分別是:@Target,@Retention,@Documented,@Inherite ...
周邊有許多同事只會使用註解,並不瞭解註解的原理。於是隨手寫一個小Demo,普及下註解的使用原理,順便加深自己的理解。如有錯誤,歡迎大牛指正。
1 註解類基本樣式
/** * * @author qpf * 此註解用於對錶名的設置 * */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface Table { String value(); }
2 註解類的元素解析
元註解:
|
@Table("StudentInfo") public class StudentInfo extends BaseTable { //學生姓名 @Column("name") private String name; //性別 @Column("sex") private String sex; }註意:@Target設置了註解放在什麼地方,設置為ElemenetType.FIELD,則需要將註解放置在屬性的上方。設置為ElemenetType.TYPE,則需要放置在class上方。放錯位置,編譯器會報錯。 原理:把public @interface Table {String value();}和@Table("StudentInfo") 放在一起看,其實註解就是返回你所設置的指定類型的值。其實就是在調用註解的value()方法,會返回String類型的值,值為註解中設置的“StudentInfo”。後面例子中會有詳細介紹。還需註意一點,註解中返回的類型是有限定的,且方法一定要是無參的,不懂的可自行百度。
3 利用註解實現小Demo
3.1 需求內容
1、有一張學生信息表,欄位包括姓名,年級,班級,教師名,性別等;2、利用註解,對錶實例的每個欄位進行檢查,並列印出查詢sql
3.2 代碼結構
annotation:存放創建的註解。 bean:存放資料庫表所用到的javaBean test:main函數,用於測試並列印查詢sql;3.3 註解類
/** * * @author qpf * 此註解用於對錶欄位的設置 */ @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface Column { String value(); }
/** * * @author qpf * 此註解用於對錶名的設置 * */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface Table { String value(); }
3.4 學生信息表的javabean
下麵的代碼刪去了get和set方法。
/** * * @author qpf * Table標簽里為表名 * Column標簽里為資料庫欄位名 */ @Table("StudentInfo") public class StudentInfo extends BaseTable { //學生姓名 @Column("name") private String name; //性別 @Column("sex") private String sex; //年級 @Column("grade") private String grade; //班級 @Column("class_num") private String classNum; //班主任 @Column("teacher") private String teacher; //總分 @Column("total_scores") private String totalScores; //微信號 @Column("weChat_num") private String weChatNum; //手機號 @Column("tel_num") private String telNum; //父親名 @Column("father_name") private String fatherName; //母親名 @Column("mother_name") private String motherName; }
3.5 AnnotationTest方法
public class AnnotationTest { /** * 需求設計: * 1、有一張學生信息表,欄位包括姓名,年級,班級,教師名,性別等; * 2、利用註解,對每個欄位的組合條件進行檢查,並列印出sql */ public static void main(String[] args) { // TODO Auto-generated method stub StudentInfo studentInfo=new StudentInfo(); studentInfo.setName("Tom"); studentInfo.setSex("men"); studentInfo.setTelNum("18255005147,18255005148,18255005149"); studentInfo.setWeChatNum("qpf123456"); String sql=querySql(studentInfo); System.out.println((sql==null)?"":sql); } public static String querySql(BaseTable table) { //獲取類載入器 Class<?> cTable=table.getClass(); //判斷類中是否包含Table的註解 boolean tableIsExists=cTable.isAnnotationPresent(Table.class); //判斷是否為表實例 if(!tableIsExists) { return null; } //獲取表名 String tableName=cTable.getAnnotation(Table.class).value(); //初始化表查詢語句 StringBuilder builder=new StringBuilder("select * from"); builder.append(" "+tableName+" where 1=1"); //獲取表實例中的所有欄位 Field[] fields=cTable.getDeclaredFields(); try { for (Field field : fields) { //判斷是否為表數據欄位 boolean columnIsExist=field.isAnnotationPresent(Column.class); if(!columnIsExist) { continue; } //判斷表數據欄位的值是否為null field.setAccessible(true); String fieldValue=(String)field.get(table); if(null==fieldValue || "".equals(fieldValue)) { continue; } //檢測到需要拼接欄位時,再獲取資料庫欄位名 String columnName=field.getAnnotation(Column.class).value(); //需要用in的欄位處理 if(fieldValue.contains(",")) { builder.append(" and "+columnName+" in("); String[] strs=fieldValue.split(","); for (int i = 0; i < strs.length; i++) { builder.append("'"+strs[i]+"'"); if(i!=strs.length-1) { builder.append(","); } } builder.append(")"); } else { builder.append(" and "+columnName+"="+"'"+fieldValue+"'"); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return builder.toString(); } }
上面方法列印出的查詢sql語句為:
select * from StudentInfo where 1=1 and name='Tom' and sex='men' and weChat_num='qpf123456' and tel_num in('18255005147','18255005148','18255005149')