利用Java Reflection(反射)原理,在hibernate里面实现对单表、视图的动态组合查询

[本文转载自 http://www.kehui.net/index.php?op=article&file=read&aid=48142]

    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

说明

Idpk

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:未激活

利用工具,生成其相关的hibernateStaff,其内部包括以下字段:

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

    至此,应该说介绍的差不多了,或许有人要问,”单表查询,可以如此,那么联表查询怎么办?“其实很简单,在数据库里面建立一个视图就可以了。希望这点经验对大家有用。

你可能感兴趣的:(reflection)