1. 程式人生 > >SpringMVC+MyBatis分頁外掛簡單實現

SpringMVC+MyBatis分頁外掛簡單實現

一、封裝分頁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;
     }
     
 
 }
二.封裝分頁外掛
    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();
        }
    }

}
三.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>
四.分頁攔截器
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;
    }
}
五、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>
六、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>







相關推薦

SpringMVC+MyBatis外掛簡單實現

一、封裝分頁page類 package com.framework.common.page.impl; import java.io.Serializable; import com.framework.common.page.IPage; /*

基於Mybatis外掛PageHelper實現功能

使用PageHelper外掛實現分頁功能 分頁的功能幾乎是所有專案必備的功能,在SSM(spring 、springmvc、mybatis)組織的專案中如何實現分頁呢? 下面介紹一種基於mybatis的分頁外掛PageHelper來幫助我們實現分頁的功能。

MyBatis簡單實現

使用spring+springmvc+mybatis實現簡單的分頁查詢 spring+springmvc+mybatis的整合配置就不在贅述了 1.需要下載pagehelper-3.2.1.jar

mybatis 外掛PageHelper的簡單使用

分頁方式的分類: 邏輯分頁 物理分頁 MyBatis-PageHelper 的使用: 首先在pom.xml配置檔案中增加相關的外掛。 外掛地址:https://github.com/pagehelper/Mybatis-PageHelper <depende

mybatis外掛PageHelper的簡單使用

外掛叫做PageHelper如果你也在用Mybatis,建議嘗試該分頁外掛,這個一定是最方便使用的分頁外掛。 該外掛目前支援Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六種資料庫分頁。 使用方法: 第一步:匯入mybatis的分頁jar包。(

mybatis外掛pageHelper簡單實用

工作的框架spring springmvc mybatis3 首先使用分頁外掛必須先引入maven依賴,在pom.xml中新增如下 <!-- 分頁助手 --> <dependency> <groupId>com.githu

easyui + mybatis 外掛 PageHelper 完成顯示功能(SpringMVC + mybatis 框架)

1、使用 easyUI datagrid 完成前臺分頁展示 <table id="dg" title="產品管理" style="width:700px;height:550px"> <thead>

mybatis外掛實現

1.瞭解過程:在資料庫伺服器中,sql語句實現分頁便要每個查詢語句都要寫上limit(開始,結束),並且不能靈活的隨前端變化,為此使用攔截器的方法,過程:攔截器攔截請求的sql語句(根據需要攔截的ID(正則匹配),進行攔截),並對根據前端傳過來的頁數,和每頁的條

Mybatis外掛PageHelper簡單使用

開發十年,就只剩下這套架構體系了! >>>   

Mybatis外掛的使用配置

開源中國介紹參考地址: http://www.oschina.net/p/mybatis_pagehelper  Github 原始碼介紹地址:   https://github.com/pagehelper/Mybatis-PageHe

Mybatis外掛Mybatis-PageHelper

一、引入jar包 在 pom.xml 中新增如下依賴: <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</a

大資料量 Mybatis 外掛Count語句優化

前言 當在大數量的情況下,進行分頁查詢,統計總數時,會自動count一次,這個語句是在我們的查詢語句的基礎上巢狀一層,如: SELECT COUNT(*) FROM (主sql) 這樣在資料量大的情況下,會出問題,很容易cpu就跑滿了 優化 在mapper.xml

SpringBoot整合MyBatis外掛PageHelper

原創作品,可以轉載,但是請標註出處地址:https://www.cnblogs.com/V1haoge/p/9971043.html SpringBoot整合MyBatis分頁外掛PageHelper 步驟 第一步:首先整合MyBatis 參照之前SpringBoot整合MyBatis.md 第二步

Spring Boot實踐——Mybatis外掛PageHelper的使用

出自:https://blog.csdn.net/csdn_huzeliang/article/details/79350425 在springboot中使用PageHelper外掛有兩種較為相似的方式,接下來我就將這兩種方式進行總結。 方式一:使用原生的PageHelper 1.在

【防坑指南】使用Mybatis外掛PageHelper為什麼PageInfo物件出現null的原因

在mybatis中,先匯入pagehelper.jar所需的jar包,然後在sqlMapConfig,xml中配置外掛 <plugins> <!-- com.github.pagehelper為PageHelper類所在包名 --> <plug

PageHelper-----Mybatis外掛

PageHelper的使用 1、pageHelper的maven依賴及外掛配置:com.github.pagehelper <dependency> <groupId>com.github.pagehelper</groupId&

MyBatis功能的實現(陣列、sql、攔截器,RowBounds

前言:學習hibernate & mybatis等持久層框架的時候,不外乎對資料庫的增刪改查操作。而使用最多的當是資料庫的查詢操

MyBatis外掛

第一步 首先要匯入jar包 第二步 <configuration> <!-- 配置分頁外掛 --> <plugins> <plugin interceptor="com.github.pagehelper.PageHe

Mybatis外掛PageHelper的配置和使用方法

前言 在web開發過程中涉及到表格時,例如dataTable,就會產生分頁的需求,通常我們將分頁方式分為兩種:前端分頁和後端分頁。 前端分頁 一次性請求資料表格中的所有記錄(ajax),然後在前端快取並且計算count和分頁邏輯,一般前端元件(例如dataTable)會提

mybatis 外掛的使用

首先,maven的依賴只是下載jar包而已,可以在其他地方下載jar包,無maven的情況下實現分頁需要三步 第一步:下載jar包匯入工程。 第二步:然後直接在mybatis中配置<plugins> 第三步:在需要分頁的service或者contro