使用此动态查询方法,不用每次都为一个带参的hibernate查询写一个查询,只需要用map传递参数即可,传递的参数map.key名必须与领域模型的属性名一致,如果不一致,则不会应用查询参数;多表连接查询等复杂推荐使用ibatis,但是使用hibernate最好设置为对象间关联,就可以在hibernate内事务内解决问题,不然事物配置很麻烦;
第一个为获取类的属性名的静态工具方法
第二个为动态查询方法,可写在抽象基类
余下为调用的示例方法
此代码写的粗糙,有不足及纰漏,望大家及时更贴斧正
package ly.tool.utils.ref;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import org.apache.log4j.Logger;
import com.jhzp.domain.Userinfo;
import com.jhzp.domain.base.BaseDomain;
public class ReflectUtils {
private static Logger log=Logger.getLogger(ReflectUtils.class);
public static void main(String[] args) throws IntrospectionException{
System.out.println(listPropNames( Userinfo.class));;
}
/**
* 获取领域属性名列表
*/
public static List<String> listPropNames(Class clazz) {
List<String> pnamel=new ArrayList<String>();
BeanInfo bi;
try {
bi = Introspector.getBeanInfo(clazz);
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
for (int i = 0; i < pds.length; i++) {
String propName = pds[i].getName();
pnamel.add(propName);
}
return pnamel;
} catch (IntrospectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
/**
* hibernate 动态参数查询 ,查询参数形式只能是: name=:name,
* 其他形式的查询使用自定义hql的查询queryByParamAndHql
*/
protected List queryByParam(org.hibernate.Session session,Class dclazz,Map<String,Object> params){
List<String> fnamel=ReflectUtils.listPropNames(dclazz);
Set<String> pnames=params.keySet();
List<String> pnamel=new ArrayList<String>();
Iterator<String> iter=pnames.iterator();
while(iter.hasNext()){
String pname=iter.next();
if(null!=params.get(pname) && fnamel.contains(pname)){
pnamel.add(pname);
}
}
String hql="from "+dclazz.getSimpleName();
if(pnamel.size()>0){
hql=hql+" where ";
}
StringBuilder sdb=new StringBuilder();
sdb.append(hql);
int count=0;
for(String pname:pnamel){
if(!fnamel.contains(pname)){
log.info(" pname: "+pname+"参数跟属性名不同,返回了,fnamel列表: "+fnamel);
return null;
}
if(count>0){
sdb.append(" and "+ pname+" = :"+pname);
}else
sdb.append(pname+" = :"+pname);
count++;
}
hql=sdb.toString();
log.info("打印生成的hql: "+hql);
Query query=session.createQuery(hql);
for(String pname:pnamel){
Object obj=params.get(pname);
if(obj instanceof String){
query.setParameter(pname, obj);
}else if(obj instanceof BigDecimal){
query.setBigDecimal(pname, ((BigDecimal)obj));
}else if(obj instanceof BigInteger){
query.setBigInteger(pname, ((BigInteger)obj));
}else if(obj instanceof Boolean){
query.setBoolean (pname, ((Boolean)obj));
}else if(obj instanceof Byte){
query.setByte(pname, ((Byte)obj));
}else if(obj instanceof Calendar){
query.setCalendar(pname, ((Calendar)obj));
}else if(obj instanceof Date){
log.info("应用到了"+Date.class);
query.setDate(pname, ((Date)obj));
}else if(obj instanceof Double){
query.setDouble(pname, ((Double)obj));
}else if(obj instanceof Integer){
query.setDouble(pname, ((Integer)obj));
}else if(obj instanceof Locale){
query.setLocale(pname, ((Locale)obj));
}else if(obj instanceof Long){
query.setLong(pname, ((Long)obj));
}else{
query.setParameter(pname, obj);
}
}
/**
* 自定义hql,传递动态的参数
*/
protected List queryByParamAndHql(Session session,String hql,Map<String,Object> params){
Query query=session.createQuery(hql);
for(String pname:params.keySet()){
if(hql.contains(pname)){
Object obj=params.get(pname);
if(obj instanceof String){
query.setParameter(pname, obj);
}else if(obj instanceof BigDecimal){
query.setBigDecimal(pname, ((BigDecimal)obj));
}else if(obj instanceof BigInteger){
query.setBigInteger(pname, ((BigInteger)obj));
}else if(obj instanceof Boolean){
query.setBoolean (pname, ((Boolean)obj));
}else if(obj instanceof Byte){
query.setByte(pname, ((Byte)obj));
}else if(obj instanceof Calendar){
query.setCalendar(pname, ((Calendar)obj));
}else if(obj instanceof Date){
log.info("应用到了"+Date.class);
query.setDate(pname, ((Date)obj));
}else if(obj instanceof Double){
query.setDouble(pname, ((Double)obj));
}else if(obj instanceof Integer){
query.setDouble(pname, ((Integer)obj));
}else if(obj instanceof Locale){
query.setLocale(pname, ((Locale)obj));
}else if(obj instanceof Long){
query.setLong(pname, ((Long)obj));
}else{
query.setParameter(pname, obj);
}
}
}
try {
return query.list();
} catch (Exception e) {
e.printStackTrace();
log.error("第二查询出错了。");
return null;
}
}
/**
* 被service调用代码片段:
* /
@Transactional(readOnly=true)
public List<Statistics> listStatistics(Map<String,Object> params) throws SQLException{
return super.queryByParam(super.getHibernateSession(), Statistics.class, params);
}
@Transactional(readOnly=true)
public List<Statistics> listStatistics2(Date date) throws SQLException{
String hql="from Statistics where atday =:atday";
Query query=super.getHibernateSession().createQuery(hql);
query.setDate("atday", date);
return query.list();
}
/**
* 被control调用代码片段
*/
@RequestMapping(value="/tss/stc/listsaleno.html", method=RequestMethod.GET)
public String listsaleno(HttpServletRequest hreq,ModelMap mm) throws SQLException{
Map<String,Object> params=new HashMap<String,Object>();
params.put("stype", "no");
params.put("atday", new Date());
List<Statistics> stcl= this.sts.listStatistics(params);
mm.addAttribute("stcl", stcl);
mm.addAttribute("stype", "no");
return "tss/stc/stcs";
}
/**
* client 调用
*/
public static void main(String[] args) throws Exception {
Calendar calendar = Calendar.getInstance();
StatisticsTask task = (StatisticsTask) act.getBean("statisticsTask");
StatisticsService sts=(StatisticsService) act.getBean("statisticsService");
Map<String,Object> params=new HashMap<String,Object>();
params.put("stype", "uc");
params.put("atday", calendar.getTime());
String hql="from Statistics where atday <:atday and stype=:stype";
List<Statistics> stcl=sts.hlistStatisticsByHql(hql, params);
log.info("统计的长度:"+stcl.size());
}