单个领域hibernate动态参数查询

本文介绍了一种使用Hibernate进行动态参数查询的方法,通过反射获取对象属性并构建查询语句,简化了带参数查询的编写过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用此动态查询方法,不用每次都为一个带参的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());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值