不少人在使用MyBatis时,涉及分页会使用PageHelper分页工具。在只对单表或者一对一的情况下,PageHelper确实挺简单方便的,但在一对多的多表联表查询时,却会出现某些问题,可以查看这篇文章。

相比使用PageHelper分页工具,我们可以采取更加保险的原始分页(虽然相对会麻烦点,但却是最靠谱的),而且只需进行两次数据库查询,节省开销。

关于分页,其实最关键是获取选取页的如果数据以及总记录数。

案例:

三张表的初始数据:
老师表

CREATE TABLE `teacher`  (`tid` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',`tname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '老师名字',PRIMARY KEY (`tid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES (1, '张老师');
INSERT INTO `teacher` VALUES (2, '李老师');
INSERT INTO `teacher` VALUES (3, '王老师');SET FOREIGN_KEY_CHECKS = 1;

班级表

CREATE TABLE `class`  (`cid` int(11) NOT NULL AUTO_INCREMENT COMMENT '班级id',`cname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '班级名称',`tid` int(11) NOT NULL COMMENT '老师id',PRIMARY KEY (`cid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of class
-- ----------------------------
INSERT INTO `class` VALUES (1, '文一班', 1);
INSERT INTO `class` VALUES (2, '文二班', 1);
INSERT INTO `class` VALUES (3, '理一班', 2);
INSERT INTO `class` VALUES (4, '理二班', 2);SET FOREIGN_KEY_CHECKS = 1;

学生表

CREATE TABLE `student`  (`sid` int(11) NOT NULL COMMENT '学生id',`sname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '学生名字',`cid` int(11) NOT NULL COMMENT '班级id',PRIMARY KEY (`sid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '麦兜', 1);
INSERT INTO `student` VALUES (2, '麦唛', 1);
INSERT INTO `student` VALUES (3, '阿May', 2);
INSERT INTO `student` VALUES (4, '得巴', 3);
INSERT INTO `student` VALUES (5, '阿辉', 4);SET FOREIGN_KEY_CHECKS = 1;

三者关系:老师一对多班级,班级一对多学生
需求:根据条件查出老师以及老师所拥有的学生(注意老师是主表)
所有数据:

代码(只贴关键部分):
分页PageInfo自定义分装类(用于接收封装返回的数据,可根据自己的实际需要添加一些字段);

import java.util.List;public class PageInfo<T> {protected int pageNum = 1;//页码protected int pageSize = 10;//返回条数protected long totalRecord = -1;//总记录数protected int totalPage = -1;//总页数protected int startIndex = 0; //第几条记录开始protected List<T> resultList;//结果集public PageInfo() {}public PageInfo(int pageSize, int pageNum) {this.pageSize = pageSize;this.pageNum = pageNum;}public PageInfo(Integer pageNum) {if (pageNum != null) {this.pageNum = pageNum.intValue();}}public int getPageNum() {return pageNum;}public void setPageNum(int pageNum) {this.pageNum = pageNum;setPageSize(this.pageSize);}public int getPageSize() {return pageSize;}public void setPageSize(int pageSize) {this.pageSize = pageSize;computeTotalPage();}public long getTotalRecord() {return totalRecord;}public int getTotalPage() {return totalPage;}public void setTotalRecord(long totalRecord) {this.totalRecord = totalRecord;computeTotalPage();}public int getStartIndex() {return (pageNum - 1) * pageSize;}protected void computeTotalPage() {if (getPageSize() > 0 && getTotalRecord() > -1) {this.totalPage = (int) (getTotalRecord() % getPageSize() == 0 ? getTotalRecord()/ getPageSize(): getTotalRecord() / getPageSize() + 1);}if (this.totalPage == 0) {this.totalPage = 1;}}public List<T> getResultList() {return resultList;}public void setResultList(List<T> resultList) {this.resultList = resultList;}}

service层(封装选取页的结果数据以及总记录数):

@Service
public class TeacherService {@ResourceTeacherMapper teacherMapper;public PageInfo selectListByPageOriginal(PageParam pageParam) {// mysql的limit分页语句:  limit startIndex, pageSize// 所以需要传的参数是startIndex和pageSizeList<TeacherDto> resultList = teacherMapper.selectListByPageOriginal((pageParam.getPageNum()-1)*pageParam.getPageSize(), pageParam.getPageSize());Integer totalRecord = teacherMapper.selectTtoal();PageInfo pageInfo = new PageInfo();pageInfo.setPageNum(pageParam.getPageNum());pageInfo.setPageSize(pageParam.getPageSize());pageInfo.setTotalRecord(totalRecord);pageInfo.setResultList(resultList);return pageInfo;}
}

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.example.page.dao.TeacherMapper"><resultMap id="TeacherDtoMap" type="com.example.page.dto.TeacherDto"><id column="tid" jdbcType="INTEGER" property="tid" /><result column="tname" jdbcType="VARCHAR" property="tname" /><collection property="classDtoList" resultMap="classDtoMap" javaType="java.util.List"></collection></resultMap><resultMap id="classDtoMap" type="com.example.page.dto.ClassDto"><id column="cid" jdbcType="INTEGER" property="cid" /><result column="tid" jdbcType="INTEGER" property="tid" /><result column="cname" jdbcType="VARCHAR" property="cname" /><collection property="studentDtoList" ofType="com.example.page.dto.StudentDto" javaType="java.util.List"><id column="sid" jdbcType="INTEGER" property="sid" /><result column="cid" jdbcType="INTEGER" property="cid" /><result column="sname" jdbcType="VARCHAR" property="sname" /></collection></resultMap><select id="selectListByPageOriginal" resultMap="TeacherDtoMap">SELECTt1.*, t2.cid, t2.cname, t3.sid, t3.sname FROM (SELECT * FROM teacher LIMIT #{startIndex}, #{pageSize}) t1 LEFT JOIN class t2 ON t1.tid = t2.tid LEFT JOIN student t3 ON t2.cid = t3.cid</select><select id="selectTtoal" resultType="java.lang.Integer">SELECT count(1) FROM (SELECT t1.tid FROM teacher t1 LEFT JOIN class t2 ON t1.tid = t2.tid LEFT JOIN student t3 ON t2.cid = t3.cid GROUP BY t1.tid) t4</select></mapper>

根据接口返回的结果,可看到当当前页为1,页大小为2时,会把张老师以及李老师的数据查询出来:

说明:

  1. 在一对多的情况下,选取页的结果数据需要在主表中进行limit(假如有加条件判断的,需自主去分辨是主表的条件还是从表的条件),不能放在最外面,错误的写法如
SELECT t1.*, t2.cid, t2.cname, t3.sid, t3.sname FROM teacher t1 LEFT JOIN class t2 ON t1.tid = t2.tid LEFT JOIN student t3 ON t2.cid = t3.cid  LIMIT #{startIndex}, #{pageSize}


这样是对所有join查询得出来的结果分页

正确的sql查询语句查出的结果则是以下:

  1. 获取的总记录数也应该是主表的总数(只需确保主表的主键不重复就可以了,可以通过group by主键语句或者distinct去重主键),即便有加条件判断。

更多的细节希望能举一反三,这里不做详细说明了!

MyBatis手动SQL分页相关推荐

  1. Mybatis最入门---分页查询(逻辑分页与SQL语句分页)

    [一步是咫尺,一步即天涯] 到目前为止,我们介绍的Mybatis种种查询都是一次性的查询出所有结果并返回给上层.但是,在实际开发过程中,在大量数据存在的情况下,是很少这么做的.本文,我们将从逻辑分页, ...

  2. Mybatis动态sql和分页

    mybatis动态sql 1.1 if1.2 trim1.3 foreach1.4 其他choose/set/where 动态sql代码展示 <select id="list1&quo ...

  3. mybatis动态sql及分页

    1. 动态sql简述 mybatis的动态sql语句是基于OGNL表达式的.可以方便的在sql语句中实现某些逻辑. 总体说来mybatis动态SQL语句主要有以下几类: if 语句 (简单的条件判断) ...

  4. Mybatis借助Sql语句进行分页

    实现:通过sql语句实现分页 在FcTagNumberInfoMapper接口中添加sql语句查询的方法 public List<FcTagNumberInfo> selectFcTagN ...

  5. sql注入及mybatis防止sql注入

    一.Sql 注入漏洞详解 Sql 注入产生原因及威胁: 当我们访问动态网页时, Web 服务器会向数据访问层发起 Sql 查询请求,如果权限验证通过就会执行 Sql 语句.这种网站内部直接发送的Sql ...

  6. springboot+mybatis实现数据分页(三种方式)

    项目准备 1.创建用户表 2.使用spring初始化向导快速创建项目,勾选mybatis,web,jdbc,driver 添加lombok插件 <?xml version="1.0&q ...

  7. mybatis 调用存储过程_你真的该进来了解下MyBatis的SQL工作流程了

    前言 MyBatis可能很多人都一直在用,但是MyBatis的SQL执行流程可能并不是所有人都清楚了,那么既然进来了,通读本文你将收获如下: 1.Mapper接口和映射文件是如何进行绑定的 2.MyB ...

  8. (4) hibernate增删查改+批量操作+类似Mybatis动态sql

    简介 采用spring + hibernate + freemaker+ maven搭建起来的一个hibernate增删查改和 类似mybatis动态sql查询的一个案例 增删查改demo + 动态s ...

  9. Mybatis四种分页方式

    1.数组分页 查询出全部数据,然后再list中截取需要的部分. mybatis接口 List<Student> queryStudentsByArray(); xml配置文件 <se ...

最新文章

  1. className的高效匹配
  2. 深度学习下的医学图像分析 2
  3. 2021-02-21 Python Easyocr 图片文字识别
  4. android 开发时遇到的环境问题3--eclipse整个项目工程报错
  5. 不再单打独斗?中国移动联合多企业组建医疗数据公司
  6. zookeeper专题:使用zookeeper实现分布式锁
  7. oracle只能在指定目录下访问,只安装PLSQL怎么访问远程数据库
  8. mingw gcc mysql_Windows平台mingw编译器 mysql
  9. 数学建模酶促反应matlab求解,数学建模实验指导书2011
  10. plc控制电机实验报告_基于西门子PLC电动机正反转互锁控制实验报告
  11. 在线打开.mpp文件工具备忘录
  12. vue2使用element UI中Descriptions组件的遍历问题
  13. 约束满足问题(CSPs)和规划问题(Planning)区别
  14. PUN☀️实用API
  15. 登出系统gif图标_来了!深度操作系统 20正式版——崭新视界,创无止境
  16. 可用于微信公众平台的机器人
  17. Windows 2008 R2 x64 Enterprise安装postgres (api-ms-win-crt-runtime-l1-1-0.dll、 0x80240017错误)
  18. 74HC573锁存器简单应用
  19. 阶乘末尾 0 的个数.c
  20. 上位机plc编程入门_plc编程入门-看完你就懂了

热门文章

  1. leetcode--最长回文串(C语言)
  2. php页面导入excel表格,php页面导入excel表格数据:php导入excel 怎么获取excel表格数据...
  3. 健身中心健身管理系统的设计与实现(源码+数据脚本+论文+技术文档)
  4. 切换组件echarts宽高不正常,100%变成100px问题
  5. 啊哈 算法 Java_《啊哈!算法》.啊哈磊.高清版.pdf
  6. os.system返回值大全
  7. 1.Supervised Learning with Projected Entangled Pair States
  8. 注解详解和Spring注解增强(基础内功)
  9. 解析超大JSON文件
  10. php插入语句,请教关于php中sql插入语句的问题。