利用Java Reflection(反射)原理,在hibernate裡面實現對單表、視圖的動態組合查詢
來源:互聯網
上載者:User
動態|視圖|組合查詢
Reflection 是 Java 程式開發語言的特徵之一,它允許運行中的程式對自身進行訪問,並能直接操作程式的內部屬性。
Hibernate是一個面向Java環境的對象/關聯式資料庫映射工具,基本上,每個表或者視圖在hibernate裡面都可以對應一個類,在此處,我們通過充分的利用這個類,來實現動態組合查詢。
首先我們一起來看看這個函數的原始碼:
/** * 組合查詢 * @param object 包含查詢條件的對象 * @param firstResult 第一個返回的位置(從0開始) * @param maxResults 最大返回數 * @param orderField 排序的欄位 * @param isAbs 是否正序排列 * @return * @throws HibernateException */ public List queryList(Object object, int firstResult, int maxResults,String orderField ,boolean isAsc) throws HibernateException,IllegalArgumentException,IllegalAccessException,InvocationTargetException { List list=null; Class c = object.getClass(); Method method[] = c.getMethods(); try { Session session = currentSession(); Criteria criteria = session.createCriteria(object.getClass()); for (int i = 0; i < method.length; i++) { String name = method[i].getName(); if(name.indexOf("getMin")==0){ //大於 String fieldName = name.substring(6, 7).toLowerCase() + name.substring(7); Object retObj = method[i].invoke(object, null); if (retObj != null && !retObj.equals("")) criteria.add(Expression.ge(fieldName, retObj)); continue; } if(name.indexOf("getMax")==0){//小於 String fieldName = name.substring(6, 7).toLowerCase() + name.substring(7); Object retObj = method[i].invoke(object, null); if (retObj != null && !retObj.equals("")) criteria.add(Expression.le(fieldName, retObj)); continue; } if (name.indexOf("get") != 0 || name.indexOf("getClass") == 0) //如果不是需要的方法,跳出 continue; String fieldName = name.substring(3, 4).toLowerCase() + name.substring(4); String returnType = method[i].getReturnType().toString(); Object retObj = method[i].invoke(object, null); if (retObj != null) { //如果為null,沒有賦值,跳出 if (returnType.indexOf("String") != -1){ if(retObj.equals("")) //如果為""的String欄位,跳出 continue; criteria.add(Expression.like(fieldName, "%" + retObj + "%")); //對String的欄位,使用like模糊查詢 }else criteria.add(Expression.like(fieldName, retObj)); } } if(isAsc) criteria.addOrder(Order.asc(orderField)); //升序 else criteria.addOrder(Order.desc(orderField)); //降序 criteria.setFirstResult(firstResult); criteria.setMaxResults(maxResults); list = criteria.list(); } finally { closeSession(); }
return list; }
假設關聯式資料庫裡面有一個物理表,其結構如下:
STAFF(員工表)
列名
類型
Null
說明
Id(pk)
VARCHAR2(20)
NOT NULL
員工工號
name
VARCHAR2(20)
NOT NULL
員工姓名
Dept
INTEGER
NULL
員工所屬部門(p3)
Password
VARCHAR2(20)
NOT NULL
密碼
Post
INTEGER
NULL
員工所屬職位(p14)
Priv
VARCHAR2(40)
NOT NULL
許可權字
Birthday
VARCHAR2(20)
NULL
生日
Active
VARCHAR2(1)
NOT NULL
Y:啟用 N:未啟用
利用工具,產生其相關的hibernate類Staff,其內部包括以下欄位:
private java.lang.String id; private java.lang.String name; private java.lang.Long dept; private java.lang.String password; private java.lang.Long post; private java.lang.String priv; private java.lang.String birthday; private java.lang.String active;
下面,我們就可以利用上面的queryList來進行查詢了
例子1:
前台需要一個包含所有人員的List,
那麼相關代碼如下:
Staff staff=new Staff();
List list=queryList(staff,0,1000,id,true);
例子2:
查詢所有姓名裡麵包含“丁”的人員
那麼相關代碼如下:
Staff staff=new Staff();
staff.setName=”丁”;
List list=queryList(staff,0,1000,id,true);
例子3:
查詢所有姓名包含“丁”,並且處於啟用狀態的人員
那麼相關代碼如下:
Staff staff=new Staff();
staff.setName=”丁”;
staff.setActive=”Y”;
List list=queryList(staff,0,1000,id,true);
例子4:
查詢所有姓名包含“丁”,並且處於啟用狀態的人員,同時要求返回的list按照生日進行排序
那麼相關代碼如下:
Staff staff=new Staff();
staff.setName=”丁”;
staff.setActive=”Y”;
List list=queryList(staff,0,1000,birthday,true,);
對Staff進行一下加工,就可以實現大於,小於的功能,比如我們想實現查詢生於1981-09-16以後的人,那麼可以在Staff類裡面增加如下代碼:
private java.lang.String minBirthday;
private java.lang.String maxBirthday;
public java.lang.String getMinBirthday () {
return minBirthday;
}
public void setMinBirthday (java.lang.String minBirthday) {
this.minBirthday = minBirthday;
}
public java.lang.String getMaxBirthday () {
return maxBirthday;
}
public void setMaxBirthday (java.lang.String maxBirthday) {
this.maxBirthday = maxBirthday;
}
例子5:
查詢生日在1978年之後,1981年之前的啟用狀態人員,要求姓名包含“丁”,按照生日降序排列
Staff staff=new Staff();
staff.setName=”丁”;
staff.setActive=”Y”;
staff. setMinBirthday(“1978”);
staff. setMaxBirthday(“1981”);
List list=queryList(staff,0,1000,birthday,false);
至此,應該說介紹的差不多了,或許有人要問,”單表查詢,可以如此,那麼聯表查詢怎麼辦?“其實很簡單,在資料庫裡面建立一個視圖就可以了。希望這點經驗對大家有用。