使用Java反射(Reflect)、自定義註解(Customer Annotation)生成簡單SQL語句


使用Java反射(Reflect)、自定義註解(Customer Annotation)生成簡單SQL語句

這次給大家介紹一下在Java開發過程中 使用自定義註解開發:
主要知識點:
            1.反射            主要用於提取註解信息
            2.自定義異常  主要是爲了自己自定義一個異常信息
            3.自定義註解  本次重點 學會如何自定義註解以及如何使用反射提取註解信息運用到實際開發
下圖表示在Java中註解的含義以及註解的分類和如何解析註解



通常我們使用自定義註解一般使用4中元註解即:
@Target
@Retention
@Documented
@Inherited
/**
 * 
 */
/**
 * ClassName:package-info.java
 * @author xg.qiu
 * @since JDK1.7
 * Aug 3, 2015
 * 使用自定義註解:
 * @Target :用於描述註解的使用範圍(即:被描述的註解可以用在什麼地方)
 * 取值(ElementType)有:
    1.ElementType.CONSTRUCTOR:用於描述構造器
    2.ElementType.FIELD:用於描述域
    3.ElementType.LOCAL_VARIABLE:用於描述局部變量
    4.ElementType.METHOD:用於描述方法
    5.ElementType.PACKAGE:用於描述包
    6.ElementType.PARAMETER:用於描述參數
    7.ElementType.TYPE:用於描述類、接口(包括註解類型) 或enum聲明
  @Retention :@Retention定義了該Annotation被保留的時間長短
  取值(RetentionPoicy)有:
    1.RetentionPolicy.SOURCE:在源文件中有效(即源文件保留)
    2.RetentionPolicy.CLASS:在class文件中有效(即class保留)
    3.RetentionPolicy.RUNTIME:在運行時有效(即運行時保留)
  @Documented:用於描述其它類型的annotation應該被作爲被標註的程序成員的公共API,
   因此可以被例如javadoc此類的工具文檔化。
   Documented是一個標識註解,沒有成員。
  @Inherited :元註解是一個標記註解,@Inherited闡述了某個被標註的類型是被繼承的
   [必須是extend class 而不是implements interface]
 */
package com.demo.ann;

註解語法:
public @interface 註解名{
   
        // 註解變量
       // 元數據類型:基本數據類型 String class enum Annotation 以及上述類型數組
       // 如果元數據只有一個時 必須聲明爲value();
}

/**
 * 
 */
package com.demo.ann.anns;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * ClassName:Table.java
 * @author xg.qiu
 * @since JDK1.7
 * Aug 3, 2015
 * 自定義註解:表
 * 用法:
 *  @Table("user")
 *  public class User
 */

@Target( ElementType.TYPE)// 作用域 類或接口
@Retention( RetentionPolicy.RUNTIME)// 有效期爲運行時
public @interface Table {
String value();
}



/**
 * 
 */
package com.demo.ann;

import com.demo.ann.anns.Column;
import com.demo.ann.anns.Table;

/**
 * ClassName:User.java
 * 
 * @author xg.qiu
 * @since JDK1.7 Aug 3, 2015
 */
