Hibernate使用原生的动态sql实现带条件的查询分页功能
2016-06-21 11:09
1031 查看
背景
最近在做项目的时候需要使用到分页功能,项目用的框架是JPA,老实说SpringDataJpa的带条件的分页查询功能真的难用。。。所以想到用hibernate的动态SQL来实现算了。实现步骤
1.在hibernate的配置文件中加实体类(移动要配置,如果没有配置,不会报错,但是就是查询不出来数据)2.编写dao和daoimpl类(关键)
3.编写2个dto类
4.调用
详细实现步骤
在hibernate的配置文件中加实体类
hibernate在使用中一般会和hibernate整合,整合之后要配置实体类有两种实现方案
1.通过在hibernate.cfg.xml中配置的方式applicationContext.xml
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocations"> <list> <value>classpath*:hibernate/**/hibernate.cfg.xml</value> </list> </property>
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <mapping class="com.nantian.man.busi.domain.TCardInfo"/> </session-factory> </hibernate-configuration>
2.直接在applicationContext.xml配置
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="annotatedClasses"> <list> <value>com.nantian.man.busi.domain.TCardInfo</value> </list> </property>
编写三个dto
PageModel(包装当前页数和每页显示条数的pojo)public class PageModel{ private int pageNo = 1;//当前页 private int pageSize = 3;//每页显示条数 //get set方法 }
HibernateQueryModel(包装查询条件,查询实体名字,排序等的POJO)
public class HibernateQueryModel { private String tableName;//实体名字 private Map<String,Object> map;//查询条件 private String orderColumn;//排序字段 private String orderType;//排序方式,比如:desc,asc private PageModel pageModel;//包装了当前页码和每页显示条数 //get set方法 }
ReturnPageModel(包装了返回数据的POJO)
public class ReturnPageModel<T> implements Serializable { private static final long serialVersionUID = 1L; private int count;//总数 private int end;//结束的行数 private long pages;//页数 private int pageSize;//每页显示行数 private List<T> list; //返回数据 private int start;//开始行数 private long currentPage;//当前页 //get set方法 }
编写dao和daoimpl类(关键)
daopublic interface HibernateQueryDao<T> { ReturnPageModel<T> getByConditionAndPage(HibernateQueryModel hqm); }
daoimpl
@Repository public class HibernateQueryDaoImpl<T> extends HibernateDaoSupport implements HibernateQueryDao<T> { @Resource public void setMySessionFactory(SessionFactory sessionFactory){ super.setSessionFactory(sessionFactory); } /** * 条件查询 * */ @SuppressWarnings("unchecked") @Override @Transactional(propagation=Propagation.REQUIRED) public ReturnPageModel<T> getByConditionAndPage(HibernateQueryModel hqm){ ReturnPageModel<T> page=new ReturnPageModel<T>(); String sql="from "+hqm.getTableName()+" t where 1=1 "; StringBuilder sb=new StringBuilder(); List<Object> paramList=new ArrayList<Object>(); Map<String,Object> querymap = hqm.getMap(); if(!querymap.isEmpty()){ for(String key : querymap.keySet()){ if(StringUtil.isNotEmpty(querymap.get(key))){ paramList.add(querymap.get(key)); sb.append("and t."+key+"=? "); } } } final Object[] objectArr=paramList.toArray(); final String hql=sql+sb.toString()+"order by t."+hqm.getOrderColumn()+" "+hqm.getOrderType(); final String sqlcount="select count(*) "+hql; logger.info("查询语句为: ["+hql+"]"); logger.info("获取数量的查询语句为:["+sqlcount+"]"); final int pageNo=hqm.getPageModel().getPageNo(); final int pageSize=hqm.getPageModel().getPageSize(); //得到总数据 List<T> list=this.getHibernateTemplate().executeFind(new HibernateCallback(){ public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query=session.createQuery(hql); query.setFirstResult((pageNo-1)*pageSize); query.setMaxResults(pageSize); for(int i=0;i<objectArr.length;i++){ query.setParameter(i, objectArr[i]); } return query.list(); }}); //得到总条数 List<Long> longlist=this.getHibernateTemplate().executeFind(new HibernateCallback(){ public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query=session.createQuery(sqlcount); for(int i=0;i<objectArr.length;i++){ query.setParameter(i, objectArr[i]); } return query.list(); }}); int count = longlist.get(0).intValue(); page.setList(list); page.setPageSize(pageSize); page.setStart(pageNo); page.setCount(count); int end = (pageNo - 1) * pageSize + pageSize; if (count < end) { page.setEnd(count); } else { page.setEnd((pageNo - 1) * pageSize + pageSize); } return page; } }
如何调用
public void test(){ //1、判断页码是否正确 int currentPage = Integer.parseInt(this.getDictionary().getDataMapValue(msgBean.getDataMap(),FieldConfigConstant.CURRENTPAGE)); int pageSize = Integer.parseInt(this.getDictionary().getDataMapValue(msgBean.getDataMap(),FieldConfigConstant.PAGESIZE)); if(currentPage<=0){ currentPage = 1; } if(pageSize<=0){ pageSize = 10; } HibernateQueryModel model = new HibernateQueryModel(); Map<String, Object> conditionMap = new HashMap<String,Object>(); PageModel pageModel=new PageModel(currentPage,pageSize); Field[] field = TCardInfoPKDto.class.getDeclaredFields(); for(Field fi:field){ String name = fi.getName(); String caseName = name.substring(0,1).toUpperCase()+name.substring(1); //将属性的首字符大写,方便构造 Method m = tc.getClass().getMethod("get"+caseName); Object value = m.invoke(tc); if(StringUtil.isNotEmpty(value)){ conditionMap.put("id."+name, value); } } model.setTableName(TCardInfo.class.getName()); model.setOrderColumn("id.value"); model.setOrderType("asc"); model.setMap(conditionMap); model.setPageModel(pageModel); ReturnPageModel<TCardInfo> page = hibernateQueryDaoImpl.getByConditionAndPage(model); }
相关文章推荐
- MySQL中TIMESTAMPDIFF和TIMESTAMPADD函数的用法
- convert(varchar(10),字段名,转换格式)
- 一个用户下的表的权限给另一个用户
- Oracle:Start with connect by prior 递归
- MySQL自增长列,设置主键和索引
- Oracle:Start with connect by prior 递归
- SQL Server 2008 R2 启动企业管理器,出现“无法读取此系统上以前注册的服务器的列表”
- Oracle用sql增删改字段,并添加索引
- 一个sql语句的改写
- POSTGRESQL大对象ID操作例子,文件上传到POSTGRESQL数据库
- sqlserver检测死锁;杀死锁和进程;查看锁信息
- 安装使用redis-cli
- mysql null和''区别
- Mybatis获取SqlSession时报空指针错误解决
- Mysql5.7.9原生JSON格式支持
- Oracle学习03【持续更新】
- MySQL命令行导入导出数据库
- java连接Oracle数据库练习题
- SQLite的使用——bruceyou1990
- Titan数据库官方文档翻译(一)