文章目录
- 1 简介
- 2 特性
- 3 环境准备
- 3.1 数据准备
- 3.2 工程依赖准备
- 3.3 代码准备
- 4 基本的CRUD
- 4.1 新增数据
- 4.2 删除数据
- 4.2.1 根据id删除
- 4.2.2 根据id批量删除
- 4.2.3 根据Map条件删除
- 4.3 修改数据
- 4.4 查询数据
- 4.4.1 根据id查询
- 4.4.2 根据id批量查询
- 4.4.3 根据map条件查询
- 4.4.4 查询全表数据
- 5 常用注解
- 5.1 @TableName注解
- 5.2 @TableId注解
- 5.3 @TableField注解
- 5.4 @TableLogic注解
- 6 条件构造器Wrapper
- 6.1 QueryWrapper
- 6.2 UpdateWrapper
- 6.3 LambdaQueryWrapper
- 6.4 LambdaUpdateWrapper
- 6.5 Condition
- 7 分页插件
1 简介
MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生(官方网址)。
2 特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分,CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
3 环境准备
要是用MyBatis-Plus我们得准备好数据库中的表数据,所需的依赖,以及部分相关代码。
3.1 数据准备
以一张简单的单表User表为例,其结构如下
id | name | age | |
---|---|---|---|
1 | Jone | 18 | test1@baomidou.com |
2 | Jack | 20 | test2@baomidou.com |
3 | Tom | 28 | test3@baomidou.com |
4 | Sandy | 21 | test4@baomidou.com |
5 | Billie | 24 | test5@baomidou.com |
对应建表语句如下
DROP TABLE IF EXISTS user;CREATE TABLE user
(id BIGINT(20) NOT NULL COMMENT '主键ID',name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',age INT(11) NULL DEFAULT NULL COMMENT '年龄',email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',PRIMARY KEY (id)
);
对应数据如下
DELETE FROM user;INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
3.2 工程依赖准备
创建一个SpringBoot工程(可以使用Spring Initializer),引入如下依赖
<dependencies><!--spring boot--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!--spring boot test--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--mybatis plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies>
注意:导入的是spring-boot-starter包而不是spring-boot-starter-web包,spring-boot-starter-web包里内嵌Tomcat依赖,而spring-boot-starter包里没有Tomcat依赖。
写一个启动类:
@SpringBootApplication
public class MybatisPlusDemoApplication {public static void main(String[] args) {SpringApplication.run(MybatisPlusDemoApplication.class,args);}
}
在application.yml中添加如下配置:
spring:datasource:url: jdbc:mysql://localhost:3306/mybatis-plus?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver# 日志中输出mybatisPlus的执行SQL语句
logging:level:com.cskaoyan.mp.mapper: debug
3.3 代码准备
在启动类上加MapperScan注解
@SpringBootApplication
@MapperScan("com.cskaoyan.mp.mapper")
public class MybatisPlusDemoApplication {public static void main(String[] args) {SpringApplication.run(MybatisPlusDemoApplication.class,args);}
}
定义user表对应的映射实体类User
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {Long id;String name;Integer age;String email;
}
定义Mapper
BaseMapper是MyBatis-Plus提供的模板mapper,其中包含了基本的CRUD方法,泛型为操作的实体类型
public interface UserMapper extends BaseMapper<User> {
}
4 基本的CRUD
定义一个用于测试的测试类,其中包含基本CRUD的代码
@SpringBootTest(classes = MybatisPlusDemoApplication.class)
@RunWith(SpringRunner.class) // 在高版本的springboot中, runwith是不用写的
public class BaseTest {
}
定义一个CRUDTest继承BaseTest,防止以后的测试类频繁加@SpringBootTest和@RunWith注解,在CRUDTest类中写测试方法进行测试。
public class CRUDTest extends BaseTest {@AutowiredUserMapper userMapper;
4.1 新增数据
@Testpublic void testInsert(){User user = new User();//user.setId(1001L);user.setName("金莲");user.setAge(35);user.setEmail("jinlian@qq.com");int affectedRows = userMapper.insert(user);System.out.println(affectedRows);System.out.println(user);}
关于insert,还有几点需要注意:
- 如果id没有指定,默认策略: id 是由mybatisPlus的内置的(雪花)算法,给我们生成的唯一id
- 如果id没有指定,那么在insert之后,mybatisPlus会给参数的user对象中的id 赋值 (相当于MyBatis中useGeneratedKeys = true)
注意: MyBatis-Plus在实现插入数据时,会默认基于雪花算法的策略生成id
4.2 删除数据
4.2.1 根据id删除
/*** 通过id删除*/
@Test
public void testDeleteById(){int affectedRows = userMapper.deleteById(1788577219342254081L);System.out.println(affectedRows);
}
4.2.2 根据id批量删除
/*** 通过id批量删除*/
@Test
public void testDeleteByIds(){List<Long> ids = Arrays.asList(5L, 1001L);int affectedRows = userMapper.deleteBatchIds(ids);System.out.println(affectedRows);
4.2.3 根据Map条件删除
注意Map中放的是where条件中包含的多个条件字段,以及条件字段对应的值(比较的关系是相等关系)
map中的key 是列名
value 是这一列对应的值
/*** 通过map删除*/
@Test
public void testDeleteByMap(){//map中的key是列名,value是这一列对应的值HashMap<String, Object> hashMap = new HashMap<>();//map中的各个条件,使用and连接hashMap.put("name","金莲");hashMap.put("age",35);int affectedRows = userMapper.deleteByMap(hashMap);System.out.println(affectedRows);
}
4.3 修改数据
/*** 改:只会修改参数的对象中不为null的列 (<if test=""></>)*/
@Test
public void testUpdate(){User user = new User();user.setId(3L);user.setName("张三丰");user.setAge(80);int affectedRows = userMapper.updateById(user);System.out.println(affectedRows);
}
4.4 查询数据
4.4.1 根据id查询
/*** 通过id来查询*/
@Test
public void testSelectById(){User user = userMapper.selectById(2L);System.out.println(user);
}
4.4.2 根据id批量查询
/*** 通过id的集合来查询*/
@Test
public void testSelectByIds(){List<Long> ids = Arrays.asList(1L, 2L, 3L);List<User> users = userMapper.selectBatchIds(ids);System.out.println(users);
}
4.4.3 根据map条件查询
/*** 通过map来查询*/
@Test
public void testSelectByMap(){//根据map集合中所设置的条件删除记录//DELETE FROM user WHERE name = ? AND age = ?HashMap<String, Object> hashMap = new HashMap<>();hashMap.put("name","张三丰");hashMap.put("age",80);List<User> users = userMapper.selectByMap(hashMap);System.out.println(users);
}
4.4.4 查询全表数据
/*** 查询所有*/
@Test
public void testSelectAll(){List<User> userList = userMapper.selectList(null);System.out.println(userList);
}
5 常用注解
5.1 @TableName注解
使用@TableName注解,定义数据库表和实体类的关系(默认情况下,会根据实体类的类名访问数据库中的表,所以如果当表名和类名相同时,不加@TableName注解,也不会报错)
@Data
@NoArgsConstructor
@AllArgsConstructor
//当一个数据库的实体对象,没有@TableName注解时,那么默认映射到和这个对象名同名的表(不区分大小写)
@TableName("t_user") //表示这个对象映射到t_user表
public class User {Long id;String name;Integer age;String email;
}
5.2 @TableId注解
使用@TableId注解,定义数据库中的主键字段和实体类中的主键属性之间的映射关系。(默认情况下,MyBatis-Plus会根据主键名来映射,映射到同名实体类属性)
@Data
@NoArgsConstructor
@AllArgsConstructor
//当一个数据库的实体对象,没有@TableName注解时,那么默认映射到和这个对象名同名的表(不区分大小写)
@TableName("t_user") //表示这个对象映射到t_user表
public class User {/*指定这个成员变量和数据库表中的主键进行映射当没有@TableId注解的时候, 会默认找 和主键这一列同名的成员变量@TableId这个注解中,还有一个属性 是 type,type就指定了生成 id的规则ASSIGN_ID: 使用MybatisPlus内置的雪花算法来生成id,这是默认的规则AUTO: 指使用数据库自增的规则,来生成idASSIGN_UUID: 使用MybatisPlus内置的策略来生成 UUID, 作为主键INPUT | NONE : 用户自己设置id雪花算法:其实就是一个 在分布式的场景下,用来生成全局唯一id的一个算法雪花算法生成的id由几部分构成:时间戳 + 数据中心的编号 + 机器的编号 + 自增的序列号444654651233242 1 1 0001mybatisPlus的源码中,雪花算法的实现:DefaultIdentifierGenerator#nextId();*/@TableId(value = "id", type = IdType.ASSIGN_ID)Long id;String name;Integer age;String email;
}
指定这个成员变量和数据库表中的主键进行映射
当没有@TableId注解的时候, 会默认找 和主键这一列同名的成员变量@TableId这个注解中,还有一个属性 是 type,type就指定了生成 id的规则
ASSIGN_ID: 使用MybatisPlus内置的雪花算法来生成id,这是默认的规则
AUTO: 指使用数据库自增的规则,来生成id
ASSIGN_UUID: 使用MybatisPlus内置的策略来生成 UUID, 作为主键
INPUT | NONE : 用户自己设置id雪花算法:其实就是一个 在分布式的场景下,用来生成全局唯一id的一个算法
雪花算法生成的id由几部分构成:
时间戳 + 数据中心的编号 + 机器的编号 + 自增的序列号
444654651233242 1 1 0001
mybatisPlus的源码中,雪花算法的实现:DefaultIdentifierGenerator#nextId();
其中,value属性指的是数据库主键字段的名称,IdType表示主键的类型。在MyBatis-Plus中主键类型有以下几种
值 | 描述 |
---|---|
AUTO | 数据库 ID 自增 |
NONE | 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT) |
INPUT | insert 前自行 set 主键值 |
ASSIGN_ID | 分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator 的方法nextId (默认实现类为DefaultIdentifierGenerator 雪花算法) |
ASSIGN_UUID | 分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator 的方法nextUUID (默认 default 方法) |
5.3 @TableField注解
类似于@TableId注解,@TableField注解在实体类中用来定义实体类中的普通属性和数据库字段的映射(默认情况下,MyBatis-Plus会根据字段名来映射,映射到同名实体类属性)
@Data
@TableName(value = "user")
public class User implements Serializable {@TableId(value = "id", type = IdType.ASSIGN_ID)private Long id;@TableField(value = "name")private String name;@TableField(value = "age")private Integer age;@TableField(value = "email")private String email;
}
@TableField注解需要注意:
- 若实体类中的属性使用的是驼峰命名风格,而表中的字段使用的是下划线命名风格(例如实体类属性userName,表中字段user_name),此时MyBatis-Plus会自动将驼峰命名风格转化为下划线命名风格
- 若实体类中的属性和表中的字段不满足上述情况,例如实体类属性name,表中字段username,此时需要在实体类属性上使用@TableField(“username”)设置属性所对应的字段名
除此之外,@TableField注解,如果我们如果不想让实体类中的某个属性,映射到数据库中的某个字段,我们可以给@TableField注解的exist属性赋值false,这样一来,在利用实体类对象的做增删改查的时候,就会忽略实体类对象的该属性值
@Data
@TableName(value = "user")
public class User implements Serializable {@TableId(value = "id", type = IdType.ASSIGN_ID)private Long id;@TableField(value = "name")private String name;// 忽略age属性,不让其映射到数据库的age字段@TableField(exist = false)private Integer age;@TableField(value = "email")private String email;
}
5.4 @TableLogic注解
为了实现逻辑删除,我们可以在表示删除状态的实体类属性上添加@TableLogic注解,从而实现逻辑删除的功能。当然,在使用之前,我们要先给数据库user表增加is_deleted属性并给该字段赋默认初值0表示未删除,以及在实体类中添加isDeleted属性。
@Data
@TableName(value = "user")
public class User implements Serializable {@TableId(value = "id", type = IdType.ASSIGN_ID)private Long id;@TableField(value = "name")private String name;@TableField(value = "age")private Integer age;@TableField(value = "email")private String email;// @TableField("is_deleted") // 这个可以不写,MybatisPlus会自动下划线转驼峰@TableLogic // 表示这个字段是一个逻辑删除的字段// 逻辑删除的字段,如果是自定义的SQL语句,MybatisPlus不会帮助我们处理private Integer isDeleted;
}
这样一来,当我们执行删除语句的时候,实际执行的就是一条set语句,比如当我们根据id删除一条记录时,实际执行的是
UPDATE user SET is_deleted=1 WHERE id=? AND is_deleted=0
当我们执行查询语句的时候,会自动附带逻辑删除状态的判断,查询结果中不会包含已经被逻辑删除的记录
SELECT id,name,age,email,is_deleted FROM user WHERE is_deleted=0
逻辑删除字段,如果是自定义SQL语句,MyBatis-Plus不会帮助处理,需要自行处理数据。
6 条件构造器Wrapper
在我们对数据库做增删改查操作的时候,往往需要附带一些条件即where条件,这些条件就是用条件构造器Wrapper来构造和表示的。
Wrapper : 条件构造抽象类,最顶端父类
AbstractWrapper : 用于查询条件的封装,生成 sql 的 where 条件
QueryWrapper : 查询条件的封装
UpdateWrapper : Update 条件封装(除了包含更新条件,还可以指定更新的字段和对应的新值)
AbstractLambdaWrapper : Lambda 语法使用的Wrapper,统一处理解析 lambda 获取 column
LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
LambdaUpdateWrapper : 用于Lambda语法使用的更新Wrapper(除了包含更新条件,还可以指定更新的字段和对应的新值)
6.1 QueryWrapper
QueryWrapper中提供了多个方法,每个方法都代表了一种条件。可以在Wrapper对象上调用多个方法,从而组装多个具体的查询条件,这些条件可以AND关系,也可以是OR关系。
调用多个方法,这些方法表示的条件默认是AND关系
/*** 查询用户名包含a,年龄在20到30之间,邮箱不为null的用户信息,并且按照年龄的升序排序* select * from user where name like '%a%' and age between 20 and 30 and email is not null order by age asc;*/@Testpublic void testQueryWrapperDemo1(){// 1. 创建一个QueryWrapperQueryWrapper<User> queryWrapper = new QueryWrapper<>();// 2. 通过queryWrapper构建条件queryWrapper.like("name","a") // likeLeft 指%在左边,likeRight指%在右边,like指%在左右两边.between("age",20,30).isNotNull("email").orderByAsc("age");// 3. 查询List<User> userList = userMapper.selectList(queryWrapper);System.out.println(userList);}
如果要想表示条件之间的OR关系,必须调用or()方法来表示OR运算符
/*** 查询用户名包含a 或者 年龄大于20,并且按照年龄的升序排序* select * from user where name like "%a%" or age > 20 order by age asc;*/@Testpublic void testQueryWrapperDemo2(){// 1. 创建一个QueryWrapperQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like("name","a").or().gt("age",20) // gt 大于 lt 小于 ge 大于等于 le 小于等于.orderByAsc("age");// 3. 查询List<User> userList = userMapper.selectList(queryWrapper);System.out.println(userList);}
除了针对where中的条件,我们还可以指定select中查询的字段
/*** 指定字段:查询用户id > 3 且 年龄在18-30之间的用户的名字* select name from user where id > 3 and age between 18 and 30;*/@Testpublic void testQueryWrapperDemo3(){// 1. 创建一个QueryWrapperQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("id",3).between("age",18,30).select("name");// 3. 查询List<User> userList = userMapper.selectList(queryWrapper);System.out.println(userList);}
当然QueryWrapper还可以使用在删除语句中,表示删除条件
/*** queryWrapper 还可以用在删除语句中,表示删除条件*SQL: delete from user where id > 3 and age between 18 and 30;*/@Testpublic void testQueryWrapperDemo4(){// 1. 创建一个QueryWrapperQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("id",3).between("age",18,30);int affectedRaws = userMapper.delete(queryWrapper);System.out.println(affectedRaws);}
6.2 UpdateWrapper
我们可以使用UpdateWrapper来实现数据的修改,在使用UpdateWrapper修改的时候,我们可以使用User对象的非空属性值,表示通过set 语句修改的目标字段及其新值 set 字段1 = 新值1,…
/*** 将Jone的年龄改为29,邮箱改为 Jone@cskaoyan.com* update user set age = 29, email = "Jone@cskaoyan.com" where name = "Jone";*/@Testpublic void testUpdateWrapperDemo1(){// 1. 创建一个UpdateWrapperUpdateWrapper<User> updateWrapper = new UpdateWrapper<>();// 2. 构建条件updateWrapper.set("age",29).set("email","Jone@cskaoyan.com").eq("name","Jone");// 3. 修改方法int affectedRaws = userMapper.update(null, updateWrapper);System.out.println(affectedRaws);}
在使用UpdateWrapper的时候,我们也可以直接使用UpdateWrapper的set方法,设置set语句修改的目标字段及其新值
/*** update user set age = 88 where name = 'Jone';*/@Testpublic void testUpdateWrapperDemo2(){// 1. 创建一个UpdateWrapperUpdateWrapper<User> updateWrapper = new UpdateWrapper<>();// 2. 构建条件updateWrapper.eq("name","Jone");// user对象中未空的成员变量,对应的列,不会受到影响,不会修改他们的值User user = new User();user.setAge(80);// 3. 修改方法int affectedRaws = userMapper.update(user, updateWrapper);System.out.println(affectedRaws);}
6.3 LambdaQueryWrapper
LambdaQueryWrapper 的本质和QueryWrapper是相同的,都主要表示where中的条件,唯一不同的是,在指定条件字段的时候,不是直接指定字段的名称,而是通过Lambda表达式(实体类中对应属性的getXxx方法或者isXxx方法)来指定。
/*** 查询name为zs,年龄在18-25岁的用户* select * from user where name = "zs" and age between 18 and 25;* * lamndaQueryWrapper和 queryWrapper都是用来构建条件的,使用QueryWrapper的地方都可以使用LambdaQueryWrapper* 不同的是:* QueryWrapper构建条件的时候,使用列名* LambdaQueryWrapper构建条件的时候,使用列名映射的对象的成员变量的 getXxx方法的方法引用* 在实际的开发中,哪个更好用呢?* LambdaQueryWrapper更好用, 因为它不需要我们关心表中的字段叫什么名字*/@Testpublic void testLamdaQueryWrapper(){// 1. 创建一个LambdaQueryWrapperLambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();// 2. 构建查询条件lambdaQueryWrapper.eq(User::getName,"zs").between(User::getAge,18,25);// 3. 查询List<User> userList = userMapper.selectList(lambdaQueryWrapper);System.out.println(userList);}
6.4 LambdaUpdateWrapper
/*** 将Jone的年龄改为29,邮箱改为 Jone@wangdao.com* update user set age = 29,email = "Jone@wangdao.com" where name = "Jone";*/@Testpublic void testLambdaUpdateWrapper(){// 1. 构建一个LambdaUpdateWrapperLambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();// 2. 构建条件lambdaUpdateWrapper.set(User::getAge,29).set(User::getEmail,"Jone@wangdao.com").eq(User::getName,"Jone");// 3. 修改int affectedRows = userMapper.update(null, lambdaUpdateWrapper);System.out.println(affectedRows);}
6.5 Condition
在实际开发中,有时需要根据条件来决定是否在SQL语句中添加条件,即需要实现动态SQL的功能,此时我们可以使用带condition参数的重载方法来实现。该condition参数是一个boolean值,表示是否在SQL语句中拼接条件。
/*** 当参数m,为奇数时,查询 id > 10的用户* 当参数m,为偶数时,查询 id <= 10的用户* <p>* condition的条件为true的时候,这个条件就会被拼接到SQL语句中* condition的条件为false的时候,这个条件不会被拼接到SQL语句中*/@Testpublic void testCondition() {int m = 20;LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();lambdaQueryWrapper.gt(m % 2 != 0, User::getId, 10).le(m % 2 == 0, User::getId, 10);List<User> userList = userMapper.selectList(lambdaQueryWrapper);System.out.println(userList);}
7 分页插件
MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能
添加配置类
@Configuration
public class MyBatisPlusConfig {//往容器中注入mybatisPlus的拦截器@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){//1.创建一个拦截器MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//2.给拦截器中添加分页插件的拦截器mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return mybatisPlusInterceptor;}
}
MyBatis Plus自带分页插件实现分页
/*** 分页:* 1. 可以使用MybatisPlus提供的分页方法来进行分页* 2. 也可以对自定义的SQL语句进行分页**/@Testpublic void testSelectPage(){// 1. 创建一个page对象int currentPage = 3; // 页码从1开始,第一页就传1,第二页就传2int pageSize = 2;Page<User> page = new Page<>(currentPage, pageSize);// 2. 创建一个查询条件LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();lambdaQueryWrapper.gt(User::getId,1);// 3. 调用API,分页查询Page<User> pageRet = userMapper.selectPage(page, lambdaQueryWrapper);// 4. 解析结果List<User> userList = pageRet.getRecords();long total = pageRet.getTotal();long pages = pageRet.getPages();long current = pageRet.getCurrent();long size = pageRet.getSize();boolean hasPrevious = pageRet.hasPrevious();boolean hasNext = pageRet.hasNext();System.out.println("userList = " + userList); // 获取这一页的记录System.out.println("total = " + total); // 获取总记录数System.out.println("pages = " + pages); // 获取总页数System.out.println("current = " + current); // 当前是第几页System.out.println("size = " + size); // 页面大小System.out.println("hasPrevious = " + hasPrevious); // 是否有上一页System.out.println("hasNext = " + hasNext); // 是否有下一页}
对自定义的SQL语句进行分页:
如果需要对自定义的SQL语句进行分页,那么只需要做两件事情:
- 给方法的参数 加上 分页参数(Page 对象)
- 给方法的返回值 由List 变为 Page对象
public interface UserMapper extends BaseMapper<User> {/*** 自定义SQL语句进行分页* 如果需要对自定义的SQL语句进行分页,那么只需要做两件事情:* 1. 给方法的参数 加上 分页参数(Page 对象)* 2. 给方法的返回值 由List 变为 Page对象**/// List<User> selectListByGTAge(Integer age);Page<User> selectListByGTAge(Page<User> page, @Param("age") Integer age);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cskaoyan.mp.mapper.UserMapper"><select id="selectListByGTAge" resultType="com.cskaoyan.mp.bean.User">select * from user where age > #{age}</select>
</mapper>
/*** 自定义SQL语句的分页方式*/@Testpublic void testSelectAgeByPage(){// 1. 创建一个page对象int currentPage = 1;int pageSize = 2;Page<User> page = new Page<>(currentPage, pageSize);Page<User> pageRet = userMapper.selectListByGTAge(page, 30);// 4. 解析结果List<User> userList = pageRet.getRecords();long total = pageRet.getTotal();long pages = pageRet.getPages();long current = pageRet.getCurrent();long size = pageRet.getSize();boolean hasPrevious = pageRet.hasPrevious();boolean hasNext = pageRet.hasNext();System.out.println("userList = " + userList); // 获取这一页的记录System.out.println("total = " + total); // 获取总记录数System.out.println("pages = " + pages); // 获取总页数System.out.println("current = " + current); // 当前是第几页System.out.println("size = " + size); // 页面大小System.out.println("hasPrevious = " + hasPrevious); // 是否有上一页System.out.println("hasNext = " + hasNext); // 是否有下一页}