Web开发中,经常会使用到翻页插件,翻页插件一般含有符合多条件的总记录数,之前通过用criteria.list().size()求解时,是相当笨的方法,当数据到20W的时候,仅仅调用一个查询列表就反应65S,而且对内存消耗也是很惊人的。
没办法只好换思路。
思路一:请过JDBC来求解:好处执行速度快,但是要自己维护连接池,还要拼SQL,尤其是多条件查询的时候,很容易出错。
思路二:通过Query来求解,速度会比JDBC慢些,好处是Hibernate可以帮你维护数据库的连接,弊端是要拼接SQL,容易出错。
思路三:还是Criteria来求解,好处有:绕开SQL,通过Java API来操作数据库;之前求多条件查询就通过Criteria来实现,只需要维护一处。弊端可能会慢,但是在几十万条规模情境下慢不了多少。
思路三代码:
/**
* 符合【多条件查询】的组合记录数
* @param entity
* @return
*/
public int getRecords(T entity){
Criteria criteria = createCriteria(entity);//约束条件
criteria.setProjection(Projections.rowCount());
return ((Long)criteria.uniqueResult()).intValue();
}
/**
* 多条件查询时
* 返回含有部分结果集的Page对象
* @param page
* @param entity
* @return
*/
public Page<T> listPage(Page page, T entity){
page.setTotalCount(getRecords(entity));//符合条件的总记录数
Criteria criteria = createCriteria(entity);//约束条件
//起始位置
criteria.setFirstResult((page.getPageNo()-1)*page.getPageSize());
criteria.setMaxResults(page.getPageSize());//结果集大小
page.setResult(criteria.list());
return page;
}
通过JUnit4i单元测试
@Test
public void testGetRecords() throws Exception {
// entity.setContent("d7");
StopWatch watch = new StopWatch();
page.setPageNo(2);
watch.start();
int result = dao.getRecords(entity);
watch.stop();
System.out.println("符合要求的记录数: " + result);
System.out.println("查询时间: " + watch.getTotalTimeSeconds() + " 秒");
}
运行结果:
下面继续:添加条件
Junit测试方法testGetRecords()的entity.setContent("d7")取消注释;
运行结果
直接通过SQL执行:
select count(*) from news t where content like '%d7%';
执行结果
数据规模为28W+,执行时间差为0.145S