Java通過反射建立JDBC操作資料庫的通用方法
阿新 • • 發佈:2018-11-26
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;
}
這樣既可以做到通用查詢!