单个领域hibernate动态参数查询
使用此动态查询方法,不用每次都为一个带参的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()); }