利用Java Reflection(反射)原理,在hibernate里面实现对单表、视图的动态组合查询
类别: JAVA教程
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);
至此,应该说介绍的差不多了,或许有人要问,”单表查询,可以如此,那么联表查询怎么办?“其实很简单,在数据库里面建立一个视图就可以了。希望这点经验对大家有用。
- 上一篇: BEA调整战略再次突围
- 下一篇: 仔细触摸Java编程中的“文档”和“包”
-= 资 源 教 程 =-
文 章 搜 索