Java简单实现SpringMVC+MyBatis分页插件
程序员文章站
2024-03-06 14:54:50
1.封装分页page类
package com.framework.common.page.impl;
import java.io.serializabl...
1.封装分页page类
package com.framework.common.page.impl; import java.io.serializable; import com.framework.common.page.ipage; /** * * * */ public abstract class basepage implements ipage, serializable { /** * */ private static final long serialversionuid = -3623448612757790359l; public static int default_page_size = 20; private int pagesize = default_page_size; private int currentresult; private int totalpage; private int currentpage = 1; private int totalcount = -1; public basepage(int currentpage, int pagesize, int totalcount) { this.currentpage = currentpage; this.pagesize = pagesize; this.totalcount = totalcount; } public int gettotalcount() { return this.totalcount; } public void settotalcount(int totalcount) { if (totalcount < 0) { this.totalcount = 0; return; } this.totalcount = totalcount; } public basepage() { } public int getfirstresult() { return (this.currentpage - 1) * this.pagesize; } public void setpagesize(int pagesize) { if (pagesize < 0) { this.pagesize = default_page_size; return; } this.pagesize = pagesize; } public int gettotalpage() { if (this.totalpage <= 0) { this.totalpage = (this.totalcount / this.pagesize); if ((this.totalpage == 0) || (this.totalcount % this.pagesize != 0)) { this.totalpage += 1; } } return this.totalpage; } public int getpagesize() { return this.pagesize; } public void setpageno(int currentpage) { this.currentpage = currentpage; } public int getpageno() { return this.currentpage; } public boolean isfirstpage() { return this.currentpage <= 1; } public boolean islastpage() { return this.currentpage >= gettotalpage(); } public int getnextpage() { if (islastpage()) { return this.currentpage; } return this.currentpage + 1; } public int getcurrentresult() { this.currentresult = ((getpageno() - 1) * getpagesize()); if (this.currentresult < 0) { this.currentresult = 0; } return this.currentresult; } public int getprepage() { if (isfirstpage()) { return this.currentpage; } return this.currentpage - 1; } }
package com.framework.common.page.impl; import java.util.list; /** * * * */ public class page extends basepage { /** * */ private static final long serialversionuid = -970177928709377315l; public static threadlocal<page> threadlocal = new threadlocal<page>(); private list<?> data; public page() { } public page(int currentpage, int pagesize, int totalcount) { super(currentpage, pagesize, totalcount); } public page(int currentpage, int pagesize, int totalcount, list<?> data) { super(currentpage, pagesize, totalcount); this.data = data; } public list<?> getdata() { return data; } public void setdata(list<?> data) { this.data = data; } }
2.封装分页插件
package com.framework.common.page.plugin; import java.sql.connection; import java.sql.preparedstatement; import java.sql.resultset; import java.sql.sqlexception; import java.util.list; import java.util.properties; import javax.xml.bind.propertyexception; import org.apache.commons.lang3.stringutils; import org.apache.ibatis.executor.errorcontext; import org.apache.ibatis.executor.executorexception; import org.apache.ibatis.executor.statement.basestatementhandler; import org.apache.ibatis.executor.statement.routingstatementhandler; import org.apache.ibatis.mapping.boundsql; import org.apache.ibatis.mapping.mappedstatement; import org.apache.ibatis.mapping.parametermapping; import org.apache.ibatis.mapping.parametermode; import org.apache.ibatis.plugin.interceptor; import org.apache.ibatis.plugin.intercepts; import org.apache.ibatis.plugin.invocation; import org.apache.ibatis.plugin.plugin; import org.apache.ibatis.reflection.metaobject; import org.apache.ibatis.reflection.property.propertytokenizer; import org.apache.ibatis.scripting.xmltags.foreachsqlnode; import org.apache.ibatis.session.configuration; import org.apache.ibatis.type.typehandler; import org.apache.ibatis.type.typehandlerregistry; import com.framework.common.page.impl.page; import com.framework.common.utils.reflectutil; /** * * * */ @intercepts({ @org.apache.ibatis.plugin.signature(type = org.apache.ibatis.executor.statement.statementhandler.class, method = "prepare", args = { connection.class }) }) public class pageplugin implements interceptor { private string dialect = ""; private string pagesqlid = ""; @override public object intercept(invocation invocation) throws throwable { if (invocation.gettarget() instanceof routingstatementhandler) { basestatementhandler delegate = (basestatementhandler) reflectutil .getvaluebyfieldname( (routingstatementhandler) invocation.gettarget(), "delegate"); mappedstatement mappedstatement = (mappedstatement) reflectutil .getvaluebyfieldname(delegate, "mappedstatement"); page page = page.threadlocal.get(); if (page == null) { page = new page(); page.threadlocal.set(page); } if (mappedstatement.getid().matches(".*(" + this.pagesqlid + ")$") && page.getpagesize() > 0) { boundsql boundsql = delegate.getboundsql(); object parameterobject = boundsql.getparameterobject(); string sql = boundsql.getsql(); string countsqlid = mappedstatement.getid().replaceall(pagesqlid, "count"); mappedstatement countmappedstatement = null; if (mappedstatement.getconfiguration().hasstatement(countsqlid)) { countmappedstatement = mappedstatement.getconfiguration().getmappedstatement(countsqlid); } string countsql = null; if (countmappedstatement != null) { countsql = countmappedstatement.getboundsql(parameterobject).getsql(); } else { countsql = "select count(1) from (" + sql + ") t_count"; } int totalcount = 0; preparedstatement countstmt = null; resultset resultset = null; try { connection connection = (connection) invocation.getargs()[0]; countstmt = connection.preparestatement(countsql); boundsql countboundsql = new boundsql(mappedstatement.getconfiguration(), countsql, boundsql.getparametermappings(), parameterobject); setparameters(countstmt, mappedstatement, countboundsql, parameterobject); resultset = countstmt.executequery(); if(resultset.next()) { totalcount = resultset.getint(1); } } catch (exception e) { throw e; } finally { try { if (resultset != null) { resultset.close(); } } finally { if (countstmt != null) { countstmt.close(); } } } page.settotalcount(totalcount); reflectutil.setvaluebyfieldname(boundsql, "sql", generatepagesql(sql,page)); } } return invocation.proceed(); } /** * 对sql参数(?)设值,参考org.apache.ibatis.executor.parameter.defaultparameterhandler * @param ps * @param mappedstatement * @param boundsql * @param parameterobject * @throws sqlexception */ private void setparameters(preparedstatement ps,mappedstatement mappedstatement,boundsql boundsql,object parameterobject) throws sqlexception { errorcontext.instance().activity("setting parameters").object(mappedstatement.getparametermap().getid()); list<parametermapping> parametermappings = boundsql.getparametermappings(); if (parametermappings != null) { configuration configuration = mappedstatement.getconfiguration(); typehandlerregistry typehandlerregistry = configuration.gettypehandlerregistry(); metaobject metaobject = parameterobject == null ? null: configuration.newmetaobject(parameterobject); for (int i = 0; i < parametermappings.size(); i++) { parametermapping parametermapping = parametermappings.get(i); if (parametermapping.getmode() != parametermode.out) { object value; string propertyname = parametermapping.getproperty(); propertytokenizer prop = new propertytokenizer(propertyname); if (parameterobject == null) { value = null; } else if (typehandlerregistry.hastypehandler(parameterobject.getclass())) { value = parameterobject; } else if (boundsql.hasadditionalparameter(propertyname)) { value = boundsql.getadditionalparameter(propertyname); } else if (propertyname.startswith(foreachsqlnode.item_prefix)&& boundsql.hasadditionalparameter(prop.getname())) { value = boundsql.getadditionalparameter(prop.getname()); if (value != null) { value = configuration.newmetaobject(value).getvalue(propertyname.substring(prop.getname().length())); } } else { value = metaobject == null ? null : metaobject.getvalue(propertyname); } typehandler typehandler = parametermapping.gettypehandler(); if (typehandler == null) { throw new executorexception("there was no typehandler found for parameter "+ propertyname + " of statement "+ mappedstatement.getid()); } typehandler.setparameter(ps, i + 1, value, parametermapping.getjdbctype()); } } } } /** * 根据数据库方言,生成特定的分页sql * @param sql * @param page * @return */ private string generatepagesql(string sql,page page){ if(page!=null && stringutils.isnotblank(dialect)){ stringbuffer pagesql = new stringbuffer(); if("mysql".equals(dialect)){ pagesql.append(sql); pagesql.append(" limit "+page.getcurrentresult()+","+page.getpagesize()); }else if("oracle".equals(dialect)){ pagesql.append("select * from (select tmp_tb.*,rownum row_id from ("); pagesql.append(sql); pagesql.append(") as tmp_tb where rownum <= "); pagesql.append(page.getcurrentresult()+page.getpagesize()); pagesql.append(") where row_id > "); pagesql.append(page.getcurrentresult()); } return pagesql.tostring(); }else{ return sql; } } @override public object plugin(object target) { return plugin.wrap(target, this); } @override public void setproperties(properties properties) { try { if (stringutils.isempty(this.dialect = properties .getproperty("dialect"))) { throw new propertyexception("dialect property is not found!"); } if (stringutils.isempty(this.pagesqlid = properties .getproperty("pagesqlid"))) { throw new propertyexception("pagesqlid property is not found!"); } } catch (propertyexception e) { e.printstacktrace(); } } }
3.mybatis配置文件:mybatis-config.xml
<?xml version="1.0" encoding="utf-8"?> <!doctype configuration public "-//mybatis.org//dtd sql map config 3.0//en" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <plugins> <plugin interceptor="com.framework.common.page.plugin.pageplugin"> <property name="dialect" value="mysql" /> <property name="pagesqlid" value="bypage" /> </plugin> </plugins> </configuration>
4.分页拦截器
package com.framework.common.page.interceptor; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import org.apache.commons.lang3.math.numberutils; import org.springframework.web.servlet.modelandview; import org.springframework.web.servlet.handler.handlerinterceptoradapter; import com.framework.common.page.impl.page; /** * * 14 * */ public class pageinterceptor extends handlerinterceptoradapter { @override public void posthandle(httpservletrequest request, httpservletresponse response, object handler, modelandview modelandview) throws exception { super.posthandle(request, response, handler, modelandview); page page = page.threadlocal.get(); if (page != null) { request.setattribute("page", page); } page.threadlocal.remove(); } @override public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception { string pagesize = request.getparameter("pagesize"); string pageno = request.getparameter("pageno"); page page = new page(); if (numberutils.isnumber(pagesize)) { page.setpagesize(numberutils.toint(pagesize)); } if (numberutils.isnumber(pageno)) { page.setpageno(numberutils.toint(pageno)); } page.threadlocal.set(page); return true; } }
5.spring配置
<!-- =================================================================== - load property file - =================================================================== --> <context:property-placeholder location="classpath:application.properties" /> <bean id="sqlsessionfactory" class="org.mybatis.spring.sqlsessionfactorybean"> <property name="datasource" ref="datasource" /> <property name="configlocation" value="classpath:mybatis-config.xml" /> <property name="mapperlocations"> <list> <value>classpath:/com/framework/mapper/**/*mapper.xml</value> </list> </property> </bean> <!-- =================================================================== - 通过扫描的模式,扫描目录下所有的dao, 根据对应的mapper.xml为其生成代理类 - =================================================================== --> <bean id="mapperscannerconfigurer" class="org.mybatis.spring.mapper.mapperscannerconfigurer"> <property name="basepackage" value="com.framework.dao" /> <property name="processpropertyplaceholders" value="true" /> <property name="sqlsessionfactorybeanname" value="sqlsessionfactory" /> </bean>
6.springmvc配置拦截器
<!-- 分页拦截器 --> <bean id="pageinterceptor" class="com.framework.common.page.interceptor.pageinterceptor"></bean> <!-- 配置拦截器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.requestmappinghandlermapping"> <property name="interceptors"> <list> <ref bean="pageinterceptor" /> </list> </property> </bean>
上一篇: Yii框架表单提交验证功能分析
下一篇: Hibernate映射解析之关联映射详解