利用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);

    至此,應該說介紹的差不多了,或許有人要問,”單表查詢,可以如此,那麼聯表查詢怎麼辦?“其實很簡單,在資料庫裡面建立一個視圖就可以了。希望這點經驗對大家有用。


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.