@Table("TABLE_USER")
public class User {
@Column("USER_ID")
private int userId;
@Column("USER_NAME")
private String userName;
@Column("PASS_WORD")
private String passWord;
@Column("AGE")
private int age;

public int getUserId() {
return userId;
}

public void setUserId(int userId) {
this.userId = userId;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getPassWord() {
return passWord;
}

public void setPassWord(String passWord) {
this.passWord = passWord;
}

public int getAge() {
return age;
}

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

 
/**
 * 
 */
package com.demo.ann.anns;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * ClassName:Column.java
 * @author xg.qiu
 * @since JDK1.7
 * Aug 3, 2015
 * 自定義註解:列
 * 用法:
 *  @Column("userId")
 *  private int userId;
 */
@Target( ElementType.FIELD)//作用於屬性
@Retention( RetentionPolicy.RUNTIME)//有效期爲運行時
public @interface Column {
String value();
}
 




/**
 
 * 
 */
package com.demo.ann;

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

import com.demo.ann.anns.Column;
import com.demo.ann.anns.Table;
import com.demo.ann.exception.AnnException;

/**
    解析註解並返回執行的sql語句 
 * ClassName:Test.java
 * @author xg.qiu
 * @since JDK1.7
 * Aug 3, 2015
 * 測試:使用自定義註解完成數據庫的查詢返回sql語句
 *  1.根據id查詢
 *  2.根據用戶名查詢
 *  3.根據用戶名、密碼組合查詢
 */
public class Test {
public static void main(String[] args) {
User user1 = new User();
user1.setUserId(1);//根據Id查詢
User user2 = new User();
user2.setUserName("xiaoqiu");// 根據用戶名查詢
User user3 = new User();
user3.setUserName("xiaoqiu");
user3.setPassWord("123456");// 根據用戶名、密碼組合查詢
User user4 = new User();
user4.setUserName("xiaoqiu,zasang,lisi");
String sql1 = executeQuery(user1);
String sql2 = executeQuery(user2);
String sql3 = executeQuery(user3);
String sql4 = executeQuery(user4);
System.out.println(sql1);
System.out.println(sql2);
System.out.println(sql3);
System.out.println(sql4);
}
         /**
          * @param user 用戶對象
          *@return String 返回的是拼裝好的sql語句
          */
private static String executeQuery(User user) {
StringBuffer sb = new StringBuffer("select * from ");
//1、獲取類
Class<? extends User> c = user.getClass();
//2、查找類是否被註解
boolean isExist = c.isAnnotationPresent(Table.class);
if(!isExist){
try {
                                // 自定義異常
throw new AnnException("the "+ c.getClass().getName() +" class is not used annotation");
} catch (AnnException e) {
e.printStackTrace();
}
}
                // 獲取Table註解 
Table table = (Table) c.getAnnotation(Table.class);
sb.append( table.value() +" where 1= 1");
//3、查找屬性是否被註解
Field[] fields = c.getDeclaredFields();
for(Field f : fields){
//3.1、處理每個字段對應的sql
//3.2、拿到字段值
boolean isFExist = f.isAnnotationPresent(Column.class);
if(!isFExist){
try {
throw new AnnException("the " + f.getName()  +" field is not used annotation");
} catch (AnnException e) {
e.printStackTrace();
}
}
                        // 獲取列註解 
Column column = f.getAnnotation(Column.class);
String columnName = column.value();
//3.2、獲取字段
String fieldName = f.getName();
//3.4、.拿到字段值
Object values = null;
String getFieldMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
try {
Method getMethod = c.getDeclaredMethod(getFieldMethodName);
values = getMethod.invoke(user);
//3.5.拼裝sql
if( values == null || ( values instanceof Integer && (Integer) values == 0) ){
continue;
}
sb.append(" and ").append(columnName);
if(values instanceof Integer){
sb.append("=").append(values);
}else if(values instanceof String){
if( ((String) values).contains(",")){
String [] valuesIn = ((String) values).split(",");
sb.append(" in('");
for(String s : valuesIn){
sb.append(s).append("'").append(",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append(")");
}else{
sb.append("='").append(values).append("'");
}
}
} catch (Exception e) {
                                 // 打印堆棧信息 
e.printStackTrace();
}
}
                // 返回拼裝好的sql語句 
return sb.toString();
}
}


運行效果:
 
select * from TABLE_USER where 1= 1 and USER_ID=1
select * from TABLE_USER where 1= 1 and USER_NAME='xiaoqiu'
select * from TABLE_USER where 1= 1 and USER_NAME='xiaoqiu' and PASS_WORD='123456'
select * from TABLE_USER where 1= 1 and USER_NAME in('xiaoqiu',zasang',lisi')

發佈了32 篇原創文章 · 獲贊 10 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章