1. 程式人生 > >使用Java註解將實體類轉化為sql字串

使用Java註解將實體類轉化為sql字串

首先是定義一個實體類,如下

/*
 * 定義使用者,通過註解對映到資料庫
 */
@Table("user")
public class User {

	@Column("id")
	private int id;
	@Column("username")
	private String username;
	@Column("nickname")
	private String nickName;
	@Column("age")
	private int age;
	@Column("email")
	private String email;
	@Column("mobile")
	private String mobile;
	public User(){
		//
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getNickname() {
		return nickName;
	}
	public void setNickName(String nickName) {
		this.nickName = nickName;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getMobile() {
		return mobile;
	}
	public void setMobile(String mobile) {
		this.mobile = mobile;
	}
}


上面有類註解和方法註解,分別new一個Annotation,

其中註解裡面只有一個值,因此直接用value()宣告即可

Table.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*ElementType引數有
 * CONSTRUCTOR:構造器的宣告
 * FIELD:域,屬性的宣告
 * LICAL_VARIABLE:區域性變數的宣告
 * PACKAGE:包宣告
 * PARAMETER:引數宣告
 * TYPE:類,介面(包括註解型別)或enum宣告
 * */
@Target({ElementType.TYPE})
/*
 * 需要儲存的級別
 * SOURCE:註解將被編譯器丟掉
 * CLASS:註解在class檔案中可以使用,會被VM丟掉
 * RUNTIME:VM將在執行時也保留註解,因此可以通過反射機制讀取註釋的資訊
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value();
}

Column.java
//定義一個描述使用者表屬性欄位的註解

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

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {

	String value();
}

然後是轉換函式
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;



//將傳入的使用者資訊轉換為sql語句
public class ToSql {

	public static String query(Object u){
		StringBuilder sqlstr=new StringBuilder();
		//獲取到class
		Class c=u.getClass();
		//  檢視是否包含Table型別的註解
		if(!c.isAnnotationPresent(Table.class)){
			return null;
		}
		//如果包含,獲取到Table類,並通過此獲取到Table類註解
		Table table=(Table)c.getAnnotation(Table.class);
		String tableName=table.value();
		//先將sql語句的前半部分寫入
		sqlstr.append("SELECT * FROM ").append(tableName).append(" WHERE 1=1");
		//獲取所有自己宣告的屬性
		Field[] fields=c.getDeclaredFields();
		//遍歷屬性
		for (Field field : fields) {
			//通過註解中的值來獲取屬性名(註解中的值應該與屬性名相等)
			String columnValue=field.getAnnotation(Column.class).value();
			//獲取屬性的get方法的方法名,方法名的寫法一般為get+屬性名(屬性名的第一個字母大寫)
			String getMethodName="get"+columnValue.substring(0, 1).toUpperCase()+columnValue.substring(1);
			//使用反射通過方法名獲取方法,並呼叫invoke方法執行該方法,得到返回值
			Object fieldValue=null;
			try {
				Method getMethod=c.getMethod(getMethodName);
				fieldValue=getMethod.invoke(u);
			} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				// TODO Auto-generated catch block
				System.out.println("MethodName="+getMethodName);
				e.printStackTrace();
			}
			//因為是遍歷所有的方法,所以有些方法是沒有賦值的,也就是不需要查詢,將其剔除
			if(fieldValue==null||((fieldValue instanceof Integer) &&((Integer)fieldValue==0))){
				continue;
			}
			sqlstr.append(" AND ").append(columnValue);
			//判斷字串,多箇中滿足任何一個用IN,並使用''
			if(fieldValue instanceof String){
				//感覺介面太神奇了
				if(((String)fieldValue).contains(",")){
					String[] values=((String)fieldValue).split(",");
					sqlstr.append(" IN(");
					for (String string : values) {
						sqlstr.append("'").append(string).append("'").append(",");
					}
					//刪除最後一個","
					sqlstr.deleteCharAt(sqlstr.length()-1);
					sqlstr.append(")");
				}else{
					//字串表示法
					sqlstr.append("=").append("'").append(fieldValue).append("'");
				}
			}else if (fieldValue instanceof Integer) {
				sqlstr.append("=").append(fieldValue);
			} 
		}
		return sqlstr.toString();
	}
}

Test.java測試類
public class Test {

	public static void main(String[] args) {
		User user=new User();
		user.setEmail("[email protected],[email protected]");
		System.out.println(ToSql.query(user));
	}
}