欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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>