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  实体类
 * @param  实体类对应的example类
 */
public interface BaseMapperExt {

/**
 * 单表分页查询
 * @param page
 *            分页对象
 * @return
 * @throws Exception
 */
public List selectByExampleListPage(Page 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 {

}

3、在与UserMapperExt.java类对应的扩展文件UserMapperExt.xml中加入分页查询代码。




  

  

  


至此,我们已经在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  查询结果对应的实体类
 * @param  单表对应的example
 */
public class Page implements Serializable {

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


public Page() {
    
}

/**
 * 初始化nextPage和limit
 * @param param --分页查询参数map
 */
public Page(Map 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 map = new HashMap();

/**
 * 记录总数
 */
private long total;

/**
 * 总页数
 */
private int pages;

/**
 * 查询结果列表
 */
private List 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;
}
/**
 * 
 * 设置排序方式
 * 严格按照sql语句关键词 ORDER BY 后面的排序字段和顺序编写
 * 例如:
 *     以 username 和 age 两个字段的倒序排序, 
 *     应该给orderBy赋值  username DESC, age DESC
 * 
* @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 getMap() { return map; } /** * 其它过滤参数,适用于个性化参数查询 * @param map */ public void setMap(Map 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 getList() { return list; } public void setList(List list) { this.list = list; } /** *
 * 获取分页查询结果,数据结构如下
 * {
 *       "total": 4,    数据总量
 *       "nextPage": 0, 下一页页码,没有下一页值为 0
 *       "limit": 3,    每页数量
 *       "list": [      查询结果列表
 *       
 *       ]
 * }
 * 
* * @return */ public Map getPageData(){ Map 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 selectByExampleListPage(Page page);

/**
 * 分页查询
 * @param param
 * @return
 */
public RespData selectListPage(Map param);

6、在BaseServiceImpl.java中实现selectByExampleListPage接口,在这里封装对dao层数据库查询。

@Autowired
protected BaseMapperExt baseMapperExt;
@Override
public Page selectByExampleListPage(Page page) {
    //查询数据总数
    Integer total = this.countByExample(page.getExample());
    
    //设置数据总数
    page.setTotal(total);
    List 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 {

}

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 implements UserService {

@Autowired
private UserMapperExt userMapperExt;

@Override
public RespData selectListPage(Map param) {
    RespData data = new RespData();
    
    //构建分页查询对象
    Page 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 result = page.getPageData();
    data.setData(result);
    
    return data;
}
}

至此,就可以在Controller中调用分页查询接口对user表数据进行分页查询了,特别注意两个参数:nextPage是查询页码,从1开始;limit是每页数量,如果不传会默认查询全部。

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

最后,文中各个文件目录结构如下图

Mybatis单表分页查询_第1张图片
Paste_Image.png

你可能感兴趣的:(Mybatis单表分页查询)