目录
引导类中添加 @MapperScan 注解,扫描 Mapper 文件夹
MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
愿景
我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。

- <dependency>
- <groupId>com.baomidougroupId>
- <artifactId>mybatis-plus-boot-starterartifactId>
- <version>3.4.2version>
- dependency>
- spring:
- #配置数据源信息
- datasource:
- type: com.zaxxer.hikari.HikariDataSource
- #配置数据库连接信息
- driver-class-name: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://localhost
- username: root
- password: root
-
- #mybatisplus添加日志功能
- mybatis-plus:
- configuration:
- log-impl: org.apache.ibatis.logging.stdout.stdOutImpl
- global-config:
- db-config:
- #配置Mybatis-plus操作表的默认前缀
- table-prefix: t_
- #配置Mybatis-plus的主键策略
- id-type: auto
配置文件注意事项
spring boot 2.0(内置jdbc5驱动),驱动类使用:driver-class-name: com.mysql.jdbc.Driver
spring boot 2.1及以上(内置jdbc8驱动),驱动类使用:
driver-class-name: com.mysql.cj.jdbc.Driver
否则运行测试用例的时候会有 WARN 信息
MySQL5.7版本的url:
jdbc:mysql://localhost:3306/?characterEncoding=utf-8&useSSL=false
MySQL8.0版本的url:
jdbc:mysql://localhost:3306/?
serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
// 这个属性用于指定 MyBatis Mapper XML 文件的位置,例如:mybatis-plus: mapper-locations: classpath*:/mapper/*Mapper.xml
mybatis-plus.mapper-locations
// 这个属性用于设置是否显示 MyBatis-Plus 的启动 banner。在示例中,该属性被设置为 false,表示禁用启动 banner
mybatis-plus.global-config.banner
// 这个属性用于设置主键 ID 的生成策略。在示例中,auto 表示使用数据库自动生成的主键 ID
mybatis-plus.global-config.db-config.id-type:auto
// 这些属性用于设置全局的 SQL 过滤策略。在示例中,not_empty 表示只在参数值非空时才会生成对应的 SQL 条件
mybatis-plus.global-config.db-config.where-strategy:not_empty
mybatis-plus.global-config.db-config.insert-strategy:not_empty
mybatis-plus.global-config.db-config.update-strategy:not_null
// 这个属性用于设置在 SQL 中处理空值时使用的 JDBC 类型。在示例中,'null' 表示使用 NULL 类型
mybatis-plus.configuration.jdbc-type-for-null:'null'
// 这个属性用于设置是否在设置属性为 NULL 时调用对应的 setter 方法。在示例中,该属性被设置为 true,表示在设置属性为 NULL 时会调用 setter 方法
mybatis-plus.configuration.call-setters-on-nulls:true
- @SpringBootApplication
- @MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
- public class MPApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(Application.class, args);
- }
-
- }
自行建立一个实体,可以是最简单的 学生,姓名,班级,学号
继承BaseMapper,后面的实体写自己的实体
- @Mapper
- public interface UserMapper extends BaseMapper
{ -
- }
public interface UserService extends IService {}
- @Slf4j
- @Service
- public class UserServiceImpl extends ServiceImpl
implements - UserService {}
-
IService 是 MyBatis-Plus 提供的一个通用 Service 层接口,它封装了常见的 CRUD 操作,包括插入、删除、查询和分页等。通过继承 IService 接口,可以快速实现对数据库的基本操作,同时保持代码的简洁性和可维护性。
IService 接口中的方法命名遵循了一定的规范,如 get 用于查询单行,remove 用于删除,list 用于查询集合,page 用于分页查询,这样可以避免与 Mapper 层的方法混淆。
提示
- 泛型
T为任意实体对象- 建议如果存在自定义通用 Service 方法的可能,请创建自己的
IBaseService继承Mybatis-Plus提供的IService基类- 对象
Wrapper为 条件构造器
- // 插入一条记录(选择字段,策略插入)
- boolean save(T entity);
- // 插入(批量)
- boolean saveBatch(Collection
entityList) ; - // 插入(批量)
- boolean saveBatch(Collection
entityList, int batchSize) ;
功能描述:插入记录,根据实体对象的字段进行策略性插入。
返回值: boolean,表示插入操作是否成功。
参数说明:
| 类型 | 参数名 | 描述 |
|---|---|---|
| T | entity | 实体对象 |
| Collection | entityList | 实体对象集合 |
| int | batchSize | 插入批次数量 |
- // 假设有一个 User 实体对象
- User user = new User();
- user.setName("John Doe");
- user.setEmail("john.doe@example.com");
- boolean result = userService.save(user); // 调用 save 方法
- if (result) {
- System.out.println("User saved successfully.");
- } else {
- System.out.println("Failed to save user.");
- }
-
- INSERT INTO user (name, email) VALUES ('John Doe', 'john.doe@example.com')
功能描述: 根据实体对象的主键 ID 进行判断,存在则更新记录,否则插入记录。
返回值: boolean,表示插入或更新操作是否成功。
参数说明:
| 类型 | 参数名 | 描述 |
|---|---|---|
| T | entity | 实体对象 |
| Wrapper | updateWrapper | 实体对象封装操作类 UpdateWrapper |
| Collection | entityList | 实体对象集合 |
| int | batchSize | 插入批次数量 |
- // TableId 注解属性值存在则更新记录,否插入一条记录
- boolean saveOrUpdate(T entity);
- // 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
- boolean saveOrUpdate(T entity, Wrapper
updateWrapper) ; - // 批量修改插入
- boolean saveOrUpdateBatch(Collection
entityList) ; - // 批量修改插入
- boolean saveOrUpdateBatch(Collection
entityList, int batchSize) ;
- // 假设有一个 User 实体对象,其中 id 是 TableId 注解的属性
- User user = new User();
- user.setId(1);
- user.setName("John Doe");
- user.setEmail("john.doe@example.com");
- boolean result = userService.saveOrUpdate(user); // 调用 saveOrUpdate 方法
- if (result) {
- System.out.println("User updated or saved successfully.");
- } else {
- System.out.println("Failed to update or save user.");
- }
UPDATE user SET name = 'John Doe', email = 'john.doe@example.com' WHERE id = 1
INSERT INTO user (id, name, email) VALUES (1, 'John Doe', 'john.doe@example.com')
- // 根据 queryWrapper 设置的条件,删除记录
- boolean remove(Wrapper
queryWrapper) ; - // 根据 ID 删除
- boolean removeById(Serializable id);
- // 根据 columnMap 条件,删除记录
- boolean removeByMap(Map
columnMap) ; - // 删除(根据ID 批量删除)
- boolean removeByIds(Collection extends Serializable> idList);
功能描述: 通过指定条件删除符合条件的记录。
返回值: boolean,表示删除操作是否成功。
参数说明:
| 类型 | 参数名 | 描述 |
|---|---|---|
| Wrapper | queryWrapper | 实体包装类 QueryWrapper |
| Serializable | id | 主键 ID |
| Map | columnMap | 表字段 map 对象 |
| Collection extends Serializable> | idList | 主键 ID 列表 |
- // 假设有一个 QueryWrapper 对象,设置删除条件为 name = 'John Doe'
- QueryWrapper
queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("name", "John Doe");
- boolean result = userService.remove(queryWrapper); // 调用 remove 方法
- if (result) {
- System.out.println("Record deleted successfully.");
- } else {
- System.out.println("Failed to delete record.");
- }
DELETE FROM user WHERE name = 'John Doe'
- // 假设要删除 ID 为 1 的用户
- boolean result = userService.removeById(1); // 调用 removeById 方法
- if (result) {
- System.out.println("User deleted successfully.");
- } else {
- System.out.println("Failed to delete user.");
- }
DELETE FROM user WHERE id = 1
- // 假设有一组 ID 列表,批量删除用户
- List
ids = Arrays.asList(1, 2, 3); - boolean result = userService.removeByIds(ids); // 调用 removeByIds 方法
- if (result) {
- System.out.println("Users deleted successfully.");
- } else {
- System.out.println("Failed to delete users.");
- }
DELETE FROM user WHERE id IN (1, 2, 3)
- // 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
- boolean update(Wrapper
updateWrapper) ; - // 根据 whereWrapper 条件,更新记录
- boolean update(T updateEntity, Wrapper
whereWrapper) ; - // 根据 ID 选择修改
- boolean updateById(T entity);
- // 根据ID 批量更新
- boolean updateBatchById(Collection
entityList) ; - // 根据ID 批量更新
- boolean updateBatchById(Collection
entityList, int batchSize) ;
功能描述: 通过指定条件更新符合条件的记录。
返回值: boolean,表示更新操作是否成功。
参数说明:
| 类型 | 参数名 | 描述 |
|---|---|---|
| Wrapper | updateWrapper | 实体对象封装操作类 UpdateWrapper |
| T | entity | 实体对象 |
| Collection | entityList | 实体对象集合 |
| int | batchSize | 更新批次数量 |
- // 假设有一个 UpdateWrapper 对象,设置更新条件为 name = 'John Doe',更新字段为 email
- UpdateWrapper
updateWrapper = new UpdateWrapper<>(); - updateWrapper.eq("name", "John Doe").set("email", "john.doe@newdomain.com");
- boolean result = userService.update(updateWrapper); // 调用 update 方法
- if (result) {
- System.out.println("Record updated successfully.");
- } else {
- System.out.println("Failed to update record.");
- }
UPDATE user SET email = 'john.doe@newdomain.com' WHERE name = 'John Doe'
- // 假设有一个 User 实体对象,设置更新字段为 email,根据 ID 更新
- User updateEntity = new User();
- updateEntity.setId(1);
- updateEntity.setEmail("updated.email@example.com");
- boolean result = userService.updateById(updateEntity); // 调用 updateById 方法
- if (result) {
- System.out.println("Record updated successfully.");
- } else {
- System.out.println("Failed to update record.");
- }
生成的 SQL:
UPDATE user SET email = 'updated.email@example.com' WHERE id = 1
- // 根据 ID 查询
- T getById(Serializable id);
- // 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
- T getOne(Wrapper
queryWrapper) ; - // 根据 Wrapper,查询一条记录
- T getOne(Wrapper
queryWrapper, boolean throwEx) ; - // 根据 Wrapper,查询一条记录
- Map
getMap(Wrapper queryWrapper) ; - // 根据 Wrapper,查询一条记录
V getObj(Wrapper queryWrapper, Function super Object, V> mapper) ;
功能描述: 根据指定条件查询符合条件的记录。
返回值: 查询结果,可能是实体对象、Map 对象或其他类型。
参数说明:
| 类型 | 参数名 | 描述 |
|---|---|---|
| Serializable | id | 主键 ID |
| Wrapper | queryWrapper | 实体对象封装操作类 QueryWrapper |
| boolean | throwEx | 有多个 result 是否抛出异常 |
| T | entity | 实体对象 |
| Function super Object, V> | mapper | 转换函数 |
- // 假设要查询 ID 为 1 的用户
- User user = userService.getById(1); // 调用 getById 方法
- if (user != null) {
- System.out.println("User found: " + user);
- } else {
- System.out.println("User not found.");
- }
SELECT * FROM user WHERE id = 1
- // 假设有一个 QueryWrapper 对象,设置查询条件为 name = 'John Doe'
- QueryWrapper
queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("name", "John Doe");
- User user = userService.getOne(queryWrapper); // 调用 getOne 方法
- if (user != null) {
- System.out.println("User found: " + user);
- } else {
- System.out.println("User not found.");
- }
SELECT * FROM user WHERE name = 'John Doe' LIMIT 1
- // 查询所有
- List
list(); - // 查询列表
- List
list(Wrapper queryWrapper) ; - // 查询(根据ID 批量查询)
- Collection
listByIds(Collection extends Serializable> idList); - // 查询(根据 columnMap 条件)
- Collection
listByMap(Map columnMap) ; - // 查询所有列表
- List
- // 查询列表
- List
- // 查询全部记录
- List
- // 查询全部记录
List listObjs(Function super Object, V> mapper); - // 根据 Wrapper 条件,查询全部记录
- List
- // 根据 Wrapper 条件,查询全部记录
List listObjs(Wrapper queryWrapper, Function super Object, V> mapper) ;
功能描述: 查询符合条件的记录。
返回值: 查询结果,可能是实体对象、Map 对象或其他类型。
参数说明:
| 类型 | 参数名 | 描述 |
|---|---|---|
| Wrapper | queryWrapper | 实体对象封装操作类 QueryWrapper |
| Collection extends Serializable> | idList | 主键 ID 列表 |
| Map | columnMap | 表字段 map 对象 |
| Function super Object, V> | mapper | 转换函数 |
- // 查询所有用户
- List
users = userService.list(); // 调用 list 方法 - for (User user : users) {
- System.out.println("User: " + user);
- }
SELECT * FROM user
- // 假设有一个 QueryWrapper 对象,设置查询条件为 age > 25
- QueryWrapper
queryWrapper = new QueryWrapper<>(); - queryWrapper.gt("age", 25);
- List
users = userService.list(queryWrapper); // 调用 list 方法 - for (User user : users) {
- System.out.println("User: " + user);
- }
SELECT * FROM user WHERE age > 25
- // 假设有一组 ID 列表,批量查询用户
- List
ids = Arrays.asList(1, 2, 3); - Collection
users = userService.listByIds(ids); // 调用 listByIds 方法 - for (User user : users) {
- System.out.println("User: " + user);
- }
生成的SQL:
SELECT * FROM user WHERE id IN (1, 2, 3)
- // 无条件分页查询
- IPage
page(IPage page) ; - // 条件分页查询
- IPage
page(IPage page, Wrapper queryWrapper) ; - // 无条件分页查询
- IPage
- // 条件分页查询
- IPage
功能描述: 分页查询符合条件的记录。
返回值: 分页查询结果,包含记录列表和总记录数。
参数说明:
| 类型 | 参数名 | 描述 |
|---|---|---|
| IPage | page | 翻页对象 |
| Wrapper | queryWrapper | 实体对象封装操作类 QueryWrapper |
- // 假设要进行无条件的分页查询,每页显示10条记录,查询第1页
- IPage
page = new Page<>(1, 10); - IPage
userPage = userService.page(page); // 调用 page 方法 - List
userList = userPage.getRecords(); - long total = userPage.getTotal();
- System.out.println("Total users: " + total);
- for (User user : userList) {
- System.out.println("User: " + user);
- }
SELECT * FROM user LIMIT 10 OFFSET 0
- // 假设有一个 QueryWrapper 对象,设置查询条件为 age > 25,进行有条件的分页查询
- IPage
page = new Page<>(1, 10); - QueryWrapper
queryWrapper = new QueryWrapper<>(); - queryWrapper.gt("age", 25);
- IPage
userPage = userService.page(page, queryWrapper); // 调用 page 方法 - List
userList = userPage.getRecords(); - long total = userPage.getTotal();
- System.out.println("Total users (age > 25): " + total);
- for (User user : userList) {
- System.out.println("User: " + user);
- }
SELECT * FROM user WHERE age > 25 LIMIT 10 OFFSET 0
- // 查询总记录数
- int count();
- // 根据 Wrapper 条件,查询总记录数
- int count(Wrapper
queryWrapper) ; -
- //自3.4.3.2开始,返回值修改为long
- // 查询总记录数
- long count();
- // 根据 Wrapper 条件,查询总记录数
- long count(Wrapper
queryWrapper) ;
功能描述: 查询符合条件的记录总数。
返回值: 符合条件的记录总数。
参数说明:
| 类型 | 参数名 | 描述 |
|---|---|---|
| Wrapper | queryWrapper | 实体对象封装操作类 QueryWrapper |
- // 查询用户表中的总记录数
- int totalUsers = userService.count(); // 调用 count 方法
- System.out.println("Total users: " + totalUsers);
SELECT COUNT(*) FROM user
- // 假设有一个 QueryWrapper 对象,设置查询条件为 age > 25,查询满足条件的用户总数
- QueryWrapper
queryWrapper = new QueryWrapper<>(); - queryWrapper.gt("age", 25);
- int totalUsers = userService.count(queryWrapper); // 调用 count 方法
- System.out.println("Total users (age > 25): " + totalUsers);
SELECT COUNT(*) FROM user WHERE age > 25
BaseMapper 是 Mybatis-Plus 提供的一个通用 Mapper 接口,它封装了一系列常用的数据库操作方法,包括增、删、改、查等。通过继承 BaseMapper,开发者可以快速地对数据库进行操作,而无需编写繁琐的 SQL 语句。
提示
- 泛型
T为任意实体对象- 参数
Serializable为任意类型主键Mybatis-Plus不推荐使用复合主键约定每一张表都有自己的唯一id主键- 对象
Wrapper为 条件构造器
- // 插入一条记录
- int insert(T entity);
功能描述: 插入一条记录。
返回值: int,表示插入操作影响的行数,通常为 1,表示插入成功。
参数说明:
| 类型 | 参数名 | 描述 |
|---|---|---|
| T | entity | 实体对象 |
- User user = new User();
- user.setName("John Doe");
- user.setEmail("john.doe@example.com");
- int rows = userMapper.insert(user); // 调用 insert 方法
- if (rows > 0) {
- System.out.println("User inserted successfully.");
- } else {
- System.out.println("Failed to insert user.");
- }
INSERT INTO user (name, email) VALUES (?, ?)
通过上述示例,我们可以看到 insert 方法是如何在 Mapper 层进行插入操作的,以及它对应的 SQL 语句。这个方法简化了插入操作的实现,使得开发者无需手动编写 SQL 语句。
- // 根据 entity 条件,删除记录
- int delete(@Param(Constants.WRAPPER) Wrapper
wrapper) ; - // 删除(根据ID 批量删除)
- int deleteBatchIds(@Param(Constants.COLLECTION) Collection extends Serializable> idList);
- // 根据 ID 删除
- int deleteById(Serializable id);
- // 根据 columnMap 条件,删除记录
- int deleteByMap(@Param(Constants.COLUMN_MAP) Map
columnMap) ;
功能描述: 删除符合条件的记录。
返回值: int,表示删除操作影响的行数,通常为 1,表示删除成功。
参数说明:
| 类型 | 参数名 | 描述 |
|---|---|---|
| Wrapper | wrapper | 实体对象封装操作类(可以为 null) |
| Collection extends Serializable> | idList | 主键 ID 列表(不能为 null 以及 empty) |
| Serializable | id | 主键 ID |
| Map | columnMap | 表字段 map 对象 |
- // 假设有一个 QueryWrapper 对象,设置查询条件为 age > 25,删除满足条件的用户
- QueryWrapper
queryWrapper = new QueryWrapper<>(); - queryWrapper.gt("age", 25);
- int rows = userMapper.delete(queryWrapper); // 调用 delete 方法
- if (rows > 0) {
- System.out.println("Users deleted successfully.");
- } else {
- System.out.println("No users deleted.");
- }
DELETE FROM user WHERE age > 25
- // 根据 ID 删除单个用户
- int userId = 1;
- int rows = userMapper.deleteById(userId); // 调用 deleteById 方法
- if (rows > 0) {
- System.out.println("User deleted successfully.");
- } else {
- System.out.println("No user deleted.");
- }
DELETE FROM user WHERE id = 1
- // 假设有一组 ID 列表,批量删除用户
- List
ids = Arrays.asList(1, 2, 3); - int rows = userMapper.deleteBatchIds(ids); // 调用 deleteBatchIds 方法
- if (rows > 0) {
- System.out.println("Users deleted successfully.");
- } else {
- System.out.println("No users deleted.");
- }
DELETE FROM user WHERE id IN (1, 2, 3)
通过上述示例,我们可以看到 delete 系列方法是如何在 Mapper 层进行删除操作的,以及它们对应的 SQL 语句。这些方法提供了灵活的数据删除方式,可以根据不同的条件进行删除操作。
- // 根据 whereWrapper 条件,更新记录
- int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper
whereWrapper) ; - // 根据 ID 修改
- int updateById(@Param(Constants.ENTITY) T entity);
功能描述: 更新符合条件的记录。
返回值: int,表示更新操作影响的行数,通常为 1,表示更新成功。
参数说明:
| 类型 | 参数名 | 描述 |
|---|---|---|
| T | entity | 实体对象 (set 条件值,可为 null) |
| Wrapper | updateWrapper | 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句) |
示例
- // 假设有一个 UpdateWrapper 对象,设置查询条件为 age > 25,更新满足条件的用户的邮箱
- UpdateWrapper
updateWrapper = new UpdateWrapper<>(); - updateWrapper.gt("age", 25);
- User updateUser = new User();
- updateUser.setEmail("new.email@example.com");
- int rows = userMapper.update(updateUser, updateWrapper); // 调用 update 方法
- if (rows > 0) {
- System.out.println("Users updated successfully.");
- } else {
- System.out.println("No users updated.");
- }
UPDATE user SET email = ? WHERE age > 25
- // 假设要更新 ID 为 1 的用户的邮箱
- User updateUser = new User();
- updateUser.setId(1);
- updateUser.setEmail("new.email@example.com");
- int rows = userMapper.updateById(updateUser); // 调用 updateById 方法
- if (rows > 0) {
- System.out.println("User updated successfully.");
- } else {
- System.out.println("No user updated.");
- }
UPDATE user SET email = ? WHERE id = 1
通过上述示例,我们可以看到 update 系列方法是如何在 Mapper 层进行更新操作的,以及它们对应的 SQL 语句。这些方法提供了灵活的数据更新方式,可以根据不同的条件进行更新操作。
- // 根据 ID 查询
- T selectById(Serializable id);
- // 根据 entity 条件,查询一条记录
- T selectOne(@Param(Constants.WRAPPER) Wrapper
queryWrapper) ; -
- // 查询(根据ID 批量查询)
- List
selectBatchIds(@Param(Constants.COLLECTION) Collection extends Serializable> idList); - // 根据 entity 条件,查询全部记录
- List
selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper) ; - // 查询(根据 columnMap 条件)
- List
selectByMap(@Param(Constants.COLUMN_MAP) Map columnMap) ; - // 根据 Wrapper 条件,查询全部记录
- List
- // 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
- List
-
- // 根据 entity 条件,查询全部记录(并翻页)
- IPage
selectPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper) ; - // 根据 Wrapper 条件,查询全部记录(并翻页)
- IPage
- // 根据 Wrapper 条件,查询总记录数
- Integer selectCount(@Param(Constants.WRAPPER) Wrapper
queryWrapper) ;
功能描述: 查询符合条件的记录。
返回值: 查询结果,可能是实体对象、Map 对象或其他类型。
参数说明:
| 类型 | 参数名 | 描述 |
|---|---|---|
| Serializable | id | 主键 ID |
| Wrapper | queryWrapper | 实体对象封装操作类(可以为 null) |
| Collection extends Serializable> | idList | 主键 ID 列表(不能为 null 以及 empty) |
| Map | columnMap | 表字段 map 对象 |
| IPage | page | 分页查询条件(可以为 RowBounds.DEFAULT) |
- // 根据 ID 查询单个用户
- int userId = 1;
- User user = userMapper.selectById(userId); // 调用 selectById 方法
- System.out.println("User: " + user);
SELECT * FROM user WHERE id = 1
- // 假设有一个 QueryWrapper 对象,设置查询条件为 age > 25,查询一条满足条件的用户
- QueryWrapper
queryWrapper = new QueryWrapper<>(); - queryWrapper.gt("age", 25);
- User user = userMapper.selectOne(queryWrapper); // 调用 selectOne 方法
- System.out.println("User: " + user);
SELECT * FROM user WHERE age > 25
- // 假设有一组 ID 列表,批量查询用户
- List
ids = Arrays.asList(1, 2, 3); - List
users = userMapper.selectBatchIds(ids); // 调用 selectBatchIds 方法 - for (User u : users) {
- System.out.println("User: " + u);
- }
SELECT * FROM user WHERE id IN (1, 2, 3)
- // 假设要进行分页查询,每页显示10条记录,查询第1页,查询条件为 age > 25
- IPage
page = new Page<>(1, 10); - QueryWrapper
queryWrapper = new QueryWrapper<>(); - queryWrapper.gt("age", 25);
- IPage
userPage = userMapper.selectPage(page, queryWrapper); // 调用 selectPage 方法 - List
userList = userPage.getRecords(); - long total = userPage.getTotal();
- System.out.println("Total users (age > 25): " + total);
- for (User user : userList) {
- System.out.println("User: " + user);
- }
SELECT * FROM user WHERE age > 25 LIMIT 10 OFFSET 0
int alwaysUpdateSomeColumnById(T entity);
源码:alwaysUpdateSomeColumnById
功能:这个方法用于在更新操作时,无论实体对象的某些字段是否有变化,都会强制更新这些字段。这在某些业务场景下非常有用,比如更新时间戳字段,确保每次更新操作都会更新该字段。
使用场景:当你需要在每次更新记录时,都更新某些特定的字段(如更新时间、版本号等),即使这些字段在实体对象中没有变化。
int insertBatchSomeColumn(List entityList) ;
源码:insertBatchSomeColumn
功能:这个方法用于批量插入实体对象,但只插入实体对象中指定的某些字段。这在需要批量插入数据,但又不希望插入所有字段时非常有用。
使用场景:当你需要批量插入数据,并且希望只插入实体对象中的部分字段,以提高插入效率或保护敏感数据。
int logicDeleteByIdWithFill(T entity);
源码:logicDeleteByIdWithFill
功能:这个方法用于逻辑删除记录,并填充实体对象中的某些字段。逻辑删除意味着不是真正从数据库中删除记录,而是通过更新某个字段(如 deleted 字段)来标记记录已被删除。
使用场景:当你需要实现逻辑删除功能,并且希望在删除操作时自动填充实体对象中的某些字段(如删除时间、删除人等)。
@TableField、@TableLogic 等)来实现更复杂的功能。通过使用这些选装件,可以进一步扩展 Mybatis-Plus 的功能,满足更多样化的业务需求。
Chain 是 Mybatis-Plus 提供的一种链式编程风格,它允许开发者以更加简洁和直观的方式编写数据库操作代码。Chain 分为 query 和 update 两大类,分别用于查询和更新操作。每类又分为普通链式和 lambda 链式两种风格,其中 lambda 链式提供了类型安全的查询条件构造,但不支持 Kotlin。
提供链式查询操作,可以连续调用方法来构建查询条件。
- // 链式查询 普通
-
- QueryChainWrapper
query(); -
- // 链式查询 lambda 式。注意:不支持 Kotlin
-
- LambdaQueryChainWrapper
lambdaQuery();
示例:
- // 普通链式查询示例
-
- query().eq("name", "John").list(); // 查询 name 为 "John" 的所有记录
-
- // lambda 链式查询示例
-
- lambdaQuery().eq(User::getAge, 30).one(); // 查询年龄为 30 的单条记录
提供链式更新操作,可以连续调用方法来构建更新条件。
- // 链式更改 普通
-
- UpdateChainWrapper
update(); -
- // 链式更改 lambda 式。注意:不支持 Kotlin
-
- LambdaUpdateChainWrapper
lambdaUpdate();
示例:
-
- // 普通链式更新示例
-
- update().set("status", "inactive").eq("name", "John").update(); // 将 name 为 "John" 的记录 status 更新为 "inactive"
-
- // lambda 链式更新示例
-
- User updateUser = new User();
-
- updateUser.setEmail("new.email@example.com");
-
- lambdaUpdate().set(User::getEmail, updateUser.getEmail()).eq(User::getId, 1).update(); // 更新 ID 为 1 的用户的邮箱
QueryChainWrapper 或 UpdateChainWrapper 的实例,允许开发者连续调用方法来构建查询或更新条件。Entity::getId 等方式,避免了字符串硬编码,提高了代码的可读性和安全性。eq、ne、gt、lt、like 等,可以根据实际需求选择合适的方法。通过使用 Chain,开发者可以更加高效地编写数据库操作代码,同时保持代码的清晰和可维护性。
ActiveRecord 模式是一种设计模式,它允许实体类直接与数据库进行交互,实体类既是领域模型又是数据访问对象。在 Mybatis-Plus 中,实体类只需继承 Model 类即可获得强大的 CRUD 操作能力。
注意
使用 ActiveRecord 模式前,需要确保项目中已注入对应实体的 BaseMapper。
继承 Model 类
- import com.baomidou.mybatisplus.extension.activerecord.Model;
-
- public class User extends Model
{ -
- // 实体类的字段定义...
-
- private Long id;
-
- private String name;
-
- private Integer age;
-
- // ... 其他字段和 getter/setter 方法
-
- }
调用 CRUD 方法
- // 创建新用户并插入数据库
-
- User user = new User();
-
- user.setName("John Doe");
-
- user.setAge(30);
-
- boolean isInserted = user.insert(); // 返回值表示操作是否成功
-
- // 查询所有用户
-
- List
allUsers = user.selectAll(); -
- // 根据 ID 更新用户信息
-
- user.setId(1L);
-
- user.setName("Updated Name");
-
- boolean isUpdated = user.updateById(); // 返回值表示操作是否成功
-
- // 根据 ID 删除用户
-
- boolean isDeleted = user.deleteById(); // 返回值表示操作是否成功
insert、selectAll、updateById、deleteById 等方法进行数据库操作。Model 类后,会自动获得一系列数据库操作方法,无需手动编写 SQL 语句。@TableField、@TableId 等)来指定字段与列的映射关系。通过使用 ActiveRecord 模式,开发者可以更加简洁地编写数据库操作代码,同时保持代码的清晰和可维护性。这种模式尤其适合于简单的 CRUD 操作,可以大大减少重复代码的编写。
SimpleQuery 是 Mybatis-Plus 提供的一个工具类,它对 selectList 查询后的结果进行了封装,使其可以通过 Stream 流的方式进行处理,从而简化了 API 的调用。
SimpleQuery 的一个特点是它的 peeks 参数,这是一个可变参数,类型为 Consumer...,意味着你可以连续添加多个操作,这些操作会在查询结果被处理时依次执行。
SimpleQuery 的使用方式可以参考官方测试用例。
注意
使用 SimpleQuery 前,需要确保项目中已注入对应实体的 BaseMapper。
引入 SimpleQuery 工具类
- import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
-
- import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;
-
- import com.baomidou.mybatisplus.core.toolkit.support.SimpleQuery;
使用 SimpleQuery 进行查询
- // 假设有一个 User 实体类和对应的 BaseMapper
-
- List
ids = SimpleQuery.list( -
- Wrappers.lambdaQuery(User.class), // 使用 lambda 查询构建器
-
- User::getId, // 提取的字段,这里是 User 的 id
-
- System.out::println, // 第一个 peek 操作,打印每个用户的 id
-
- user -> userNames.add(user.getName()) // 第二个 peek 操作,将每个用户的名字添加到 userNames 列表中
-
- );
Wrappers.lambdaQuery()),一个用于提取结果的字段(如 User::getId),以及一个或多个 Consumer 类型的 peek 操作。peek 操作可以用于执行任何副作用操作,如打印日志、更新缓存、发送通知等,而不会影响查询结果本身。peek 操作。通过使用 SimpleQuery 工具类,开发者可以更加高效地处理查询结果,同时保持代码的简洁性和可读性。这种工具类尤其适合于需要对查询结果进行复杂处理的场景。
SimpleQuery 的 keyMap 方法提供了一种便捷的方式来查询数据库,并将查询结果封装成一个 Map,其中实体的某个属性作为键(key),实体本身作为值(value)。这个方法还支持在处理查询结果时执行额外的副作用操作,如打印日志或更新缓存。
- // 查询表内记录,封装返回为 Map<属性,实体>
-
-
- // 查询表内记录,封装返回为 Map<属性,实体>,考虑了并行流的情况
-
| 类型 | 参数名 | 描述 |
|---|---|---|
| E | entity | 实体对象类型,即查询结果的实体类型。 |
| A | attribute | 实体属性类型,也是返回的 Map 中键(key)的类型。 |
| LambdaQueryWrapper | wrapper | 支持 lambda 表达式的条件构造器,用于构建查询条件。 |
| SFunction | sFunction | 实体中属性的 getter 方法引用,用于确定 Map 中键(key)的值。 |
| boolean | isParallel | 如果设置为 true,则底层使用并行流执行查询,可以提高处理大量数据时的效率。 |
| Consumer | peeks | 可变参数,用于指定在处理查询结果时执行的额外操作,如打印日志、更新缓存等。 |
- // 假设有一个 User 实体类和对应的 BaseMapper
-
- LambdaQueryWrapper
queryWrapper = new LambdaQueryWrapper<>(); -
- queryWrapper.eq(User::getStatus, "active"); // 查询状态为 "active" 的用户
-
- // 使用 keyMap 方法查询并封装结果
-
- Map
userMap = SimpleQuery.keyMap( -
- queryWrapper, // 查询条件构造器
-
- User::getUsername, // 使用用户名作为键
-
- user -> System.out.println("Processing user: " + user.getUsername()) // 打印处理的用户名
-
- );
-
- // 遍历结果
-
- for (Map.Entry
entry : userMap.entrySet()) { -
- System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
-
- }
keyMap 方法适用于需要根据实体的某个属性快速查找实体的场景。sFunction 参数,你可以指定任何实体属性作为 Map 的键,这使得查询结果的访问更加直观和高效。peeks 参数允许你在处理查询结果时执行额外的副作用操作,这些操作不会影响最终的 Map 结果。isParallel 参数设置为 true 以启用并行流,从而提高查询效率。通过使用 SimpleQuery 的 keyMap 方法,开发者可以更加高效地处理查询结果,并将其封装成易于使用的数据结构,同时还可以执行额外的副作用操作,使代码更加简洁和灵活。
SimpleQuery 的 map 方法提供了一种便捷的方式来查询数据库,并将查询结果封装成一个 Map,其中实体的某个属性作为键(key),另一个属性作为值(value)。这个方法还支持在处理查询结果时执行额外的副作用操作,如打印日志或更新缓存。
- // 查询表内记录,封装返回为 Map<属性,属性>
-
-
- // 查询表内记录,封装返回为 Map<属性,属性>,考虑了并行流的情况
-
| 类型 | 参数名 | 描述 |
|---|---|---|
| E | entity | 实体对象类型,即查询结果的实体类型。 |
| A | attribute | 实体属性类型,作为返回的 Map 中键(key)的类型。 |
| P | attribute | 实体属性类型,作为返回的 Map 中值(value)的类型。 |
| LambdaQueryWrapper | wrapper | 支持 lambda 表达式的条件构造器,用于构建查询条件。 |
| SFunction | keyFunc | 实体中属性的 getter 方法引用,用于确定 Map 中键(key)的值。 |
| SFunction | valueFunc | 实体中属性的 getter 方法引用,用于确定 Map 中值(value)的值。 |
| boolean | isParallel | 如果设置为 true,则底层使用并行流执行查询,可以提高处理大量数据时的效率。 |
| Consumer | peeks | 可变参数,用于指定在处理查询结果时执行的额外操作,如打印日志、更新缓存等。 |
- // 假设有一个 User 实体类和对应的 BaseMapper
-
- LambdaQueryWrapper
queryWrapper = new LambdaQueryWrapper<>(); -
- queryWrapper.eq(User::getStatus, "active"); // 查询状态为 "active" 的用户
-
- // 使用 map 方法查询并封装结果
-
- Map
userMap = SimpleQuery.map( -
- queryWrapper, // 查询条件构造器
-
- User::getUsername, // 使用用户名作为键
-
- User::getAge, // 使用年龄作为值
-
- user -> System.out.println("Processing user: " + user.getUsername()) // 打印处理的用户名
-
- );
-
- // 遍历结果
-
- for (Map.Entry
entry : userMap.entrySet()) { -
- System.out.println("Username: " + entry.getKey() + ", Age: " + entry.getValue());
-
- }
map 方法适用于需要根据实体的某个属性快速查找另一个属性的场景。keyFunc 和 valueFunc 参数,你可以指定任何实体属性作为 Map 的键和值,这使得查询结果的访问更加直观和高效。peeks 参数允许你在处理查询结果时执行额外的副作用操作,这些操作不会影响最终的 Map 结果。isParallel 参数设置为 true 以启用并行流,从而提高查询效率。通过使用 SimpleQuery 的 map 方法,开发者可以更加高效地处理查询结果,并将其封装成易于使用的数据结构,同时还可以执行额外的副作用操作,使代码更加简洁和灵活。
SimpleQuery 的 group 方法提供了一种便捷的方式来查询数据库,并将查询结果按照实体的某个属性进行分组,封装成一个 Map。这个方法还支持在处理查询结果时执行额外的副作用操作,如打印日志或更新缓存。此外,它还允许你使用 Collector 对分组后的集合进行进一步的处理。
-
- // 查询表内记录,封装返回为 Map<属性,List<实体>>
-
- Map
> group(LambdaQueryWrapper wrapper, SFunction sFunction, Consumer... peeks) ; -
- // 查询表内记录,封装返回为 Map<属性,List<实体>>,考虑了并行流的情况
-
- Map
> group(LambdaQueryWrapper wrapper, SFunction sFunction, boolean isParallel, Consumer... peeks) ; -
- // 查询表内记录,封装返回为 Map<属性,分组后对集合进行的下游收集器>
-
- M group(LambdaQueryWrapper
wrapper, SFunction sFunction, Collector super T, A, D> downstream, Consumer... peeks) ; -
- // 查询表内记录,封装返回为 Map<属性,分组后对集合进行的下游收集器>,考虑了并行流的情况
-
- M group(LambdaQueryWrapper
wrapper, SFunction sFunction, Collector super T, A, D> downstream, boolean isParallel, Consumer... peeks) ;
| 类型 | 参数名 | 描述 |
|---|---|---|
| T | entity | 实体对象类型,即查询结果的实体类型。 |
| K | attribute | 实体属性类型,作为返回的 Map 中键(key)的类型。 |
| D | - | 下游收集器返回类型,作为 Map 中值(value)的类型。 |
| A | - | 下游操作中间类型,用于 Collector 的中间结果。 |
| M | - | 最终结束返回的 Map 类型。 |
| LambdaQueryWrapper | wrapper | 支持 lambda 表达式的条件构造器,用于构建查询条件。 |
| SFunction | sFunction | 分组依据,实体中属性的 getter 方法引用,用于确定 Map 中键(key)的值。 |
| Collector | downstream | 下游收集器,用于对分组后的集合进行进一步的处理。 |
| boolean | isParallel | 如果设置为 true,则底层使用并行流执行查询,可以提高处理大量数据时的效率。 |
| Consumer | peeks | 可变参数,用于指定在处理查询结果时执行的额外操作,如打印日志、更新缓存等。 |
- // 假设有一个 User 实体类和对应的 BaseMapper
-
- LambdaQueryWrapper
queryWrapper = new LambdaQueryWrapper<>(); -
- queryWrapper.eq(User::getStatus, "active"); // 查询状态为 "active" 的用户
-
- // 使用 group 方法查询并封装结果,按照用户名分组
-
- Map
> userGroup = SimpleQuery.group( -
- queryWrapper, // 查询条件构造器
-
- User::getUsername, // 使用用户名作为分组键
-
- user -> System.out.println("Processing user: " + user.getUsername()) // 打印处理的用户名
-
- );
-
- // 遍历结果
-
- for (Map.Entry
> entry : userGroup.entrySet()) { -
- System.out.println("Username: " + entry.getKey());
-
- for (User user : entry.getValue()) {
-
- System.out.println(" - User: " + user);
-
- }
-
- }
group 方法适用于需要根据实体的某个属性对查询结果进行分组的场景。sFunction 参数,你可以指定任何实体属性作为分组的依据,这使得查询结果的组织更加灵活。downstream 参数允许你使用 Collector 对分组后的集合进行进一步的处理,如计数、求和、平均值等。peeks 参数允许你在处理查询结果时执行额外的副作用操作,这些操作不会影响最终的 Map 结果。isParallel 参数设置为 true 以启用并行流,从而提高查询效率。通过使用 SimpleQuery 的 group 方法,开发者可以更加高效地处理查询结果,并将其按照特定属性进行分组,同时还可以执行额外的副作用操作,使代码更加简洁和灵活。
SimpleQuery 的 list 方法提供了一种便捷的方式来查询数据库,并将查询结果封装成一个 List,其中列表的元素是实体的某个属性。这个方法还支持在处理查询结果时执行额外的副作用操作,如打印日志或更新缓存。
- // 查询表内记录,封装返回为 List<属性>
-
-
- // 查询表内记录,封装返回为 List<属性>,考虑了并行流的情况
-
| 类型 | 参数名 | 描述 |
|---|---|---|
| E | entity | 实体对象类型,即查询结果的实体类型。 |
| A | attribute | 实体属性类型,作为返回的 List 中元素的类型。 |
| LambdaQueryWrapper | wrapper | 支持 lambda 表达式的条件构造器,用于构建查询条件。 |
| SFunction | sFunction | 实体中属性的 getter 方法引用,用于确定 List 中元素的值。 |
| boolean | isParallel | 如果设置为 true,则底层使用并行流执行查询,可以提高处理大量数据时的效率。 |
| Consumer | peeks | 可变参数,用于指定在处理查询结果时执行的额外操作,如打印日志、更新缓存等。 |
- // 假设有一个 User 实体类和对应的 BaseMapper
-
- LambdaQueryWrapper
queryWrapper = new LambdaQueryWrapper<>(); -
- queryWrapper.eq(User::getStatus, "active"); // 查询状态为 "active" 的用户
-
- // 使用 list 方法查询并封装结果,提取所有用户的用户名
-
- List
userNames = SimpleQuery.list( -
- queryWrapper, // 查询条件构造器
-
- User::getUsername, // 提取用户名作为列表元素
-
- user -> System.out.println("Processing user: " + user.getUsername()) // 打印处理的用户名
-
- );
-
- // 遍历结果
-
- for (String username : userNames) {
-
- System.out.println("Username: " + username);
-
- }
list 方法适用于需要根据实体的某个属性快速获取一个列表的场景。sFunction 参数,你可以指定任何实体属性作为 List 的元素,这使得查询结果的访问更加直观和高效。peeks 参数允许你在处理查询结果时执行额外的副作用操作,这些操作不会影响最终的 List 结果。isParallel 参数设置为 true 以启用并行流,从而提高查询效率。通过使用 SimpleQuery 的 list 方法,开发者可以更加高效地处理查询结果,并将其封装成易于使用的数据结构,同时还可以执行额外的副作用操作,使代码更加简洁和灵活。
Db Kit 是 Mybatis-Plus 提供的一个工具类,它允许开发者通过静态调用的方式执行 CRUD 操作,从而避免了在 Spring 环境下可能出现的 Service 循环注入问题,简化了代码,提升了开发效率。
Db Kit 的完整使用方式可以参考官方测试用例。
注意
Db.saveBatch(数据) 等批量方法进行保存。-
- // 假设有一个 User 实体类和对应的 BaseMapper
-
- // 根据 id 查询单个实体
-
- User user = Db.getById(1L, User.class);
-
- // 根据 id 查询多个实体
-
- List
userList = Db.listByIds(Arrays.asList(1L, 2L, 3L), User.class); -
- // 根据条件构造器查询
-
- LambdaQueryWrapper
queryWrapper = Wrappers.lambdaQuery(User.class) -
- .eq(User::getStatus, "active");
-
- List
activeUsers = Db.list(queryWrapper); -
- // 插入新实体
-
- User newUser = new User();
-
- newUser.setUsername("newUser");
-
- newUser.setAge(25);
-
- boolean isInserted = Db.insert(newUser);
-
- // 根据 id 更新实体
-
- User updateUser = new User();
-
- updateUser.setId(1L);
-
- updateUser.setUsername("updatedUser");
-
- boolean isUpdated = Db.updateById(updateUser);
-
- // 根据条件构造器更新
-
- LambdaUpdateWrapper
updateWrapper = Wrappers.lambdaUpdate(User.class) -
- .set(User::getAge, 30)
-
- .eq(User::getUsername, "updatedUser");
-
- boolean isUpdatedByWrapper = Db.update(null, updateWrapper);
-
- // 根据 id 删除实体
-
- boolean isDeleted = Db.removeById(1L);
-
- // 根据条件构造器删除
-
- LambdaDeleteWrapper
deleteWrapper = Wrappers.lambdaDelete(User.class) -
- .eq(User::getStatus, "inactive");
-
- boolean isDeletedByWrapper = Db.remove(deleteWrapper);
-
- // 批量插入
-
- List
batchUsers = Arrays.asList( -
- new User("user1", 20),
-
- new User("user2", 22),
-
- new User("user3", 24)
-
- );
-
- boolean isBatchInserted = Db.saveBatch(batchUsers);
-
- // 批量更新
-
- List
batchUpdateUsers = Arrays.asList( -
- new User(1L, "user1", 21),
-
- new User(2L, "user2", 23),
-
- new User(3L, "user3", 25)
-
- );
-
- boolean isBatchUpdated = Db.updateBatchById(batchUpdateUsers);
通过使用 Db Kit,开发者可以更加高效地执行数据库操作,同时保持代码的简洁性和可读性。这种工具类尤其适合于简单的 CRUD 操作,可以大大减少重复代码的编写。