1. 程式人生 > >Java通過反射建立JDBC操作資料庫的通用方法

Java通過反射建立JDBC操作資料庫的通用方法

JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意方法和屬性;這種動態獲取資訊以及動態呼叫物件方法的功能稱為java語言的反射機制。

首先我們看個反射的小例子。

1.我們新建一個User的類。

2.通過反射獲取User物件的屬性和方法。

package com.lb.op;

public class User {
	private int id;
	private String name;

	public User() {
		super();
	}

	public User(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + "]";
	}

	


}

(注意:該例項中要有系統預設的無參構造方法,否則後面通過反射例項物件時會報錯)

 

/**
	 * 通過反射獲取物件的屬性和方法
	 * @param object
	 */
	public static void ReflectDemo(Object object){
		System.out.println("物件名:");
		System.out.println(object.getClass().getSimpleName());

		//獲取包括公共的、受保護的、預設的(包)訪問和私有屬性,但是不包括繼承的屬性。
		Field[] fd = object.getClass().getDeclaredFields();

		System.out.println("所有屬性:");
		for(Field field:fd) {
			//將屬性設定為可見的,主要是獲取包括private在內的所有屬性
			field.setAccessible(true);

			//屬性修飾
			String fieldModifier = Modifier.toString(field.getModifiers());

			//屬性型別
			String fieldType = field.getType().getSimpleName();

			//屬性名
			String fieldName = field.getName();

			System.out.println(fieldModifier+" "+fieldType+" "+fieldName);
		}

		//獲取包括公共的、受保護的、預設的(包)訪問和私有方法,但是不包括繼承的方法。
		Method[] md = object.getClass().getDeclaredMethods();

		System.out.println("所有方法:");
		for(Method method:md) {
			//將方法設定為可見的,主要是獲取包括private在內的所有方法
			method.setAccessible(true);

			//方法修飾
			String methodModifier = Modifier.toString(method.getModifiers());

			//方法型別
			String methodType = method.getReturnType().getSimpleName();

			//方法名
			String methodName = method.getName();

			System.out.println(methodModifier+" "+methodType+" "+methodName);
		}
	}

執行的結果如下:

物件名:
User
所有屬性:
private int id
private String name
所有方法:
public String toString
public String getName
public int getId
public void setName
public void setId

 

通過這個例子我們可以將反射比作一面鏡子,它能照射出物件的所有內容。

 

那我們可以運用反射做些什麼事情呢?就拿用最原始的例子來說,當我們用jdbc操作資料庫時,你會發現我會要寫好多好多增刪改查的函式,有幾個物件我們可能就要寫幾個,當物件一多時我們就能發現裡面的共同點。

當我們查詢所有資訊時,你會發現查詢不同的物件的資訊時不同的就是那句sql語句和儲存結果集的泛型,因此我們可以通過面向抽象程式設計實現這類查詢的公共方法。

 

第一步:我們拼出sql語句

/**
	 * 建立查詢所有資訊的sql語句    即:select * from tablename;
	 * @param object
	 * @return
	 */
	public static String CreateSelectAllSql(Object object) {
		StringBuffer sb = new StringBuffer();
		sb.append("select * from ");
		//類名一般是大寫字母開頭,資料庫表權威小寫
		sb.append(object.getClass().getSimpleName().toLowerCase()+";");

		System.out.println("生成的sql:"+sb);
		return sb.toString();
	}

 

第二步:查詢資料,獲取類的屬性,最後儲存結果集。

/**
	 * 通用查詢方法
	 * @param servlet
	 * @param object
	 * @return
	 */
	public static ArrayList<Object> SelectAll(HttpServlet servlet,Object object){
		ArrayList<Object> list = new ArrayList<Object>();
        
        //這裡是通過web.xml裡的引數獲得連線物件,你可以改成其他方式
		Connection con = DateBaseTools.con_db(servlet); 

		ResultSet rs = null; 
		Statement st; 

		//生成的sql語句
		String sql = CreateSelectAllSql(object);

		System.out.println("傳入的sql:"+sql);

		try { 
			st=(Statement) con.createStatement(); 
			rs=st.executeQuery(sql);
			while(rs.next()){ 
				System.out.println("one record");

				//例項化一個物件
				Object record = object.getClass().newInstance();

				//獲取物件的所有屬性
				Field[] fields = object.getClass().getDeclaredFields();

				//判斷屬性的型別
				for(Field field : fields){
					//將所有屬性設定成可見的
					field.setAccessible(true);

					//通過屬性的型別呼叫不同的獲取方法
					switch(field.getType().getSimpleName()){
					case "String":
						field.set(record, rs.getString(field.getName()));
						break;
					case "int":
						field.set(record, rs.getInt(field.getName()));
						break;
					}
				}

				list.add(record);
			}
		}catch(Exception e) {
			e.printStackTrace();
		}
		System.out.println(list.size());

		return list;
	}

 

這樣既可以做到通用查詢!