MybatisPlus 是一个基于 Mybatis 的增强型持久层框架,提供了诸多便捷的功能,旨在简化开发流程并提高效率。本文将详细介绍 MybatisPlus 的基本概念、主要特点以及如何快速上手使用 MybatisPlus 进行数据操作。内容涵盖环境搭建、配置核心配置文件、编写 CRUD 操作代码等,帮助开发者快速掌握 MybatisPlus。
MybatisPlus 简介 MybatisPlus 是什么MybatisPlus(简称 MP)是基于 Mybatis 的一个增强型持久层框架,它在 Mybatis 的基础上提供了诸多便捷的功能,旨在简化开发、提高效率。MybatisPlus 扩展了 Mybatis 的功能,提供了如分布式 ID 生成、分页插件等实用工具,同时它也简化了数据层的代码,使得开发者能够更加专注于业务逻辑的实现。
MybatisPlus 的主要特点- 无侵入:基于 Mybatis,提供了增强功能,但不改变 Mybatis 的使用方式,可以无缝接入。
- CRUD 增强:提供了默认的 CRUD 操作实现,简化了开发流程。
- Lambda 语法:支持 Lambda 表达式,提供了一种更简洁的方式来编写 SQL。
- 分页插件:内置了分页插件,支持自定义配置分页方式。
- 条件构造器:内置了条件构造器,支持复杂的条件组合。
- 逻辑删除:提供逻辑删除功能,避免物理删除带来的数据丢失风险。
- 自定义主键生成策略:支持自定义主键生成策略,如雪花算法。
- 乐观锁:提供乐观锁支持,防止数据重复提交。
- 审计功能:提供了自定义填充功能,可以自动填充一些字段,如创建时间、更新时间。
- SQL 执行信息:提供了 SQL 执行效率分析功能,可以方便地获取 SQL 执行详情。
- 代码生成器:提供代码生成器,可以自动生成实体类、Mapper 接口等。
MybatisPlus 在 Mybatis 的基础上进行了功能增强,提供了更多便捷的开发工具和功能,同时保持了 Mybatis 的灵活性和高性能。MybatisPlus 本质上是对 Mybatis 的封装和扩展,二者的关系可以理解为 Mybatis 提供基础的数据持久化操作,而 MybatisPlus 在此基础上增加了许多实用的功能和优化。
快速上手 MybatisPlus MybatisPlus 的环境搭建要使用 MybatisPlus,首先需要在项目中引入 MybatisPlus 相关依赖。以下是使用 Spring Boot 搭建环境的步骤:
- 创建 Spring Boot 项目:
- 选择 Spring Initializr,添加 Spring Web、Mybatis Plus Starter 等依赖。
-
引入 MybatisPlus 依赖:
- 在
pom.xml
或build.gradle
文件中添加 MybatisPlus 依赖。 - Maven 依赖示例:
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.23</version> </dependency>
- Gradle 依赖示例:
implementation 'com.baomidou:mybatis-plus-boot-starter:3.4.3' implementation 'mysql:mysql-connector-java:8.0.23'
- 在
- 配置数据库连接:
- 在
application.properties
或application.yml
文件中配置数据库连接信息。 - 示例配置:
spring.datasource.url=jdbc:mysql://localhost:3306/mybatisplus?useSSL=false&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
- 在
为了更好地使用 MybatisPlus,可以对其进行一些核心配置,如设置全局表名策略、逻辑删除字段等。这些配置通常在 Spring Boot 的 application.properties
或 application.yml
文件中完成。
-
设置全局表名策略:
- 通过
mybatis-plus.global-config.db-config.table-underline-to-camel
配置全局表名下划线转驼峰策略。 - 示例配置:
mybatis-plus.global-config.db-config.table-underline-to-camel=true
- 通过
-
设置逻辑删除字段:
- 通过
mybatis-plus.global-config.db-config.logic-delete-field-name
配置逻辑删除字段。 - 示例配置:
mybatis-plus.global-config.db-config.logic-delete-field-name=deleted
- 通过
- 开启数据库字段填充:
- 通过
mybatis-plus.global-config.db-config.table-field-auto-fill-strategy
配置数据库字段自动填充策略。 - 示例配置:
mybatis-plus.global-config.db-config.table-field-auto-fill-strategy=INSERT:CREATED_TIME,UPDATE:UPDATED_TIME
- 通过
创建一个简单的示例,展示如何使用 MybatisPlus 进行数据操作。
-
创建实体类:
-
创建一个简单的实体类,示例如下:
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.time.LocalDateTime; @TableName("user") public class User { @TableId private Long id; private String name; private String email; private LocalDateTime createdTime; private LocalDateTime updatedTime; }
-
-
创建 Mapper 接口:
-
创建一个 Mapper 接口,继承
BaseMapper
接口,示例如下:import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.demo.entity.User; public interface UserMapper extends BaseMapper<User> { }
-
-
编写 Service 层代码:
-
创建一个 Service 接口及其实现类,示例如下:
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.demo.entity.User; import com.example.demo.mapper.UserMapper; import org.springframework.stereotype.Service; @Service public class UserService extends ServiceImpl<UserMapper, User> { }
-
-
编写 Controller 层代码:
-
创建一个 Controller 类,用于处理 HTTP 请求,示例如下:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.example.demo.service.UserService; @RestController @RequestMapping("/api/user") public class UserController { @Autowired private UserService userService; @GetMapping("/list") public List<User> listAll() { return userService.list(); } }
-
MybatisPlus 提供了简洁的 CRUD 操作接口,可以快速进行增删改查操作。
插入数据
insert
方法用于插入一条数据,示例如下:
User user = new User();
user.setName("张三");
user.setEmail("zhangsan@example.com");
user.setCreatedTime(LocalDateTime.now());
user.setUpdatedTime(user.getCreatedTime());
userService.save(user);
查询数据
list
方法用于查询所有数据,listById
方法用于根据主键查询单条数据,示例如下:
List<User> users = userService.list();
User user = userService.getById(1L);
更新数据
updateById
方法用于根据主键更新数据,示例如下:
User user = userService.getById(1L);
user.setName("李四");
user.setUpdatedTime(LocalDateTime.now());
userService.updateById(user);
删除数据
removeById
方法用于根据主键删除数据,remove
方法用于删除满足条件的数据,示例如下:
userService.removeById(1L);
userService.remove(new QueryWrapper<User>().eq("name", "张三"));
Page 分页插件的使用
MybatisPlus 内置了分页插件,可以方便地进行分页查询。
配置分页插件
在 Spring Boot 的启动类中配置分页插件,示例如下:
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
使用分页插件
在查询时使用 Page
对象进行分页查询,示例如下:
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
Page<User> page = new Page<>(1, 5); // 第一页,每页5条数据
IPage<User> result = userService.page(page, new QueryWrapper<User>());
List<User> users = result.getRecords();
long total = result.getTotal();
自定义 SQL 查询
MybatisPlus 支持自定义 SQL 查询,可以通过 @Select
注解直接编写 SQL 语句。
使用 @Select 注解
在 Mapper 接口中使用 @Select
注解编写 SQL 查询,示例如下:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;
import com.example.demo.entity.User;
public interface UserMapper extends BaseMapper<User> {
@Select("SELECT * FROM user WHERE name = #{name}")
List<User> selectByName(@Param("name") String name);
}
使用 QueryWrapper 实现复杂查询
QueryWrapper
是一个强大的条件构造器,可以方便地组合查询条件,示例如下:
import org.apache.ibatis.annotations.Select;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.entity.User;
Page<User> page = new Page<>(1, 5);
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "张三");
queryWrapper.like("email", "@example");
IPage<User> result = userService.page(page, queryWrapper);
List<User> users = result.getRecords();
MybatisPlus 的动态 SQL
动态 SQL 的概念
动态 SQL 是指根据不同的条件生成不同的 SQL 语句。MybatisPlus 通过 QueryWrapper
、UpdateWrapper
等工具类提供了强大的动态 SQL 生成能力,可以方便地构建复杂的查询和更新语句。
QueryWrapper
和 UpdateWrapper
是 MybatisPlus 提供的两个强大工具类,用于实现复杂的条件查询和更新。
使用 QueryWrapper 进行条件查询
QueryWrapper
支持丰富的条件组合,如 eq
、ne
、gt
、between
等,示例如下:
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.entity.User;
import java.util.List;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "张三");
queryWrapper.gt("age", 20);
queryWrapper.between("created_time", LocalDateTime.of(2022, 1, 1, 0, 0), LocalDateTime.of(2022, 12, 31, 23, 59));
List<User> users = userService.list(queryWrapper);
使用 UpdateWrapper 进行条件更新
UpdateWrapper
用于构建复杂的更新语句,示例如下:
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.demo.entity.User;
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name", "张三");
updateWrapper.set("email", "zhangsan@example.org");
userService.update(updateWrapper, new User());
动态 SQL 在实际项目中的应用
在实际项目中,动态 SQL 的应用场景非常广泛,如权限控制、复杂业务逻辑等,通过动态生成 SQL 语句,可以灵活地满足各种查询需求。
动态 SQL 在权限控制中的应用
在用户权限控制中,可以通过 QueryWrapper
动态构建查询语句,示例如下:
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.entity.User;
public List<User> getUsersWithPermissions(Integer userId) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id", userId);
queryWrapper.eq("status", "active");
return userService.list(queryWrapper);
}
动态 SQL 在复杂业务逻辑中的应用
在处理复杂业务逻辑时,动态生成 SQL 语句可以减少硬编码,提高代码的可维护性,示例如下:
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.demo.entity.User;
public void updateUserInfo(Integer userId, String newName, String newEmail) {
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", userId);
updateWrapper.set("name", newName);
updateWrapper.set("email", newEmail);
userService.update(updateWrapper, new User());
}
MybatisPlus 的高级功能
乐观锁机制
乐观锁机制是一种在更新数据时使用的锁机制,它假设在大多数情况下,数据不会发生冲突,因此不会加锁。如果在更新数据时发现数据已发生变化,则会回滚事务。
配置乐观锁
-
实体类中添加乐观锁字段:
-
在实体类中添加
@Version
注解的字段,示例如下:import com.baomidou.mybatisplus.annotation.Version; @Version private Integer version;
-
-
启用乐观锁插件:
- 在 MybatisPlus 配置文件中启用乐观锁插件,示例如下:
mybatis-plus.global-config.db-config.version-field-name=version
- 在 MybatisPlus 配置文件中启用乐观锁插件,示例如下:
- 使用乐观锁进行更新:
- 在更新操作中,MybatisPlus 会自动处理乐观锁字段,示例如下:
User user = userService.getById(1L); user.setName("李四"); userService.updateById(user);
- 在更新操作中,MybatisPlus 会自动处理乐观锁字段,示例如下:
MybatisPlus 提供了自动填充字段的功能,可以在插入或更新数据时自动填充某些字段,如创建时间和更新时间。
配置自动填充
-
创建自动填充策略类:
-
创建一个实现
MetaObjectHandler
接口的类,实现自动填充逻辑,示例如下:import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import com.baomidou.mybatisplus.annotation.TableField; import com.example.demo.entity.User; public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { setFieldValByName("createdTime", LocalDateTime.now(), metaObject); setFieldValByName("updatedTime", LocalDateTime.now(), metaObject); } @Override public void updateFill(MetaObject metaObject) { setFieldValByName("updatedTime", LocalDateTime.now(), metaObject); } }
-
-
配置自动填充插件:
- 在 MybatisPlus 配置文件中配置自动填充插件,示例如下:
mybatis-plus.global-config.db-config.table-fill-strategy=INSERT:CREATED_TIME,UPDATE:UPDATED_TIME
- 在 MybatisPlus 配置文件中配置自动填充插件,示例如下:
-
使用自动填充:
-
在插入和更新数据时,自动填充的字段将被自动填充,示例如下:
User user = new User(); user.setName("张三"); user.setEmail("zhangsan@example.com"); userService.save(user); user.setName("李四"); userService.updateById(user);
-
逻辑删除是指在删除数据时,不是真正地从数据库中删除数据,而是将数据标记为已删除。逻辑删除可以避免数据丢失的风险,同时也可以方便地恢复数据。
配置逻辑删除
-
实体类中添加逻辑删除字段:
-
在实体类中添加一个逻辑删除字段,并使用
@TableLogic
注解标记该字段,示例如下:import com.baomidou.mybatisplus.annotation.TableLogic; @TableLogic private Boolean deleted;
-
-
启用逻辑删除插件:
- 在 MybatisPlus 配置文件中启用逻辑删除插件,示例如下:
mybatis-plus.global-config.db-config.logic-delete-field-name=deleted
- 在 MybatisPlus 配置文件中启用逻辑删除插件,示例如下:
-
使用逻辑删除进行删除:
- 在删除操作中,逻辑删除字段将被设置为已删除状态,示例如下:
User user = userService.getById(1L); user.setDeleted(true); userService.updateById(user);
- 在删除操作中,逻辑删除字段将被设置为已删除状态,示例如下:
- 查询逻辑未删除的数据:
- 在查询数据时,可以使用
QueryWrapper
排除已删除的数据,示例如下:QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.ne("deleted", true); List<User> users = userService.list(queryWrapper);
- 在查询数据时,可以使用
MybatisPlus 提供了一系列插件以增强 Mybatis 的功能,这些插件可以方便地扩展 Mybatis 的功能,提高开发效率。以下是一些常用的插件:
-
分页插件:
- 分页插件提供了一种简单的方式来实现分页查询,可以方便地获取指定页的数据。
- 使用场景:数据分页显示,如列表页面的分页显示。
-
乐观锁插件:
- 乐观锁插件提供了乐观锁机制,可以在更新数据时避免数据冲突。
- 使用场景:多用户并发操作同一数据时,避免数据冲突。
-
自动填充插件:
- 自动填充插件可以在插入或更新数据时自动填充某些字段,如创建时间和更新时间。
- 使用场景:记录数据的变化时间,方便审计和追踪。
- 逻辑删除插件:
- 逻辑删除插件可以在删除数据时将数据标记为已删除,而不是真正地删除数据。
- 使用场景:避免数据丢失的风险,同时可以方便地恢复数据。
以上提到的插件都可以通过配置文件或代码的方式进行配置和使用。
分页插件的配置与使用
-
配置分页插件:
-
在 Spring Boot 的启动类中配置分页插件,示例如下:
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } }
-
-
使用分页插件:
-
在查询时使用
Page
对象进行分页查询,示例如下:import com.baomidou.mybatisplus.extension.plugins.pagination.Page; Page<User> page = new Page<>(1, 5); // 第一页,每页5条数据 IPage<User> result = userService.page(page, new QueryWrapper<User>()); List<User> users = result.getRecords(); long total = result.getTotal();
-
乐观锁插件的配置与使用
-
配置乐观锁插件:
-
在实体类中添加乐观锁字段,并启用乐观锁插件,示例如下:
import com.baomidou.mybatisplus.annotation.Version; @Version private Integer version;
-
- 使用乐观锁插件:
- 在更新操作中,MybatisPlus 会自动处理乐观锁字段,示例如下:
User user = userService.getById(1L); user.setName("李四"); userService.updateById(user);
- 在更新操作中,MybatisPlus 会自动处理乐观锁字段,示例如下:
自动填充插件的配置与使用
-
配置自动填充插件:
-
创建一个实现
MetaObjectHandler
接口的类,实现自动填充逻辑,并在配置文件中启用自动填充插件,示例如下:import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import com.baomidou.mybatisplus.annotation.TableField; public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { setFieldValByName("createdTime", LocalDateTime.now(), metaObject); setFieldValByName("updatedTime", LocalDateTime.now(), metaObject); } @Override public void updateFill(MetaObject metaObject) { setFieldValByName("updatedTime", LocalDateTime.now(), metaObject); } }
-
-
使用自动填充插件:
-
在插入和更新数据时,自动填充的字段将被自动填充,示例如下:
User user = new User(); user.setName("张三"); user.setEmail("zhangsan@example.com"); userService.save(user); user.setName("李四"); userService.updateById(user);
-
逻辑删除插件的配置与使用
-
配置逻辑删除插件:
-
在实体类中添加逻辑删除字段,并启用逻辑删除插件,示例如下:
import com.baomidou.mybatisplus.annotation.TableLogic; @TableLogic private Boolean deleted;
-
- 使用逻辑删除插件:
- 在删除操作中,逻辑删除字段将被设置为已删除状态,示例如下:
User user = userService.getById(1L); user.setDeleted(true); userService.updateById(user);
- 在删除操作中,逻辑删除字段将被设置为已删除状态,示例如下:
除了使用 MybatisPlus 自带的插件外,还可以根据实际需求开发自定义插件,以扩展 Mybatis 的功能。
开发自定义插件
-
自定义插件接口:
-
实现
MetaObjectHandler
接口或Interceptor
接口,示例如下:import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; public class CustomMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { // 自定义插入填充逻辑 } @Override public void updateFill(MetaObject metaObject) { // 自定义更新填充逻辑 } }
-
-
配置自定义插件:
- 在 MybatisPlus 配置文件中配置自定义插件,示例如下:
mybatis-plus.global-config.db-config.table-fill-strategy=INSERT:CREATED_TIME,UPDATE:UPDATED_TIME
- 在 MybatisPlus 配置文件中配置自定义插件,示例如下:
-
使用自定义插件:
-
在插入和更新数据时,使用自定义插件的逻辑,示例如下:
User user = new User(); user.setName("张三"); user.setEmail("zhangsan@example.com"); userService.save(user); user.setName("李四"); userService.updateById(user);
-
以上是 MybatisPlus 的入门与实战指南,通过本文,你将了解并掌握如何在项目中使用 MybatisPlus 进行高效、便捷的数据操作。希望这些内容能够帮助你更好地理解和应用 MybatisPlus。