1,对于分页来说,效率是关键,本例是在分页的时候,缓存5页记录,默认每页20条,缓存大小100,这可以修改的;
2,基本思路是:第一次查的时候,先判断缓存中存不存在当前页的数据,如果存在,查找缓存中的数据,如果不存在,则去数据库中查询5页数据放入缓存中,然后再缓存中读取数据。如果是当前页是前3页,那么读取1-5页的数据,如果当前页是后3页,读取后5页的数据,如果是中间页,读取当前页前两页+当前页+当前页后两页的数据;
一,分页的参数封装类、返回结果封装类;
- package com.dg11185.iyw.common;
- /**
- * 分页的参数类
- *
- * @author
- * @since 1.0
- * @Copyright 2013
- */
- public class PagingParams {
- private Integer nextPage;// 需要显示内容的页码
- private Integer pageSize; // 每页的条数
- private String allSizeHql; // 查询总记录条数的hql
- private String queryHql; // 查询记录的hql
- private Class clazz; //查询对象的class类
- //设置下一页的页码
- public Integer getNextPage() {
- if (nextPage == null || "".equals(nextPage)) {
- return 1;
- }else {
- return nextPage;
- }
- }
- public Class getClazz() {
- return clazz;
- }
- public void setClazz(Class clazz) {
- this.clazz = clazz;
- }
- public void setNextPage(Integer nextPage) {
- this.nextPage = nextPage;
- }
- public Integer getPageSize() {
- if (pageSize == null || "".equals(pageSize)) {
- int configSize = Integer.parseInt(SysConfig.getProperty("pageSize"));
- return configSize;
- }else {
- return pageSize;
- }
- }
- //设置每页条数
- public void setPageSize(Integer pageSize) {
- this.pageSize = pageSize;
- }
- public String getAllSizeHql() {
- return allSizeHql;
- }
- public void setAllSizeHql(String allSizeHql) {
- this.allSizeHql = allSizeHql;
- }
- public String getQueryHql() {
- return queryHql;
- }
- public void setQueryHql(String queryHql) {
- this.queryHql = queryHql;
- }
- }
- package com.dg11185.iyw.common;
- import java.util.List;
- /**
- * 分页结果类
- *
- * @author 黄文韬
- * @since 1.0
- * @Copyright 2013 东莞市邮政局All rights reserved.
- */
- public class PagingResults {
- private int currentPage; //当前页码
- private int totalSize; //总共条数
- private int totalPages; //总共页数
- private List list; //结果集
- public int getCurrentPage() {
- return currentPage;
- }
- public void setCurrentPage(int currentPage) {
- this.currentPage = currentPage;
- }
- public int getTotalSize() {
- return totalSize;
- }
- public void setTotalSize(int totalSize) {
- this.totalSize = totalSize;
- }
- public int getTotalPages() {
- return totalPages;
- }
- public void setTotalPages(int totalPages) {
- this.totalPages = totalPages;
- }
- public List getList() {
- return list;
- }
- public void setList(List list) {
- this.list = list;
- }
- }
二,分页缓存类
- package com.dg11185.iyw.common;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
- import javax.annotation.Resource;
- import org.apache.log4j.Logger;
- import com.dg11185.iyw.baseDAO.BaseDAOImpl;
- /**
- * 分页缓存类
- * @author hwt
- *
- */
- public class CachePage {
- private static final Logger LOGGER = Logger.getLogger(CachePage.class);
- @Resource
- private BaseDAOImpl baseDAOImpl;
- private int pageStart = 1; // 页码
- private int pageSize = 20; // 每页显示的大小
- private int pageNum = 0; //总页数
- private int totalNum = 0; //总记录条数
- //private int cacheSize = 100; // 缓存大小
- private List cacheList = new ArrayList(); // 缓存列表
- /**
- * 构造方法
- * @param pageSize 每页大小
- * @param cacheSize 缓存大小
- */
- public CachePage(Integer pageSize) {
- this.pageSize = pageSize;
- }
- /**
- * 判断是否存在缓存中
- *
- * @param page
- * 页码
- * @return
- */
- public boolean inCache(int page) {
- // 当前缓存对象的个数
- int cacheNum = cacheList.size();
- if (cacheNum > 0) {
- if (page <= 0) {
- page = 1;
- }
- // 判断当前页是不是在缓存中
- if (page >= pageStart && (page - pageStart) * pageSize <= cacheNum) {
- return true;
- } else {
- return false;
- }
- }else {
- return false;
- }
- }
- /**
- * 清空缓存
- * @param pageNum 起始页
- */
- public void refleshCache() {
- // this.isFirst = true;
- for (int i = cacheList.size() -1 ; i >= 0; i--) {
- cacheList.remove(i);
- }
- }
- /**
- * 新增缓存
- *
- * @param doc
- */
- public void addCache(Object obj) {
- if (this.cacheList.size() < pageSize*5) {
- this.cacheList.add(obj);
- } else {
- LOGGER.info("缓存池已满");
- }
- }
- /**
- * 读缓存中的数据
- * @param page
- * @return
- */
- public PagingResults readCache(int page) {
- int start = (page - pageStart) * pageSize;
- int end = start + pageSize > cacheList.size() ? cacheList.size()
- : start + pageSize;
- //缓存中的结果集
- List cacheRs = new ArrayList();
- for (int i = start; i < end; i++) {
- cacheRs.add(cacheList.get(i));
- }
- //缓存结果集
- PagingResults pageResult = new PagingResults();
- pageResult.setCurrentPage(page); //当前页
- pageResult.setTotalSize(totalNum); //总记录条数
- pageResult.setTotalPages(pageNum); //总页数
- pageResult.setList(cacheRs);
- return pageResult;
- }
- /**
- * 搜索
- * @param query query对象
- * @param sort 排序对象
- * @param page 页码
- * @return
- */
- public PagingResults search(PagingParams params) throws IOException{
- int page = params.getNextPage();
- if (page < 0) {
- page = 1;
- }
- //如果存在缓存中
- if (inCache(page)) {
- return readCache(page);
- }else {//如果不在缓存中
- //总共记录条数
- int totalNum = baseDAOImpl.getSum(params.getAllSizeHql());
- //总页数
- int pageNum = totalNum % pageSize == 0 ? totalNum / pageSize : totalNum / pageSize + 1;
- if (page > pageNum) {
- page = pageNum;
- }
- //保存当前页的前后两页放入缓存中
- int startPage = 1;
- int endPage = 1;
- if (page <= 5) { //前五页
- startPage = 1;
- endPage = startPage + 4 > pageNum ? pageNum : startPage + 4;
- }else if(page >= pageNum - 4){ //后五页
- endPage = pageNum ;
- startPage = endPage - 4 < 0 ? 1 : endPage - 4;
- } else { //中间页
- startPage = page - 2 <= 0 ? 1 : page - 2;
- endPage = page + 2 > pageNum ? pageNum : page + 2;
- }
- //清空缓存
- refleshCache();
- //得到缓存结果集
- List resultList = baseDAOImpl.getAllResults(params.getQueryHql(),startPage,pageSize*5,params.getClazz());
- //将对象加入缓存中
- for (int i = 0,len = resultList.size() ; i < len; i++) {
- addCache(resultList.get(i));
- }
- //替换缓存集合
- this.pageNum = pageNum;
- this.totalNum = totalNum;
- this.pageStart = startPage;
- return readCache(page);
- }
- }
- public Integer getPageSize() {
- return pageSize;
- }
- public void setPageSize(Integer pageSize) {
- this.pageSize = pageSize;
- }
- public Integer getPageStart() {
- return pageStart;
- }
- public void setPageStart(Integer pageStart) {
- this.pageStart = pageStart;
- }
- // public Integer getCacheSize() {
- // return cacheSize;
- // }
- //
- // public void setCacheSize(Integer cacheSize) {
- // this.cacheSize = cacheSize;
- // }
- }
三,dao层的两个方法,其他方法省略....
- package com.dg11185.iyw.baseDAO;
- import java.sql.CallableStatement;
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.ResultSetMetaData;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import javax.annotation.Resource;
- import javax.sql.DataSource;
- import org.springframework.dao.DataAccessException;
- import org.springframework.jdbc.core.BatchPreparedStatementSetter;
- import org.springframework.jdbc.core.CallableStatementCallback;
- import org.springframework.jdbc.core.CallableStatementCreator;
- import org.springframework.jdbc.core.SqlParameter;
- import org.springframework.jdbc.core.support.JdbcDaoSupport;
- import org.springframework.stereotype.Repository;
- import com.dg11185.iyw.common.ObjectRowMapper;
- import com.dg11185.iyw.common.PagingParams;
- /**
- * BaseDAO的实现类
- *
- * @author 黄文韬
- * @since 1.0
- * @Copyright 2013 东莞市邮政局All rights reserved.
- */
- @Repository
- public class BaseDAOImpl extends JdbcDaoSupport implements BaseDAO {
- @Resource(name = "dataSource")
- public void setMyDataSource(DataSource dataSource) {
- super.setDataSource(dataSource);
- }
- /**
- * 根据序列得到记录的ID
- *
- * @param seqName
- * @return
- */
- @Override
- public int getTableId(String seqName) {
- String queryId = "select " + seqName + ".nextval from dual";
- return getJdbcTemplate().queryForInt(queryId);
- }
- /**
- * 得到所有的记录
- *
- * @param sql 查询sql
- * @param startPage 起始页
- * @param pageSize 每页大小
- * @param claszz 查询的类名
- * @return
- */
- public List getAllResults(String sql, Integer startPage, Integer pageSize,
- Class claszz) {
- // 终止位置
- int start = (startPage - 1) * pageSize + 1;
- int end = startPage * pageSize;
- // 得到分页数据
- String allSQL = "select * from(select rownum rn,e.* from (" + sql
- + ") e where rownum <= " + end + ") where rn >= " + start;
- List locations = getJdbcTemplate().query(allSQL,
- new ObjectRowMapper(claszz));
- return locations;
- }
- /**
- * 得到总共的数据
- *
- * @param sql
- * @return
- */
- @Override
- public int getSum(String sql, Object... obj) {
- return getJdbcTemplate().queryForInt(sql, obj);
- }
- //。。。。(其他方法省略)
- }