Mybatis單表分頁查詢

本文以user表為例來記錄一種Mybatis單表分頁查詢實現。
文中關于擴展文件的內容請參考:Spring Boot整合Mybatis框架在擴展文件編寫自己的sql語句

1、在擴展查詢接口基類BaseMapperExt.java中定義單表查詢接口,但是針對某張表一定要有對應的擴展Mapper類繼承它,比如要實現user表分頁查詢,一定要有接口類UserMapperExt.java繼承BaseMapperExt.java,然后還要有與之對應的UserMapperExt.xml,具體請看下文。

package com.beibei.doc.dao.base;

import java.util.List;
import com.beibei.doc.util.Page;

/**
 * 擴展基類
 * @author beibei
 *
 * @param <M> 實體類
 * @param <E> 實體類對應的example類
 */
public interface BaseMapperExt<M, E> {

/**
 * 單表分頁查詢
 * @param page
 *            分頁對象
 * @return
 * @throws Exception
 */
public List<M> selectByExampleListPage(Page<M, E> page);

}

2、讓UserMapperExt類繼承BaseMapperExt,并且將泛型設置為User, UserExample類

package com.beibei.doc.dao.user.ext;

import com.beibei.doc.dao.base.BaseMapperExt;
import com.beibei.doc.model.user.User;
import com.beibei.doc.model.user.UserExample;

public interface UserMapperExt extends BaseMapperExt<User, UserExample> {

}

3、在與UserMapperExt.java類對應的擴展文件UserMapperExt.xml中加入分頁查詢代碼。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.beibei.doc.dao.user.ext.UserMapperExt" >
  <resultMap id="ExtResultMap" extends="com.beibei.doc.dao.user.UserMapper.BaseResultMap" type="com.beibei.doc.model.user.User" >

  </resultMap>

  <select id="selectByExampleListPage" resultMap="ExtResultMap" parameterType="com.beibei.doc.util.Page">
    select
    <include refid="com.beibei.doc.dao.user.UserMapper.Base_Column_List" />
    from user
    <if test="_parameter != null">
        <include refid="com.beibei.doc.dao.user.UserMapper.Update_By_Example_Where_Clause" />
    </if>
    <if test="orderBy != null">
        order by ${orderBy}
    </if>
    <if test="limit != null">
        limit ${start} , ${limit}
    </if>
    </select>

</mapper>

至此,我們已經在dao層有了分頁查詢的方法,接下來介紹怎么在業務層實現分頁查詢。

4、創建分頁輔助類Page.java,這個類至關重要,基本上關于分頁的核心邏輯都封裝在這個類里。

package com.beibei.doc.util;

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

/**
 * 分頁輔助類
 * @author beibei
 *
 * @param <M> 查詢結果對應的實體類
 * @param <E> 單表對應的example
 */
public class Page<M, E> implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = 1959424260780112289L;


public Page() {
    
}

/**
 * 初始化nextPage和limit
 * @param param --分頁查詢參數map
 */
public Page(Map<String, Object> param) {
    String limitStr = StringUtil.getStr(param.get("limit"));
    if(!"".equals(limitStr)){
        this.limit = StringUtil.getInt(param.get("limit"));
        this.nextPage = StringUtil.getInt(param.get("nextPage"));
    }
}

/** 每頁默認顯示數據條數 */
public static int defaultLimit = 20;

/**是否 distinct */
private boolean distinct = false;

/** 
 * 下一頁碼,如需要當前頁碼則該屬性減1 
 */
private int nextPage;

/** 
 * 每頁顯示記錄數
 */
private Integer limit;

/** 
 * 起始記錄,因為引用的時候不會調用其get方法,因此要通過調用
 */
private int start;

/** 
 * 排序
 */
private String orderBy;

/**
 * 查詢參數
 */
private String search;

/**
 * example查詢參數
 */
private E example;

/**
 * 其它查詢參數,適用于聯表查詢時候設置條件參數
 */
private Map<String, Object> map = new HashMap<String, Object>();

/**
 * 記錄總數
 */
private long total;

/**
 * 總頁數
 */
private int pages;

/**
 * 查詢結果列表
 */
private List<M> list;

public boolean isDistinct() {
    return distinct;
}
public void setDistinct(boolean distinct) {
    this.distinct = distinct;
}

/**
 * 獲取下一頁頁碼必須先初始化:nextPage、limit、total
 * @return
 */
public int getNextPage() {
    if(limit == null){
        return 0;
    }
    if(nextPage*limit >= total){
        return 0;
    } else {
        return nextPage+1;
    }
}
public void setNextPage(int nextPage) {
    this.nextPage = nextPage;
}

public Integer getLimit() {
    return limit;
}
public void setLimit(Integer limit) {
    this.limit = limit;
}

public int getStart() {
    if(this.nextPage < 1){
        this.nextPage = 1;
    }
    if(limit == null){
        return 0;
    }
    this.start = (nextPage - 1) * limit;
    return start;
}
/**
 * 查詢頁起始記錄,分頁查詢必須設置起始頁
 * @param start
 */
public void setStart(int start) {
    this.start = start;
}

public String getOrderBy() {
    return orderBy;
}
/**
 * <pre>
 * 設置排序方式
 * 嚴格按照sql語句關鍵詞 ORDER BY 后面的排序字段和順序編寫
 * 例如:
 *     以 username 和 age 兩個字段的倒序排序, 
 *     應該給orderBy賦值  username DESC, age DESC
 * </pre>
 * @param order
 */
public void setOrderBy(String orderBy) {
    if(orderBy != null){
        orderBy = " " + orderBy + " ";//加空格
    }
    this.orderBy = orderBy;
}

