准备工作
创建web工程,引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
配置 (yml格式)
server:
port: 8081
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/company?serverTimezone=UTC&rewriteBatchedStatements=true
username: root
password: 123456
type: com.mysql.cj.jdbc.MysqlDataSource
main:
banner-mode: off
logging:
level:
root: error
创建实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
private String name;
private String nickname;
private Integer age;
private String gender;
private Integer capital;
public User(String name, String nickname, Integer age, String gender, Integer capital) {
this.name = name;
this.nickname = nickname;
this.age = age;
this.gender = gender;
this.capital = capital;
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class address {
private int id;
private int userId;
private String country;
private String province;
private String city;
}
创建dao层
@Repository
public interface UserMapper {
}
创建mapper映射文件
<?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.glaty.studyspringcloud.mapper">
</mapper>
创建service层,并实现service接口
public interface UserService {
}
@Service
public class UserServiceImpl implements UserService {
}
创建controller层
@Controller
public class UserController {
}
创建数据库(使用的是MySQL)以及相应表格
drop database if exists company;
create database if not exists company;
use company;
drop table if exists user;
create table if not exists user(
id int primary key auto_increment,
name varchar(10) not null ,
nickname varchar(20),
age int,
gender varchar(2),
capital int default 0
)auto_increment = 1;
drop table if exists address;
create table if not exists address(
id int primary key auto_increment,
user_id int not null ,
country varchar(15),
province varchar(15),
city varchar(15),
detail varchar(50),
deleted int default 0 comment '逻辑删除,0为未删除'
);
快速入门
快速开始
引入依赖
引入MyBatisPlus依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
修改mapper
MybatisPlus提供了一个基础的BaseMapper接口,其中已经实现了绝大部分单表的CRUD。自定义的Mapper继承了这个BaseMapper,就可以直接使用BaseMapper接口定义好的方法。并且可以将@Repository注解改为@Mapper注解
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
测试
@SpringBootTest
public class MyBatisPlusTest {
@Autowired
UserMapper userMapper;
@Test
void TestUserMapper() {
User user1 = new User(1,"张三", "Java高手", 20, "男", 5000);
User user2 = new User(2,"李四", "JS高手", 19, "女", 5000);
User user3 = new User(3,"王五", "半个废材", 18, "男", 20000);
userMapper.insert(user1);
userMapper.insert(user2);
userMapper.insert(user3);
System.out.println(userMapper.selectById(1));
user1.setCapital(user1.getCapital() + 500);
userMapper.updateById(user1);
userMapper.deleteById(user1);
ArrayList<User> users = new ArrayList<>();
users.add(user2);
users.add(user3);
userMapper.deleteBatchIds(users);
}
}
常见注解
MybatisPlus会根据向BaseMapper接口传入的泛型来推断出表的信息,从而生成SQL。
默认情况下:
MybatisPlus会把PO实体的类名驼峰转下划线作为表名
MybatisPlus会把PO实体的所有变量名驼峰转下划线作为表的字段名,并根据变量类型推断字段类型
MybatisPlus会把名为id的字段作为主键
但很多情况下,默认的实现与实际场景不符,因此MybatisPlus提供了一些注解便于我们声明表信息。
@TableName
表名注解,标识实体类对应的表,用在实体类的定义上
@TableName("user")
public class User {
}
TableName注解除了指定表名以外,还可以指定很多其它属性:
属性 | 类型 | 必须指定 | 默认值 | 描述 |
value | String | 否 | "" | 表名 |
schema | String | 否 | "" | schema |
keepGlobalPrefix | boolean | 否 | false | 是否保持使用全局的 tablePrefix 的值(当全局 tablePrefix 生效时) |
resultMap | String | 否 | "" | xml 中 resultMap 的 id(用于满足特定类型的实体类对象绑定) |
autoResultMap | boolean | 否 | false | 是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建与注入) |
excludeProperty | String[] | 否 | {} | 需要排除的属性名 @since 3.3.1 |
@TableId
MyBatisPlus会将名为id的属性作为主键来看,但有些主键的字段名不为id。可以使用@TableId注解,用来标识实体类中的主键字段。
@TableName("user")
public class User {
@TableId
private Integer id;
}
TableId注解支持两个属性:
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | "" | 表名 |
type | Enum | 否 | IdType.NONE | 指定主键类型 |
IdType支持的类型有:
值 | 描述 |
---|---|
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 方法) |
| 分布式全局唯一 ID 长整型类型(please use ASSIGN_ID) |
| 32 位 UUID 字符串(please use ASSIGN_UUID) |
| 分布式全局唯一 ID 字符串类型(please use ASSIGN_ID) |
这里比较常用的有三种:AUTO、INPUT、ASSIGN_ID
@TableField
用于普通字段注解
@TableName("user")
public class User {
@TableId
private Integer id;
private String name;
private String nickname;
private Integer age;
@TableField("gender")
private String gender;
@TableField("capital")
private Integer capital;
}
一般情况下我们并不需要给字段添加@TableField注解,一些特殊情况除外:
成员变量名与数据库字段名不一致
成员变量是以isXXX命名,按照JavaBean的规范,MybatisPlus识别字段时会把is去除,这就导致与数据库不符。
成员变量名与数据库一致,但是与数据库的关键字冲突。使用@TableField注解给字段名添加转义字符:``
支持的其它属性如下:
属性 | 类型 | 必填 | 默认值 | 描述 |
value | String | 否 | "" | 数据库字段名 |
exist | boolean | 否 | true | 是否为数据库表字段 |
condition | String | 否 | "" | 字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s},参考(opens new window) |
update | String | 否 | "" | 字段 update set 部分注入,例如:当在version字段上注解update="%s+1" 表示更新时会 set version=version+1 (该属性优先级高于 el 属性) |
insertStrategy | Enum | 否 | FieldStrategy.DEFAULT | 举例:NOT_NULL insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>) |
updateStrategy | Enum | 否 | FieldStrategy.DEFAULT | 举例:IGNORED update table_a set column=#{columnProperty} |
whereStrategy | Enum | 否 | FieldStrategy.DEFAULT | 举例:NOT_EMPTY where <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if> |
fill | Enum | 否 | FieldFill.DEFAULT | 字段自动填充策略 |
select | boolean | 否 | true | 是否进行 select 查询 |
keepGlobalFormat | boolean | 否 | false | 是否保持使用全局的 format 进行处理 |
jdbcType | JdbcType | 否 | JdbcType.UNDEFINED | JDBC 类型 (该默认值不代表会按照该值生效) |
typeHandler | TypeHander | 否 | 类型处理器 (该默认值不代表会按照该值生效) | |
numericScale | String | 否 | "" | 指定小数点后保留的位数 |
常见配置
MybatisPlus也支持基于yaml文件的自定义配置,详见官方文档:https://www.baomidou.com/reference/
大多数的配置都有默认值,因此我们都无需配置。但还有一些是没有默认值的,例如:
实体类的别名扫描包
全局id类型
mybatis-plus:
type-aliases-package: com.glaty.studyspringcloud.pojo
global-config:
db-config:
id-type: auto # 全局id类型为自增长
MyBatisPlus也支持手写SQL的,而mapper文件的读取地址可以自己配置:
mybatis-plus:
# Mapper.xml文件地址,当前这个是默认值。
mapper-locations: "classpath*:/mapper/**/*.xml"
核心功能
MyBatis除了可以直接进行简单的CRUD,还有更和、高级的功能可以完成一些复杂条件的SQL语句
条件构造器
除了新增以外,修改、删除、查询的SQL语句都需要指定where条件。BaseMapper中提供的相关方法除了以id作为where条件以外,还可以作用Wrapper添加更加复杂的where条件。Wrapper是一个条件构造的抽象类,其下有很多默认实现,继承关系如图:
AbstractWrapper提供了where中包含的所有条件构造方法:
allEq(condition, params, null2IsNull):所有非空属性等于 =
condition:执行条件
params:map 类型的参数, key 是字段名, value 是字段值
null2IsNull:是否参数为 null 自动执行 isNull 方法, false 则忽略这个字段allEq(condition, filter, params, null2IsNull):传入多参数时允许对参数进行过滤
condition:执行条件
filter:返回 true 来允许字段传入比对条件中
params:map 类型的参数, key 是字段名, value 是字段值
null2IsNull:是否参数为 null 自动执行 isNull 方法, false 则忽略这个字段eq(condition, column, val):等于 =
ne(condition, column, val):不等于 !=
gt(condition, column, val):大于 >
ge(condition, column, val):大于等于
lt(condition, column, val):小于
le(condition, column, val):小于等于
condition:执行条件
column:字段
val:值
between(condition, column, val1, val2):在两值之间
notBetween(condition, column, val1, val2):不在两值之间like(condition, column, val):LIKE '%值%'
likeLeft(condition, column, val):LIKE '%值%'
likeRight(condition, column, val):LIKE '%值%'notLike(condition, column, val):NOT LIKE '%值%'
notLikeLeft(condition, column, val):NOT LIKE '%值%'
notLikeRight(condition, column, val):NOT LIKE '%值%'and(condition, consumer):AND 嵌套
or(condition, consumer):OR嵌套
nested(condition, consumer):正常嵌套 不带AND 或者 OR
not(condition, consumer):NOT嵌套
例: and(i ->gt i.eq("name", "李白").ne("status", "活着"))
consumer:消费函数
or(condition):拼接OR
apply(condition, applySql, values):拼接sql(会有sql注入风险)
values:数据数组last(condition, lastSql):无视优化规则直接拼接到sql的最后(有sql注入的风险)
lastSql:sql语句comment(condition, comment):sql 注释(会拼接在sql的最后面)
comment sql注释first(condition, firstSql):sql 起始句(会拼接在SQL语句的起始处)
firstSql:起始语句exists(condition, existsSql, values):拼接 EXISTS(sql语句)(sql 注入方法)
notExists(condition, existsSql, values):拼接 NOT EXISTS(sql语句)(sql 注入方法)
existsSql:sql语句
values:数据数组
QueryWrapper在AbstractWrapper的基础上拓展了一个select方法,允许指定查询字段。UpdateWrapper在AbstractWrapper的基础上拓展了一个set方法,允许指定SQL中的SET部分。
QueryWrapper
修改、删除、查询,都可以使用QueryWrapper来构建查询条件
@Test
void testQueryWrapper() {
// 1.构建查询条件 where name like "%o%" AND balance >= 1000
QueryWrapper<User> wrapper = new QueryWrapper<User>()
.select("id", "name", "nickname", "capital")
.like("nickname", "%手%")
.ge("capital", 5500);
// 2.查询数据
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
UpdateWrapper
BaseMapper中的update方法更新时只能直接赋值,对于一些复杂的需求就难以实现。SET的赋值结果是基于字段现有值的,这个时候就要利用UpdateWrapper中的setSql功能了
@Test
void testUpdateWrapper() {
List<Long> ids = List.of(2L, 3L);
// 1.生成SQL
UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
.setSql("capital = capital + 2000") // SET balance = balance - 200
.in("id", ids); // WHERE id in (1, 2, 4)
// 2.更新,注意第一个参数可以给null,也就是不填更新字段和数据,
// 而是基于UpdateWrapper中的setSQL来更新
userMapper.update(null, wrapper);
}
LambdaWrapper
无论是QueryWrapper还是UpdateWrapper在构造条件的时候都需要写死字段名称,这在编程规范中显然是不推荐的。
基于变量的gettter方法结合反射技术,MybatisPlus又提供了一套基于Lambda的Wrapper:
LambdaQueryWrapper
LambdaUpdateWrapper
分别对应着QueryWrapper和UpdateWrapper
只要将条件对应的字段的getter法传递给MybatisPlus,就能计算出对应的变量名。传递方法可以使用JDK8中的方法引用Lambda表达式。
@Test
void testLambdaQueryWrapper() {
// 1.构建条件
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.lambda()
.select(User::getId, User::getName, User::getNickname, User::getCapital)
.like(User::getNickname, "手")
.ge(User::getCapital, 5500);
// 2.查询数据
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
@Test
void testLambdaQueryWrapper() {
// 1.构建条件
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.select(User::getId, User::getName, User::getNickname, User::getCapital)
.like(User::getNickname, "手")
.ge(User::getCapital, 5500);
// 2.查询数据
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
自定义SQL
MybatisPlus提供了自定义SQL功能,可以让我们利用Wrapper生成查询条件,再结合Mapper.xml编写SQL
基本用法
UserMapper中自定义方法并自定义SQL:
@Mapper
public interface UserMapper extends BaseMapper<User> {
@Select("UPDATE user SET capital = capital + #{money} ${ew.customSqlSegment}")
void deductCapitalByIds(@Param("money") int money, @Param("ew") QueryWrapper<User> wrapper);
}
执行操作:
@Test
void testCustomWrapper() {
// 1.准备自定义查询条件
List<Long> ids = List.of(1L, 2L, 3L);
QueryWrapper<User> wrapper = new QueryWrapper<User>().in("id", ids);
// 2.调用mapper的自定义方法,直接传递Wrapper
userMapper.deductCapitalByIds(200, wrapper);
}
多表关联
MyBatisPlus不支持多表查询,但是可以利用Wrapper中自定义条件结合自定义SQL来实现多表查询的效果。
UserMapper中自定义方法并自定义SQL:
@Select("SELECT u.* FROM user u INNER JOIN address a ON u.id = a.user_id ${ew.customSqlSegment}")
List<User> queryUserByWrapper(@Param("ew")QueryWrapper<User> wrapper);
执行操作:
@Test
void testCustomJoinWrapper() {
// 1.自定义查询条件
QueryWrapper<User> wrapper = new QueryWrapper<User>()
.in("u.id", List.of(1L, 2L, 3L))
.eq("a.city", "北京");
// 2.调用mapper的自定义方法
List<User> users = userMapper.queryUserByWrapper(wrapper);
users.forEach(System.out::println);
}
Service接口
MybatisPlus不仅提供了BaseMapper,还提供了通用的Service接口及默认实现,封装了一些常用的service模板方法。
通用接口为IService,默认实现为ServiceImpl,其中封装的方法可以分为以下几类:
save:新增
remove:删除
update:更新
get:查询单个结果
list:查询集合结果
count:计数
page:分页查询
CRUD
save:新增单个元素
saveBatch:批量新增
saveOrUpdate:根据id判断,如果数据存在就更新,不存在则新增
saveOrUpdateBatch:批量的新增或修改
removeById:根据id删除
removeByIds:根据id批量删除
removeByMap:根据Map中的键值对为条件删除
remove(Wrapper<T>):根据Wrapper条件删除
~~removeBatchByIds~~:暂不支持
updateById:根据id修改
update(Wrapper<T>):根据UpdateWrapper修改,Wrapper中包含set和where部分
update(T,Wrapper<T>):按照T内的数据修改与Wrapper匹配到的数据
updateBatchById:根据id批量修改
getById:根据id查询1条数据
getOne(Wrapper<T>):根据Wrapper查询1条数据
getBaseMapper:获取Service内的BaseMapper实现,某些时候需要直接调用Mapper内的自定义SQL时可以用这个方法获取到Mapper
listByIds:根据id批量查询
list(Wrapper<T>):根据Wrapper条件查询多条数据
list():查询所有count():统计所有数量
count(Wrapper<T>):统计符合Wrapper条件的数据数量
在service中需要调用Mapper中自定义SQL时,必须通过方法GetBathMapper获取service对应的Mapper
基本用法
让自定义Service接口继承IService,Service实现类继承ServiceImpl:
public interface UserService extends IService<User> {
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
然后在Controller层注入Service后可以直接使用其方法
@Controller
public class UserController {
@Autowired
UserService userService;
@PostMapping
// 新增用户
public void saveUser(@RequestBody User user){
userService.save(user);
}
@DeleteMapping("/{id}")
// 删除用户
public void removeUserById(@PathVariable("id") Integer id){
userService.removeById(id);
}
@GetMapping("/{id}")
// 根据id查询用户
public User queryUserById(@PathVariable("id") Integer id){
return userService.getById(id);
}
@GetMapping
// 根据id集合查询用户
public List<User> queryUserByIds(@RequestParam("ids") List<Integer> ids){
return userService.listByIds(ids);
}
}
Lambda
IService中还提供了Lambda功能来简化我们的复杂查询及更新功能。而且Service中对LambdaQueryWrapper和LambdaUpdateWrapper的用法进一步做了简化。可以直接调用lambdaQuery和lambdaUpdate方法。
lambdaQuery方法中除了可以构建条件,还需要在链式编程的最后添加一个list(),意为返回list集合。这里不仅可以用list(),还可以用one()、count()。
.one():最多1个结果
.list():返回集合结果
.count():返回计数结果
@GetMapping("/list")
// 根据id集合查询用户
public List<User> queryUsers(Map<String, String> query){
String name = query.get("name");
String minBalance = query.get("minBalance");
String maxBalance = query.get("maxBalance");
return userService.lambdaQuery()
.like(name != null, User::getName, name)
.ge(minBalance != null, User::getCapital, minBalance)
.le(maxBalance != null, User::getCapital, maxBalance)
.list();
}
批量新增
MybatisPlus的批处理saveBatch()可以减少对数据库的请求次数,从而加快运行速度。
@Test
void testSaveBatch() {
List<User> list = new ArrayList<>(1000);
long b = System.currentTimeMillis();
for (int i = 1; i <= 100000; i++) {
list.add(new User(i));
if (i % 1000 == 0) {
userService.saveBatch(list);
list.clear();
}
}
long e = System.currentTimeMillis();
System.out.println("耗时:" + (e - b));
}
MybatisPlus的批处理是基于PrepareStatement的预编译模式,然后批量提交,最终在数据库再分别执行多条insert语句,逐条插入数据。但可以设置MySQL的客户端连接参数中的rewriteBatchedStatements为true,这样可以使数据库直接用一条语句完成批量新增。
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/company?serverTimezone=UTC&rewriteBatchedStatements=true
username: root
password: 123456
type: com.mysql.cj.jdbc.MysqlDataSource
扩展功能
代码生成
在使用MybatisPlus以后,基础的Mapper、Service、pojo代码相对固定,重复编写也比较麻烦。因此MybatisPlus官方提供了代码生成器根据数据库表结构生成pojo、Mapper、Service等相关代码。只不过代码生成器同样要编码使用,也很麻烦。可以使用idea的MybatisPlus插件,可以基于图形化界面完成MybatisPlus的代码生成。安装后重启Idea即可使用。
在Config Databas中设置连接的数据库
在Code Generator生成代码
mapper还需要手动加上@Mapper注解,自动生成的是无注解的
@Mapper
public interface AddressMapper extends BaseMapper<Address> {
}
静态工具
Service之间也会相互调用,为了避免出现循环依赖问题,MybatisPlus提供一个静态工具类Db,其中的一些静态方法与IService中方法签名基本一致,也可以实现CRUD功能。
@GetMapping("/{id}/content/address")
@ResponseBody
UserAndAddress DbGet(@PathVariable Integer id) {
User user = userService.getById(id);
return new UserAndAddress(user, Db.lambdaQuery(Address.class).ge(Address::getUserId, id).list());
}
上例的UserAndAddress是创建的一个包含User及其Address的实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserAndAddress {
private User user;
private List<Address> addresses;
}
逻辑删除
对于一些比较重要的数据,往往会采用逻辑删除的方案,MybatisPlus也支持逻辑删除(只有MybatisPlus生成的SQL语句才支持自动的逻辑删除,自定义SQL需要自己手动处理逻辑删除)
在application.yml中配置逻辑删除字段:
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
配置好后删除操作都会变为逻辑删除
通用枚举
在进行判断用户状态时可以使用数字进行储存其状态,但是不利于阅读。可以定义枚举类来储存其数字的含义。
定义枚举类:
@Getter
public enum UserStatus {
NORMAL(1, "正常"),
FREEZE(2, "冻结")
;
@EnumValue //标记枚举属性
private final int value;
@JsonValue //标记JSON序列化时展示的字段
private final String desc;
UserStatus(int value, String desc) {
this.value = value;
this.desc = desc;
}
}
配置枚举处理器在application.yaml文件中添加配置:
mybatis-plus:
configuration:
default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
在User类中加入UserStatus属性:
private UserStatus status;
在数据库中User表中加入status字段名:
alter table user add status int default 1;
JSON类型处理器
MybatisPlus提供了很多特殊类型字段的类型处理器,解决特殊字段类型与数据库类型转换的问题。处理JSON可以使用JacksonTypeHandler处理器。
定义实体:
@Data
public class UserInfo {
private Integer age;
private String intro;
private String gender;
}
在User实体类和数据库的User表中加入Info,并在User实体类的Info属性上加上注解
@TableField(typeHandler = JacksonTypeHandler.class)
private UserInfo info;
alter table user add info JSON;
这样可以在数据库中储存的数据未json类型,但在Java中其属性是一个实体类。
插件功能
分页插件
在未引入分页插件的情况下,MybatisPlus是不支持分页功能的,IService和BaseMapper中的分页方法都无法正常起效。
配置分页插件:
@Configuration
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
// 初始化核心插件
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
分页查询需要借助Page
@GetMapping("/{current}/{size}")
public Page<User> getUserByPage(@PathVariable Integer current, @PathVariable Integer size) {
// 1.分页查询,new Page()的两个参数分别是:页码、每页大小
Page<User> page = new Page<>(current, size);
return userService.page(page);
}
page有以下属性:
records:查询数据列表
total:总数
size:每页显示条数,默认 10
current:当前页
orders:排序字段信息
optimizeCountSql:自动优化 COUNT SQL,默认 true
searchCount:是否进行 count 查询,默认 true
maxLimit:单页分页条数限制
countId:countId