mybatis分页,spring3.1+struts2

本文介绍了一种基于MyBatis的手动分页实现方法,适用于大数据量场景下的分页查询。通过自定义分页逻辑,避免了内存溢出问题,并提供了具体的实现代码和步骤。

有的代码是拷贝来的。捣鼓了半天才好用。mybatis自带的分页是内存的。测试了下10W条的数据。立马内存溢出,只能自己瞎写了。

为了其他人使用的时候方便可能写的有点麻烦。

代码下载地址:http://download.csdn.net/detail/fairyhawk/4938207

有错误或者不好的地方请指正下,多分享~

一、先贴下开发人员使用时需要写的4个地方

1.action,比普通方法多传个分页的this.getPage()就可以。

/**
	 * 分页demo
	 * @return String
	 */
	public String testpage() {
		try {
			this.getPage().setPageSize(50);//设置每页为50,默认10
			customerLists = customerService.getCustomerName(getQueryCondation(),
					this.getPage());
		} catch (Exception e) {
			logger.error("test page error:",e);
			return ERROR;
		}
		return "testpage";
	}
2 jsp.显示,在页面下方引用公用的分页jsp
 <body>
   <s:iterator value="customerLists" var="customer">
		<s:property value="#customer.email"/><br/>
	</s:iterator>
    <jsp:include page="/WEB-INF/jsp/common/page.jsp" />
  </body>

3.实现类:传入参数,sql.条件类和分页类

(分页一般会用2个SQL,一个查询数据list,另一个查询总行数,这个地方只设置了一个。另一个必须命名为加PageCount)

public List<Customer> getCustomerName(CustomerQueryCondition queryCondition,PageEntity page){
		return this.queryForListPage("CustomerMapper.getCustest", queryCondition,page);
	};

4.mybstis sql:如3所注意的命名
getCustest,另一个计算count的sql必须命名为getCustestPageCount,也可以让3的实现类传2个sql.就可以随便命名了。。。

