分页缓存设置

1,对于分页来说,效率是关键,本例是在分页的时候,缓存5页记录,默认每页20条,缓存大小100,这可以修改的;

2,基本思路是:第一次查的时候,先判断缓存中存不存在当前页的数据,如果存在,查找缓存中的数据,如果不存在,则去数据库中查询5页数据放入缓存中,然后再缓存中读取数据。如果是当前页是前3页,那么读取1-5页的数据,如果当前页是后3页,读取后5页的数据,如果是中间页,读取当前页前两页+当前页+当前页后两页的数据;


一,分页的参数封装类、返回结果封装类;

package com.dg11185.iyw.common;


/**
 * 分页的参数类
 * 
 * @author 黄文韬
 * @since 1.0
 * @Copyright 2013 东莞市邮政局All rights reserved.
 */
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);
	}

	
       //。。。。(其他方法省略)
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值