mybatis常用经典分页方法

来自棱镜学院-在线IT教育www.prismcollege.com

分页方法一:

可以查看如下代码,新建一个数据库分页基础类

[java]  view plain  copy
 
  1. package com.ssm.utils.pagination.pagebounds;  
  2.   
  3. import java.util.List;  
  4. import org.apache.ibatis.session.SqlSession;  
  5. import org.apache.ibatis.session.SqlSessionFactory;  
  6. import org.mybatis.spring.SqlSessionFactoryBean;  
  7. import org.mybatis.spring.SqlSessionUtils;  
  8. import org.springframework.beans.factory.annotation.Autowired;  
  9. import com.github.miemiedev.mybatis.paginator.domain.PageBounds;  
  10. /** 
  11.  * 用于数据库分页 
  12.  * 使用方法如:public class XXXServiceImpl extends BasePageService implements IXXXService { 
  13.  * 然后代码中使用如:this.getPageList(XXXMapper.class, 
  14.                             "selectObjectListMethod", sqlmapperParams, currentPage,pageSize); 
  15.     其中currentPage由网页客户端保存,每次分页+1 
  16.  * @author Administrator 
  17.  * 
  18.  */  
  19. public class BasePageService {  
  20.     @Autowired  
  21.     private SqlSessionFactoryBean sqlSessionFactoryBean;  
  22.   
  23.     public List getPageList(Class mapperClass, String sqlId,  
  24.             Object sqlParameter, int pageIndex, int pageSize) {  
  25.         SqlSession session = null;  
  26.         try {  
  27.             SqlSessionFactory sessionFactory = sqlSessionFactoryBean  
  28.                     .getObject();  
  29.             session = sessionFactory.openSession();  
  30.             if (pageIndex <= 0) {  
  31.                 pageIndex = 1;  
  32.             }  
  33.             if (pageSize <= 0) {  
  34.                 pageSize = 10;  
  35.             }  
  36.             PageBounds pageBounds = new PageBounds(pageIndex, pageSize);  
  37.             List pageList = session.selectList(mapperClass.getName()  
  38.                     + "." + sqlId, sqlParameter, pageBounds);  
  39.             return pageList;  
  40.         } catch (Exception e) {  
  41.             e.printStackTrace();  
  42.         } finally {  
  43.             session.close();  
  44.         }  
  45.         return null;  
  46.     }  
  47. }  

  48. 分页方法2:

    定义一个page基本类,用于网页与后端之间的页面传输封装

    [java]  view plain  copy
     
    1. import java.io.BufferedReader;  
    2. import java.io.File;  
    3. import java.io.FileInputStream;  
    4. import java.io.InputStreamReader;  
    5. import com.ssm.util.PageData;  
    6.   
    7. public class Page {  
    8.     private int isM1 = 0// 每页显示记录数  
    9.     private int isM2; // 每页显示记录数  
    10.     private int showCount = 10// 每页显示记录数  
    11.     private int totalPage; // 总页数  
    12.     private int totalResult; // 总记录数  
    13.     private int currentPage = 1// 当前页  
    14.     private int currentResult; // 当前记录起始索引  
    15.     private boolean entityOrField; // true:需要分页的地方,传入的参数就是Page实体;false:需要分页的地方,传入的参数所代表的实体拥有Page属性  
    16.     private String pageStr; // 最终页面显示的底部翻页导航,详细见:getPageStr();  
    17.     private PageData pd = new PageData();  
    18.     private int begin;  
    19.     private int end;  
    20.     // 总行数,需要外接传入  
    21.     private int rows;  
    22.   
    23.     public int getIsM1() {  
    24.         return isM1;  
    25.     }  
    26.   
    27.     public void setIsM1(int isM1) {  
    28.         this.isM1 = isM1;  
    29.     }  
    30.   
    31.     public int getIsM2() {  
    32.         return isM2;  
    33.     }  
    34.   
    35.     public void setIsM2(int isM2) {  
    36.         this.isM2 = isM2;  
    37.     }  
    38.   
    39.     public int getRows() {  
    40.         return rows;  
    41.     }  
    42.   
    43.     public void setRows(int rows) {  
    44.         this.rows = rows;  
    45.     }  
    46.   
    47.     public int getBegin() {  
    48.         begin = (currentPage - 1) * showCount;  
    49.         return begin;  
    50.     }  
    51.   
    52.     public void setBegin(int begin) {  
    53.         this.begin = begin;  
    54.     }  
    55.   
    56.     public int getEnd() {  
    57.         end = currentPage * showCount;  
    58.         return end;  
    59.     }  
    60.   
    61.     public void setEnd(int end) {  
    62.         this.end = end;  
    63.     }  
    64.   
    65.     public Page() {  
    66.         // 通过page。txt设置每页显示的条数  
    67.         // String xmpath =  
    68.         // String.valueOf(Thread.currentThread().getContextClassLoader().getResource(""));  
    69.         // // System.out.println(xmpath);  
    70.         // xmpath = xmpath.substring(6)+"page.txt";  
    71.         // // System.out.println(xmpath);  
    72.         // this.showCount = Integer.parseInt(readTxtFile(xmpath));  
    73.     }  
    74.   
    75.     public int getTotalPage() {  
    76.         if (rows % showCount == 0)  
    77.             totalPage = rows / showCount;  
    78.         else  
    79.             totalPage = rows / showCount + 1;  
    80.         return totalPage;  
    81.     }  
    82.   
    83.     public void setTotalPage(int totalPage) {  
    84.         this.totalPage = totalPage;  
    85.     }  
    86.   
    87.     public int getTotalResult() {  
    88.         return totalResult;  
    89.     }  
    90.   
    91.     public void setTotalResult(int totalResult) {  
    92.         this.totalResult = totalResult;  
    93.     }  
    94.   
    95.     public int getCurrentPage() {  
    96.         if (currentPage <= 0)  
    97.             currentPage = 1;  
    98.         if (currentPage > getTotalPage())  
    99.             currentPage = getTotalPage();  
    100.         return currentPage;  
    101.     }  
    102.   
    103.     public void setCurrentPage(int currentPage) {  
    104.         this.currentPage = currentPage;  
    105.     }  
    106.   
    107.     // 用于显示页码  
    108.     public String getPageStr() {  
    109.         StringBuffer sb = new StringBuffer();  
    110.         if (totalResult > 0) {  
    111.             sb.append(
        \n");  
      •             if (currentPage == 1) {  
      •                 sb.append(
      • " + totalResult  
      •                         + "条
      • \n");  
      •                 sb.append(
      • \n");  
      •                 sb.append(跳转
      • \n");  
      •                 sb.append(
      • 首页
      • \n");  
      •                 sb.append(
      • 上页
      • \n");  
      •             } else {  
      •                 sb.append(
      • " + totalResult  
      •                         + "条
      • \n");  
      •                 sb.append(
      • \n");  
      •                 sb.append(跳转
      • \n");  
      •                 sb.append(首页
      • \n");  
      •                 sb.append(  
      •                         + (currentPage - 1) + ")\">上页
      • \n");  
      •             }  
      •             int showTag = 3// 分页标签显示数量  
      •             int startTag = 1;  
      •             if (currentPage > showTag) {  
      •                 startTag = currentPage - 1;  
      •             }  
      •             int endTag = startTag + showTag - 1;  
      •             for (int i = startTag; i <= totalPage && i <= endTag; i++) {  
      •                 if (currentPage == i)  
      •                     sb.append("" + i + "
      • \n");  
      •                 else  
      •                     sb.append(  
      •                             + i + ")\">" + i + "
      • \n");  
      •             }  
      •             if (currentPage == totalPage) {  
      •                 sb.append(
      • 下页
      • \n");  
      •                 sb.append(
      • 尾页
      • \n");  
      •             } else {  
      •                 sb.append(  
      •                         + (currentPage + 1) + ")\">下页
      • \n");  
      •                 sb.append(  
      •                         + totalPage + ")\">尾页
      • \n");  
      •             }  
      •             sb.append(
      • 第" + currentPage + "页
      • \n");  
      •             sb.append(
      • 共" + totalPage + "页
      • \n");  
      •             // sb.append("  跳转
      • \n");  
      •             sb.append("
      \n"
      );  
    112.             sb.append("\n");  
    113.             sb.append("function nextPage(page){");  
    114.             sb.append(" if(true && document.forms[0]){\n");  
    115.             sb.append("     var url = document.forms[0].getAttribute(\"action\");\n");  
    116.             sb.append("     if(url.indexOf('?')>-1){url += \"&"  
    117.                     + (entityOrField ? "currentPage" : "page.currentPage")  
    118.                     + "=\";}\n");  
    119.             sb.append("     else{url += \"?"  
    120.                     + (entityOrField ? "currentPage" : "page.currentPage")  
    121.                     + "=\";}\n");  
    122.             sb.append("     document.forms[0].action = url+page;\n");  
    123.             sb.append("     document.forms[0].submit();\n");  
    124.             sb.append(" }else{\n");  
    125.             sb.append("     var url = document.location+'';\n");  
    126.             sb.append("     if(url.indexOf('?')>-1){\n");  
    127.             sb.append("         if(url.indexOf('currentPage')>-1){\n");  
    128.             sb.append("             var reg = /currentPage=\\d*/g;\n");  
    129.             sb.append("             url = url.replace(reg,'currentPage=');\n");  
    130.             sb.append("         }else{\n");  
    131.             sb.append("             url += \"&"  
    132.                     + (entityOrField ? "currentPage" : "page.currentPage")  
    133.                     + "=\";\n");  
    134.             sb.append("         }\n");  
    135.             sb.append("     }else{url += \"?"  
    136.                     + (entityOrField ? "currentPage" : "page.currentPage")  
    137.                     + "=\";}\n");  
    138.             sb.append("     document.location = url + page;\n");  
    139.             sb.append(" }\n");  
    140.             sb.append("}\n");  
    141.             sb.append("function toTZ(){");  
    142.             sb.append("var toPaggeVlue = document.getElementById(\"toGoPage\").value;");  
    143.             sb.append("if(toPaggeVlue == ''){document.getElementById(\"toGoPage\").value=1;return;}");  
    144.             sb.append("if(isNaN(Number(toPaggeVlue))){document.getElementById(\"toGoPage\").value=1;return;}");  
    145.             sb.append("nextPage(toPaggeVlue);");  
    146.             sb.append("}\n");  
    147.             sb.append("\n");  
    148.         }  
    149.         pageStr = sb.toString();  
    150.         return pageStr;  
    151.     }  
    152.   
    153.     public void setPageStr(String pageStr) {  
    154.         this.pageStr = pageStr;  
    155.     }  
    156.   
    157.     public int getShowCount() {  
    158.         return showCount;  
    159.     }  
    160.   
    161.     public void setShowCount(int showCount) {  
    162.   
    163.         this.showCount = showCount;  
    164.     }  
    165.   
    166.     public int getCurrentResult() {  
    167.         currentResult = (getCurrentPage() - 1) * getShowCount();  
    168.         if (currentResult < 0)  
    169.             currentResult = 0;  
    170.         return currentResult;  
    171.     }  
    172.   
    173.     public void setCurrentResult(int currentResult) {  
    174.         this.currentResult = currentResult;  
    175.     }  
    176.   
    177.     public boolean isEntityOrField() {  
    178.         return entityOrField;  
    179.     }  
    180.   
    181.     public void setEntityOrField(boolean entityOrField) {  
    182.         this.entityOrField = entityOrField;  
    183.     }  
    184.   
    185.     public PageData getPd() {  
    186.         return pd;  
    187.     }  
    188.   
    189.     public void setPd(PageData pd) {  
    190.         this.pd = pd;  
    191.     }  
    192.   
    193.     // 读取文件  
    194.     public String readTxtFile(String filePath) {  
    195.         try {  
    196.             String encoding = "utf-8";  
    197.             File file = new File(filePath);  
    198.             if (file.isFile() && file.exists()) { // 判断文件是否存在  
    199.                 InputStreamReader read = new InputStreamReader(  
    200.                         new FileInputStream(file), encoding);// 考虑到编码格式  
    201.                 BufferedReader bufferedReader = new BufferedReader(read);  
    202.                 String lineTxt = null;  
    203.                 while ((lineTxt = bufferedReader.readLine()) != null) {  
    204.                     return lineTxt;  
    205.                 }  
    206.                 read.close();  
    207.             } else {  
    208.                 System.out.println("找不到指定的文件");  
    209.             }  
    210.         } catch (Exception e) {  
    211.             System.out.println("读取文件内容出错");  
    212.             e.printStackTrace();  
    213.         }  
    214.         return "";  
    215.     }  
    216. }  


    下面这个类PageData为扩展使用,目前暂未使用

    [java]  view plain  copy
     
    1. package com.ssm.util;  
    2.   
    3. import java.util.Collection;  
    4. import java.util.HashMap;  
    5. import java.util.Iterator;  
    6. import java.util.Map;  
    7. import java.util.Set;  
    8.   
    9. import javax.servlet.http.HttpServletRequest;  
    10.   
    11. public class PageData extends HashMap implements Map{  
    12.     private static final long serialVersionUID = 1L;  
    13.     Map map = null;  
    14.     HttpServletRequest request;  
    15.       
    16.     //获取请求参数和请求参数值的map  
    17.     public PageData(HttpServletRequest request){  
    18.         this.request = request;  
    19.         Map properties = request.getParameterMap();  
    20.         Map returnMap = new HashMap();   
    21.         Iterator entries = properties.entrySet().iterator();   
    22.         Map.Entry entry;   
    23.         String name = "";    
    24.         String value = "";    
    25.         while (entries.hasNext()) {  
    26.             entry = (Map.Entry) entries.next();   
    27.             name = (String) entry.getKey();   
    28.             Object valueObj = entry.getValue();   
    29.             if(null == valueObj){   
    30.                 value = "";   
    31.             }else if(valueObj instanceof String[]){   
    32.                 String[] values = (String[])valueObj;  
    33.                 for(int i=0;i
    34.                      value = values[i] + ",";  
    35.                 }  
    36.                 value = value.substring(0, value.length()-1);   
    37.             }else{  
    38.                 value = valueObj.toString();   
    39.             }  
    40.             returnMap.put(name, value);   
    41.         }  
    42.         map = returnMap;  
    43.     }  
    44.       
    45.     public PageData() {  
    46.         map = new HashMap();  
    47.     }  
    48.       
    49.     @Override  
    50.     public Object get(Object key) {  
    51.         Object obj = null;  
    52.         if(map.get(key) instanceof Object[]) {  
    53.             Object[] arr = (Object[])map.get(key);  
    54.             obj = request == null ? arr:(request.getParameter((String)key) == null ? arr:arr[0]);  
    55.         } else {  
    56.             obj = map.get(key);  
    57.         }  
    58.         return obj;  
    59.     }  
    60.       
    61.     public String getString(Object key) {  
    62.         return (String)get(key);  
    63.     }  
    64.       
    65.     @SuppressWarnings("unchecked")  
    66.     @Override  
    67.     public Object put(Object key, Object value) {  
    68.         return map.put(key, value);  
    69.     }  
    70.       
    71.     @Override  
    72.     public Object remove(Object key) {  
    73.         return map.remove(key);  
    74.     }  
    75.   
    76.     public void clear() {  
    77.         map.clear();  
    78.     }  
    79.   
    80.     public boolean containsKey(Object key) {  
    81.         return map.containsKey(key);  
    82.     }  
    83.   
    84.     public boolean containsValue(Object value) {  
    85.         return map.containsValue(value);  
    86.     }  
    87.   
    88.     public Set entrySet() {  
    89.         return map.entrySet();  
    90.     }  
    91.   
    92.     public boolean isEmpty() {  
    93.         return map.isEmpty();  
    94.     }  
    95.   
    96.     public Set keySet() {  
    97.         return map.keySet();  
    98.     }  
    99.   
    100.     @SuppressWarnings("unchecked")  
    101.     public void putAll(Map t) {  
    102.         map.putAll(t);  
    103.     }  
    104.   
    105.     public int size() {  
    106.         return map.size();  
    107.     }  
    108.   
    109.     public Collection values() {  
    110.         return map.values();  
    111.     }  
    112. }  

    接下来可根据page定义一个更加具体的页面和后端传输的页面封装类,如

    [java]  view plain  copy
     
    1. import java.io.Serializable;  
    2. import java.util.List;  
    3.   
    4. public class XXXPage extends Page implements Serializable{  
    5.     private String identity_type;  
    6.     private String username;  
    7.     private String name;  
    8.     private String city;  
    9.     private List freeTimeList;  
    10.     private String[] jobType;  
    11.     private List createdTimeList;  
    12.     ********************************  
    13.     public String getIdentity_type() {  
    14.         return identity_type;  
    15.     }  
    16.     public void setIdentity_type(String identity_type) {  
    17.         this.identity_type = identity_type;  
    18.     }  
    19. }  

    下一步可在controller的action中使用 如

    public String listPageData(Model model, XXXPage page,HttpServletRequest request) {

    xxxxxxxxx;

    }
    并在传回客户端时可 model.addAttribute("page", page);


    其中 mybatis中操作

    List list = userMapper.findXXXByPage(page);//得到满足条件的招聘用户列表
    int rows = xxxMapper.findRows(page);//得到满足条件的行数

    page.setRows(rows);

    只需要在mapper中sql中 进行sql分页  limit  #{begin,jdbcType=INTEGER},#{showCount,jdbcType=INTEGER} 即可。

    分页方法3:

    修改mybatis自带的rowbound内存分页为物理分页

    新建类Page_duan 

    [java]  view plain  copy
     
    1. import java.util.List;  
    2. import java.util.Map;  
    3. import org.codehaus.jackson.map.ObjectMapper;  
    4. import org.slf4j.Logger;  
    5. import org.slf4j.LoggerFactory;  
    6. import com.google.common.base.Joiner;  
    7. import com.google.common.collect.Lists;  
    8. import com.google.common.collect.Maps;  
    9.   
    10. public class Page_duan {  
    11.     private static final long serialVersionUID = -399284318168302833L;    
    12.     private static final Logger logger = LoggerFactory  
    13.             .getLogger(Page_duan.class);  
    14.     private static ObjectMapper mapper = new ObjectMapper();  
    15.     public static String DEFAULT_PAGESIZE = "10";  
    16.     private int pageNo; // 当前页码  
    17.     private int pageSize; // 每页行数  
    18.     private int totalRecord; // 总记录数  
    19.     private int totalPage; // 总页数  
    20.     private Map params; // 查询条件  
    21.     private Map> paramLists; // 数组查询条件  
    22.     private String searchUrl; // Url地址  
    23.     private String pageNoDisp; // 可以显示的页号(分隔符"|",总页数变更时更新)  
    24.   
    25.     private Page_duan() {  
    26.         pageNo = 1;  
    27.         pageSize = Integer.valueOf(DEFAULT_PAGESIZE);  
    28.         totalRecord = 0;  
    29.         totalPage = 0;  
    30.         params = Maps.newHashMap();  
    31.         paramLists = Maps.newHashMap();  
    32.         searchUrl = "";  
    33.         pageNoDisp = "";  
    34.     }  
    35.   
    36.     public int getPageNo() {  
    37.         return pageNo;  
    38.     }  
    39.   
    40.     public void setPageNo(int pageNo) {  
    41.         this.pageNo = pageNo;  
    42.     }  
    43.   
    44.     public int getPageSize() {  
    45.         return pageSize;  
    46.     }  
    47.   
    48.     public void setPageSize(int pageSize) {  
    49.         this.pageSize = pageSize;  
    50.     }  
    51.   
    52.     public int getTotalRecord() {  
    53.         return totalRecord;  
    54.     }  
    55.   
    56.     public void setTotalRecord(int totalRecord) {  
    57.         this.totalRecord = totalRecord;  
    58.         refreshPage();  
    59.     }  
    60.   
    61.     public int getTotalPage() {  
    62.         return totalPage;  
    63.     }  
    64.   
    65.     public void setTotalPage(int totalPage) {  
    66.         this.totalPage = totalPage;  
    67.     }  
    68.   
    69.     public Map getParams() {  
    70.         return params;  
    71.     }  
    72.   
    73.     public void setParams(Map params) {  
    74.         this.params = params;  
    75.     }  
    76.   
    77.     public Map> getParamLists() {  
    78.         return paramLists;  
    79.     }  
    80.   
    81.     public void setParamLists(Map> paramLists) {  
    82.         this.paramLists = paramLists;  
    83.     }  
    84.   
    85.     public String getSearchUrl() {  
    86.         return searchUrl;  
    87.     }  
    88.   
    89.     public void setSearchUrl(String searchUrl) {  
    90.         this.searchUrl = searchUrl;  
    91.     }  
    92.   
    93.     public String getPageNoDisp() {  
    94.         return pageNoDisp;  
    95.     }  
    96.   
    97.     public void setPageNoDisp(String pageNoDisp) {  
    98.         this.pageNoDisp = pageNoDisp;  
    99.     }  
    100.   
    101.     public static Page_duan newBuilder(int pageNo, int pageSize, String url) {  
    102.         Page_duan page = new Page_duan();  
    103.         page.setPageNo(pageNo);  
    104.         page.setPageSize(pageSize);  
    105.         page.setSearchUrl(url);  
    106.         return page;  
    107.     }  
    108.   
    109.     /** 
    110.      * 查询条件转JSON 
    111.      */  
    112.     public String getParaJson() {  
    113.         Map map = Maps.newHashMap();  
    114.         for (String key : params.keySet()) {  
    115.             if (params.get(key) != null) {  
    116.                 map.put(key, params.get(key));  
    117.             }  
    118.         }  
    119.         String json = "";  
    120.         try {  
    121.             json = mapper.writeValueAsString(map);  
    122.         } catch (Exception e) {  
    123.             logger.error("转换JSON失败", params, e);  
    124.         }  
    125.         return json;  
    126.     }  
    127.   
    128.     /** 
    129.      * 数组查询条件转JSON 
    130.      */  
    131.     public String getParaListJson() {  
    132.         Map map = Maps.newHashMap();  
    133.         for (String key : paramLists.keySet()) {  
    134.             List lists = paramLists.get(key);  
    135.             if (lists != null && lists.size() > 0) {  
    136.                 map.put(key, lists);  
    137.             }  
    138.         }  
    139.         String json = "";  
    140.         try {  
    141.             json = mapper.writeValueAsString(map);  
    142.         } catch (Exception e) {  
    143.             logger.error("转换JSON失败", params, e);  
    144.         }  
    145.         return json;  
    146.     }  
    147.   
    148.     /** 
    149.      * 总件数变化时,更新总页数并计算显示样式 
    150.      */  
    151.     private void refreshPage() {  
    152.         // 总页数计算  
    153.         totalPage = totalRecord % pageSize == 0 ? totalRecord / pageSize  
    154.                 : (totalRecord / pageSize + 1);  
    155.         // 防止超出最末页(浏览途中数据被删除的情况)  
    156.         if (pageNo > totalPage && totalPage != 0) {  
    157.             pageNo = totalPage;  
    158.         }  
    159.         pageNoDisp = computeDisplayStyleAndPage();  
    160.     }  
    161.   
    162.     /** 
    163.      * 计算页号显示样式 这里实现以下的分页样式("[]"代表当前页号),可根据项目需求调整 [1],2,3,4,5,6,7,8..12,13 
    164.      * 1,2..5,6,[7],8,9..12,13 1,2..6,7,8,9,10,11,12,[13] 
    165.      */  
    166.     private String computeDisplayStyleAndPage() {  
    167.         List pageDisplays = Lists.newArrayList();  
    168.         if (totalPage <= 11) {  
    169.             for (int i = 1; i <= totalPage; i++) {  
    170.                 pageDisplays.add(i);  
    171.             }  
    172.         } else if (pageNo < 7) {  
    173.             for (int i = 1; i <= 8; i++) {  
    174.                 pageDisplays.add(i);  
    175.             }  
    176.             pageDisplays.add(0);// 0 表示 省略部分(下同)  
    177.             pageDisplays.add(totalPage - 1);  
    178.             pageDisplays.add(totalPage);  
    179.         } else if (pageNo > totalPage - 6) {  
    180.             pageDisplays.add(1);  
    181.             pageDisplays.add(2);  
    182.             pageDisplays.add(0);  
    183.             for (int i = totalPage - 7; i <= totalPage; i++) {  
    184.                 pageDisplays.add(i);  
    185.             }  
    186.         } else {  
    187.             pageDisplays.add(1);  
    188.             pageDisplays.add(2);  
    189.             pageDisplays.add(0);  
    190.             for (int i = pageNo - 2; i <= pageNo + 2; i++) {  
    191.                 pageDisplays.add(i);  
    192.             }  
    193.             pageDisplays.add(0);  
    194.             pageDisplays.add(totalPage - 1);  
    195.             pageDisplays.add(totalPage);  
    196.         }  
    197.         return Joiner.on("|").join(pageDisplays.toArray());  
    198.     }  
    199.   
    200. }  

    新建如下类

    [java]  view plain  copy
     
    1. import java.util.Properties;  
    2. import org.apache.ibatis.plugin.Interceptor;  
    3. import org.apache.ibatis.plugin.Invocation;  
    4. import java.sql.Connection;    
    5. import java.sql.PreparedStatement;    
    6. import java.sql.ResultSet;    
    7. import java.util.Properties;    
    8. import org.apache.commons.jxpath.JXPathContext;    
    9. import org.apache.commons.jxpath.JXPathNotFoundException;    
    10. import org.apache.ibatis.executor.Executor;    
    11. import org.apache.ibatis.executor.parameter.DefaultParameterHandler;    
    12. import org.apache.ibatis.mapping.BoundSql;    
    13. import org.apache.ibatis.mapping.MappedStatement;    
    14. import org.apache.ibatis.mapping.MappedStatement.Builder;    
    15. import org.apache.ibatis.mapping.ParameterMapping;    
    16. import org.apache.ibatis.mapping.SqlSource;    
    17. import org.apache.ibatis.plugin.Interceptor;    
    18. import org.apache.ibatis.plugin.Intercepts;    
    19. import org.apache.ibatis.plugin.Invocation;    
    20. import org.apache.ibatis.plugin.Plugin;    
    21. import org.apache.ibatis.plugin.Signature;    
    22. import org.apache.ibatis.session.ResultHandler;    
    23. import org.apache.ibatis.session.RowBounds;  
    24.   
    25. @Intercepts({@Signature(type=Executor.class,method="query",  
    26. args={ MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class })})    
    27. public class PageHelper_duan implements Interceptor {  
    28.   
    29.     @Override  
    30.     public Object intercept(Invocation invocation) throws Throwable {    
    31.             
    32.         //当前环境 MappedStatement,BoundSql,及sql取得    
    33.         MappedStatement mappedStatement=(MappedStatement)invocation.getArgs()[0];        
    34.         Object parameter = invocation.getArgs()[1];     
    35.         BoundSql boundSql = mappedStatement.getBoundSql(parameter);     
    36.         String originalSql = boundSql.getSql().trim();    
    37.         Object parameterObject = boundSql.getParameterObject();    
    38.         
    39.         //Page对象获取,“信使”到达拦截器!    
    40.         Page_duan page = searchPageWithXpath(boundSql.getParameterObject(),".","page","*/page");    
    41.         
    42.         if(page!=null ){    
    43.           //Page对象存在的场合,开始分页处理    
    44.           String countSql = getCountSql(originalSql);    
    45.           Connection connection=mappedStatement.getConfiguration()  
    46.                             .getEnvironment().getDataSource().getConnection()  ;              
    47.           PreparedStatement countStmt = connection.prepareStatement(countSql);      
    48.           BoundSql countBS = copyFromBoundSql(mappedStatement, boundSql, countSql);    
    49.           DefaultParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, countBS);    
    50.           parameterHandler.setParameters(countStmt);    
    51.           ResultSet rs = countStmt.executeQuery();    
    52.           int totpage=0;    
    53.           if (rs.next()) {      
    54.             totpage = rs.getInt(1);      
    55.           }    
    56.           rs.close();      
    57.           countStmt.close();      
    58.           connection.close();    
    59.               
    60.           //分页计算    
    61.           page.setTotalRecord(totpage);    
    62.           //对原始Sql追加limit    
    63.           int offset = (page.getPageNo() - 1) * page.getPageSize();    
    64.           StringBuffer sb = new StringBuffer();    
    65.           sb.append(originalSql).append(" limit ").append(offset).append(",").append(page.getPageSize());    
    66.           BoundSql newBoundSql = copyFromBoundSql(mappedStatement, boundSql, sb.toString());    
    67.           MappedStatement newMs = copyFromMappedStatement(mappedStatement,new BoundSqlSqlSource(newBoundSql));      
    68.           invocation.getArgs()[0]= newMs;      
    69.         }    
    70.         return invocation.proceed();    
    71.             
    72.       }    
    73.   
    74.       
    75.       
    76.     /**  
    77.        * 根据给定的xpath查询Page对象  
    78.        */    
    79.       private Page_duan searchPageWithXpath(Object o,String... xpaths) {    
    80.         JXPathContext context = JXPathContext.newContext(o);    
    81.         Object result;    
    82.         for(String xpath : xpaths){    
    83.           try {    
    84.             result = context.selectSingleNode(xpath);    
    85.           } catch (JXPathNotFoundException e) {    
    86.             continue;    
    87.           }    
    88.           if ( result instanceof Page_duan ){    
    89.             return (Page_duan)result;    
    90.           }    
    91.         }    
    92.         return null;    
    93.       }    
    94.         
    95.       /**  
    96.        * 复制MappedStatement对象  
    97.        */    
    98.       private MappedStatement copyFromMappedStatement(MappedStatement ms,SqlSource newSqlSource) {    
    99.         Builder builder = new Builder(ms.getConfiguration(),ms.getId(),newSqlSource,ms.getSqlCommandType());    
    100.             
    101.         builder.resource(ms.getResource());    
    102.         builder.fetchSize(ms.getFetchSize());    
    103.         builder.statementType(ms.getStatementType());    
    104.         builder.keyGenerator(ms.getKeyGenerator());   
    105.         for(String pro : ms.getKeyProperties())  
    106.             builder.keyProperty(pro);   
    107.         builder.timeout(ms.getTimeout());    
    108.         builder.parameterMap(ms.getParameterMap());    
    109.         builder.resultMaps(ms.getResultMaps());    
    110.         builder.resultSetType(ms.getResultSetType());    
    111.         builder.cache(ms.getCache());    
    112.         builder.flushCacheRequired(ms.isFlushCacheRequired());    
    113.         builder.useCache(ms.isUseCache());    
    114.         return builder.build();    
    115.       }    
    116.         
    117.       /**  
    118.        * 复制BoundSql对象  
    119.        */    
    120.       private BoundSql copyFromBoundSql(MappedStatement ms, BoundSql boundSql, String sql) {    
    121.         BoundSql newBoundSql = new BoundSql(ms.getConfiguration(),sql, boundSql.getParameterMappings(), boundSql.getParameterObject());    
    122.         for (ParameterMapping mapping : boundSql.getParameterMappings()) {    
    123.             String prop = mapping.getProperty();    
    124.             if (boundSql.hasAdditionalParameter(prop)) {    
    125.                 newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop));    
    126.             }    
    127.         }    
    128.         return newBoundSql;    
    129.       }    
    130.         
    131.       /**  
    132.        * 根据原Sql语句获取对应的查询总记录数的Sql语句  
    133.        */    
    134.       private String getCountSql(String sql) {    
    135.         return "SELECT COUNT(*) FROM (" + sql + ") aliasForPage";    
    136.       }    
    137.         
    138.       public class BoundSqlSqlSource implements SqlSource {      
    139.           BoundSql boundSql;      
    140.           public BoundSqlSqlSource(BoundSql boundSql) {      
    141.             this.boundSql = boundSql;      
    142.           }      
    143.           public BoundSql getBoundSql(Object parameterObject) {      
    144.             return boundSql;      
    145.           }      
    146.         }      
    147.       @Override  
    148.       public Object plugin(Object arg0) {    
    149.          return Plugin.wrap(arg0, this);    
    150.       }  
    151.   
    152.   
    153.   
    154.     @Override  
    155.     public void setProperties(Properties arg0) {  
    156.         // TODO Auto-generated method stub  
    157.           
    158.     }    
    159.   
    160. }  
    java,架构技术学习 欢迎加QQ群交流: 368614849 14

    你可能感兴趣的:(技术分析总结)