<!-- 分页demo Sql-->
    <select id="getCustest" parameterType="java.util.HashMap" resultMap="csutomerMap">
     	select *  from cus_customer_tbl where
     	<![CDATA[  cus_id <#{pageCondition.cusId,jdbcType=INTEGER}  ]]>
     	order by cus_id desc
     	<include refid="publicMapper.pageEnd"/>
    </select>
     <select id="getCustestPageCount" parameterType="java.util.HashMap" resultType="java.lang.Integer">
     	select count(1)  from cus_customer_tbl where
     	<![CDATA[  cus_id <#{pageCondition.cusId,jdbcType=INTEGER}  ]]>
    </select>

个人使用的时候应该只需要注意这4个地方就可以了。谁有更简便的求代码~


二、下面贴一下详细的代码。其实重要的地方就3个地方。1. BaseService里返回分页的方法queryForListPage,2.CommonAction获得页面请求的参数,3,分页page.jsp

customerAction,继承CommonAction

package com.ssi.edu.customer.action;
import java.util.List;
import org.apache.log4j.Logger;
import com.ssi.common.action.CommonAction;
import com.ssi.edu.customer.dto.CustomerQueryCondition;
import com.ssi.edu.customer.entity.Customer;
import com.ssi.edu.customer.iservice.ICustomerService;
public class CustomerAction extends CommonAction {
	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = -5437567400651524629L;
	private static final Logger logger = Logger.getLogger(CustomerAction.class);

	private ICustomerService customerService;
	private List<Customer> customerLists;
	CustomerQueryCondition queryCondition;
	/**
	 * 分页demo
	 * @return String
	 */
	public String testpage() {
		try {
			this.getPage().setPageSize(50);//设置每页为50,默认10
			customerLists = customerService.getCustomerName(getQueryCondation(),
					this.getPage());
		} catch (Exception e) {
			logger.error("test page error:",e);
			return ERROR;
		}
		return "testpage";
	}
	/**
	 * ajax demo
	 * @return
	 */
	public String tesajax() {
		this.getPage().setPageSize(50);
		customerLists = customerService.getCustomerName(getQueryCondation(),
				this.getPage());
		return "json";
	}
	public ICustomerService getCustomerService() {
		return customerService;
	}

	public void setCustomerService(ICustomerService customerService) {
		this.customerService = customerService;
	}

	public List<Customer> getCustomerLists() {
		return customerLists;
	}

	public void setCustomerLists(List<Customer> customerLists) {
		this.customerLists = customerLists;
	}

	public CustomerQueryCondition getQueryCondation() {
		if (queryCondition == null) {
			queryCondition = new CustomerQueryCondition();
		}
		return queryCondition;
	}

	public void setQueryCondation(CustomerQueryCondition queryCondition) {
		this.queryCondition = queryCondition;
	}

}

CommonAction:主要定义page变量和
getServletRequestUrlParms 方法~

public class CommonAction extends ActionSupport{
	/**
	 * 
	 */
	private static final long serialVersionUID = -2257300693413224000L;
	
	ActionContext context = ActionContext.getContext(); 
	
	
	/** 分页页面地址及参数 */
	private String servletRequestParms;
	/** log对象 */
	private static final Logger logger = Logger.getLogger(CommonAction.class);
	/** request对象 */
	protected HttpServletRequest servletRequest;
	/** response对象 */
	private HttpServletResponse servletResponse;

    	private PageEntity page;


	public HttpServletRequest getServletRequest() {
		return (HttpServletRequest) (servletRequest != null ? servletRequest : context.get(ServletActionContext.HTTP_REQUEST));
	}

	public void setServletRequest(HttpServletRequest servletRequest) {
		this.servletRequest = servletRequest;
	}

	public HttpServletResponse getServletResponse() {
		return (HttpServletResponse) (servletResponse != null ? servletResponse : context.get(ServletActionContext.HTTP_RESPONSE));
	}

	public void setServletResponse(HttpServletResponse servletResponse) {
		this.servletResponse = servletResponse;
	}

	/**
	 * 获取URL及参数
	 * 
	 * @return 
	 */
	public String getServletRequestUrlParms(){
		//获得的地址参数,如果没有为空 ,有时是以&结束的
		StringBuffer sbUrlParms = getServletRequest().getRequestURL();
		sbUrlParms.append("?");
		@SuppressWarnings("rawtypes")
		Enumeration parNames = getServletRequest().getParameterNames();
		while (parNames.hasMoreElements()) {
			String parName = parNames.nextElement().toString();
			try {
				sbUrlParms.append(parName).append("=").append(
						URLEncoder.encode(getServletRequest().getParameter(parName),"UTF-8")).append("&");
			} catch (UnsupportedEncodingException e) {
				logger.error("基类获取分页参数错误", e);
				return "";
			}
		}
		return sbUrlParms.toString();
	}

	public void setServletRequestParms() {
		this.servletRequestParms = getServletRequestUrlParms();
	}

	public String getServletRequestParms() {
		servletRequestParms=getServletRequestUrlParms();
		return servletRequestParms;
	}

	public void setServletRequestParms(String servletRequestParms) {
		this.servletRequestParms = servletRequestParms;
	}


	public void setSession(String name, Object o) {
		ActionContext.getContext().getSession().put(name, o);
	}

	@SuppressWarnings("unchecked")
	public <T extends Object> T getSession(String name) {
		if (ActionContext.getContext().getSession().get(name) == null) {
			return null;
		} else {
			return (T) ActionContext.getContext().getSession().get(name);
		}
	}
 

	public PageEntity getPage() {
		if (page==null){
			page =new PageEntity();
		}
		return page;
	}

	public void setPage(PageEntity page) {
		this.page = page;
	}
}

实现类,继承BaseService

package com.ssi.edu.customer.serviceImpl;

import java.util.List;

import com.ssi.common.entity.PageEntity;
import com.ssi.common.service.BaseService;
import com.ssi.edu.customer.dto.CustomerQueryCondition;
import com.ssi.edu.customer.entity.Customer;
import com.ssi.edu.customer.iservice.ICustomerService;

public class ICustomerServiceImpl extends BaseService implements ICustomerService {
	
	public List<Customer> getCustomerName(CustomerQueryCondition queryCondition,PageEntity page){
		return this.queryForListPage("CustomerMapper.getCustest", queryCondition,page);
	};
	public List<Customer> getCustomerName(CustomerQueryCondition queryCondition){
		return this.getMyBatisDao().selectList("CustomerMapper.getCustomerListJson", queryCondition);
	};
	
}

BaseService:主要定义了dao接口和分页的方法。分页的也可以直接写在mybatisdao的实现里。我单独放这边了。。

package com.ssi.common.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ssi.common.dao.MyBatisDao;
import com.ssi.common.entity.PageEntity;
import com.ssi.common.entity.PageOL;

public abstract class BaseService {

	private MyBatisDao myBatisDao;

	public MyBatisDao getMyBatisDao() {
		return myBatisDao;
	}

	public void setMyBatisDao(MyBatisDao myBatisDao) {
		this.myBatisDao = myBatisDao;
	}

	/**
	 * 分页查询时使用
	 * 
	 * @return
	 */
	public <T> List<T> queryForListPage(String sqlKey, Object params,
			PageEntity page) {

		/**
		 * 分页时需要2个sql。在正常sql后面加pageCount为计算count的sql
		 * 如:customre.getcustomreByTime必须命名为customre.getcustomreByTimePageCount
		 */

		// 查询总行数
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("pageCondition", params);
		PageOL pageOL = new PageOL();
		pageOL.setOffsetPara((page.getCurrentPage() - 1)
				* page.getPageSize());
		pageOL.setLimitPara(page.getPageSize());
		map.put("page", pageOL);
		
		Integer objectscount = this.getMyBatisDao().selectOne(
				sqlKey+ "PageCount",
				map);

		if (objectscount == null || objectscount == 0) {
			page.setTotalResultSize(0);
			int totalPageSize = (page.getTotalResultSize() - 1)
					/ page.getPageSize() + 1;
			page.setTotalPageSize(totalPageSize);
			return null;
		} else {
			page.setTotalResultSize(objectscount);
			int totalPageSize = (page.getTotalResultSize() - 1)
					/ page.getPageSize() + 1;
			page.setTotalPageSize(totalPageSize);
			return this.getMyBatisDao().selectList(sqlKey, map);
		}

	}

}

MyBatisDaoImpl实现类:这个没什么东西。跟mybatis的sqlsession的方法一样。

package com.ssi.common.dao;

import java.util.List;

import org.mybatis.spring.support.SqlSessionDaoSupport;

public class  MyBatisDaoImpl extends SqlSessionDaoSupport implements MyBatisDao{
	
	public int insert(String sqlKey, Object object) {
		return (Integer) this.getSqlSession().insert(sqlKey, object);
	}

	public int delete(String sqlKey, Object object) {
		return this.getSqlSession().delete(sqlKey, object);
	}
	
	public int update(String key, Object object) {
		return getSqlSession().update(key, object);
	}
	
	@SuppressWarnings("unchecked")
	public <T> T selectOne(String sqlKey, Object params) {
		return (T) this.getSqlSession().selectOne(sqlKey, params);
	}
	
	public <T> List<T> selectList(String sqlKey, Object params) {
		return this.getSqlSession().selectList(sqlKey, params);
	}
    
    
}

分页的jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<%@ include file="/WEB-INF/inc/header.inc" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<s:if test="page != null" >
  <table border="0" width="100%" height="100%" class="lists_td_ablock">
        <tr>
        	<td>
        	 共有 <s:property value="page.totalResultSize"/> 条记录,当前第 <s:property value="page.currentPage"/>/<s:property value="page.totalPageSize"/> 页
        	</td>
            <td width="45">
                <s:if test="!page.first">
                    <a href="#" onclick="goPage(1);">
                </s:if>
                <img src="<%=contextPath%>/back/images/first.gif" />
                <s:if test="!page.first">
                    </a>
                </s:if>
            </td>
            <td width="45">
                <s:if test="!page.first">
                    <a href="#" onclick="goPage(<s:property value="page.currentPage-1"/>);">
                </s:if>
              	<img src="<%=contextPath%>/back/images/back.gif" />
                <s:if test="!page.first">
                    </a>
                </s:if>
            </td>
            <td id="goPageByNumber" width="15">
            </td>
            <td width="45">
                <s:if test="!page.last">
                    <a href="#" onclick="goPage(<s:property value="page.currentPage+1"/>);">
                </s:if>
               	<img src="<%=contextPath%>/back/images/next.gif" /> 
                <s:if test="!page.last">
                    </a>
                </s:if>
            </td>
            <td width="45">
                <s:if test="!page.last">
                    <a href="#" onclick="goPage(<s:property value="page.totalPageSize"/>);">
                </s:if>
               	<img src="<%=contextPath%>/back/images/last.gif" />
                <s:if test="!page.last">
                    </a>
                </s:if>
            </td>
            <td width="50">
            	<div align="center"><span class="STYLE1">转到第</span></div>
            </td>
            <td width="25">
            	<div align="center"><span class="STYLE1">
                    <input name="textfield" id="pageNoIpt" type="text" size="4" style="height:16px; margin-top:2px; width:24px; border:1px solid #999999;" /> 
                    </span></div>
            </td>
            <td width="16">
            	<div align="center"><span class="STYLE1">页 </span></div>
            </td>
            <td width="45">
            	<a href="javascript:goPageByInput()"><img src="<%=contextPath%>/back/images/go.gif" width="37" height="15" /></a>
            </td>
        </tr>
    </table>  
</s:if>

<script type="text/javascript">

	var totalPageSize=<s:property value="page.totalPageSize"/>;//总页码
    function goPage(pageNum){
        var pageNoReg = new RegExp("\\.currentPage=[0-9]*");
        document.location="${servletRequestParms}".replace(pageNoReg,".currentPage=" + pageNum);
    }
    
    function goPageByInput() {
    	var pageNo = document.getElementById("pageNoIpt").value;
    	if(/^\d+$/.test(pageNo)==false) {
    		alert("只能输入整数,请重新输入!");
    		document.getElementById("pageNoIpt").value='';
    		return;
    	}
    	if(pageNo < 1) {
    		pageNo = 1;
    	}
    	if(pageNo > totalPageSize) {
    		if(totalPageSize>0)
    			pageNo = totalPageSize;
    		else
    			pageNo=1;
    	}
    	goPage(pageNo);
    };
    
</script>




封装通用的Spring3+Struts2+MyBatis3的CRUD+条件分页查询,Spring+Quartz调度,FunctionCharts图像化工具 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="temperMonitorTimerJob" class="cn.sup.cd.listener.TemperatureMonitorTaskJob"></bean> <!-- 政策调度--> <bean id="temperMonitorTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <!-- 调用的类 --> <property name="targetObject"> <ref bean="temperMonitorTimerJob"/> </property> <!-- 调用类中的方法 --> <property name="targetMethod"> <value>temperatureMonitorTimer</value> </property> </bean> <!-- BOOK定义触发时间 几秒后执行monitor.start.time 每隔monitor.interval.time执行--> <bean id="getPolicyTime" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="temperMonitorTask"/> </property> <!-- cron表达式 --> <property name="cronExpression"> <value>${monitor.start.time}/${monitor.interval.time} * * * * ?</value> </property> </bean> <!-- 总管理类 如果将lazy-init=&#39;false&#39;那么容器启动就会执行调度程序 --> <bean id="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="getPolicyTime"/> </list> </property> </bean> </beans>
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值