public String getSearch() {
    return search;
}
public void setSearch(String search) {
    this.search = search;
}

public E getExample() {
    return example;
}
public void setExample(E example) {
    this.example = example;
}

/**
 * 其它過濾參數,適用于個性化參數查詢
 * @return
 */
public Map<String, Object> getMap() {
    return map;
}
/**
 * 其它過濾參數,適用于個性化參數查詢
 * @param map
 */
public void setMap(Map<String, Object> map) {
    this.map = map;
}

public long getTotal() {
    return total;
}
public void setTotal(long total) {
    this.total = total;
}

/**
 * 返回總頁數
 * @return
 */
public int getPages() {
    this.pages = 1;
    if(this.limit != null && limit > 0){
        int a = (int) (this.total / this.limit);
        int b = (int) (this.total % this.limit);
        if(b > 0){
            pages = a + 1;
        } else {
            pages = a;
        }
    }
    return pages;
}

public void setPages(int pages) {
    this.pages = pages;
}

public List<M> getList() {
    return list;
}
public void setList(List<M> list) {
    this.list = list;
}

/**
 * <pre>
 * 獲取分頁查詢結果,數據結構如下
 * {
 *       "total": 4,    數據總量
 *       "nextPage": 0, 下一頁頁碼,沒有下一頁值為 0
 *       "limit": 3,    每頁數量
 *       "list": [      查詢結果列表
 *       
 *       ]
 * }
 * </pre>
 * 
 * @return
 */
public Map<String, Object> getPageData(){
    Map<String, Object> data = new HashMap<>();
    data.put("nextPage", this.getNextPage());
    data.put("total", this.getTotal());
    data.put("limit", this.getLimit());
    data.put("list", this.getList());
    return data;
}

@Override
public String toString() {
    return "Page [distinct=" + distinct + ", limit=" + limit + ", start="
            + start + ", orderBy=" + orderBy + ", nextPage=" + nextPage
            + ", total=" + total + ", pages=" + pages
            + ", search=" + search + ", example=" + example + ", map="
            + map + "]";
}
}

5、在BaseService.java中加入單表分頁查詢接口的定義

/**
 * 單表分頁查詢
 * @param page
 * @return
 */
public Page<M, E> selectByExampleListPage(Page<M, E> page);

/**
 * 分頁查詢
 * @param param
 * @return
 */
public RespData selectListPage(Map<String, Object> param);

6、在BaseServiceImpl.java中實現selectByExampleListPage接口,在這里封裝對dao層數據庫查詢。

@Autowired
protected BaseMapperExt<M, E> baseMapperExt;
@Override
public Page<M, E> selectByExampleListPage(Page<M, E> page) {
    //查詢數據總數
    Integer total = this.countByExample(page.getExample());
    
    //設置數據總數
    page.setTotal(total);
    List<M> list = this.baseMapperExt.selectByExampleListPage(page);
    page.setList(list);
    return page;
}

7、讓UserService.java接口類繼承BaseService.java

UserService.java

package com.beibei.doc.service.user;

import com.beibei.doc.model.user.User;
import com.beibei.doc.model.user.UserExample;
import com.beibei.doc.service.base.BaseService;

public interface UserService extends BaseService<User, UserExample> {

}

8、讓UserServiceImpl.java類繼承BaseServiceImpl.java,并且實現selectListPage接口。

package com.beibei.doc.service.user.impl;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.beibei.doc.dao.user.ext.UserMapperExt;
import com.beibei.doc.model.user.User;
import com.beibei.doc.model.user.UserExample;
import com.beibei.doc.model.user.UserExample.Criteria;
import com.beibei.doc.service.base.impl.BaseServiceImpl;
import com.beibei.doc.service.user.UserService;
import com.beibei.doc.util.Page;
import com.beibei.doc.util.RespData;

@Service
public class UserServiceImpl extends BaseServiceImpl<User, UserExample> implements UserService {

@Autowired
private UserMapperExt userMapperExt;

@Override
public RespData selectListPage(Map<String, Object> param) {
    RespData data = new RespData();
    
    //構建分頁查詢對象
    Page<User, UserExample> page = new Page<>(param);
    
    //設置查詢條件
    UserExample example = new UserExample();
    Criteria criteria = example.createCriteria();
    criteria.andAgeEqualTo(18);
    
    //設置分頁數據
    page.setOrderBy("id desc");
    page.setExample(example);
    
    //執行查詢提取結果
    page = this.selectByExampleListPage(page);
    Map<String, Object> result = page.getPageData();
    data.setData(result);
    
    return data;
}
}

至此,就可以在Controller中調用分頁查詢接口對user表數據進行分頁查詢了,特別注意兩個參數:nextPage是查詢頁碼,從1開始;limit是每頁數量,如果不傳會默認查詢全部。

@RequestMapping(value="/list")
public RespData list(@RequestParam Map<String, Object> param){
    RespData data = this.userService.selectListPage(param);
    return data;
}

最后,文中各個文件目錄結構如下圖

Paste_Image.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,765評論 18 399
  • 一. Java基礎部分.................................................
    wy_sure閱讀 3,835評論 0 11
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,923評論 18 139
  • 昨天結束了自己的2017研究生入學考試初試,走出考場的時候,自己蠻平靜的,倒不是自己考的好,而且自己考的太差了,...
    hallelujah666閱讀 211評論 0 2
  • 時代變了,你如何跟上節奏? 風口變了,你如何把握機遇? 玩法變了,你如何應對自如? 2017年的微商第一步我們要以...
    肖紅千金閱讀 436評論 0 0