全网最新springboot整合mybatis-plus的过程
作者:! 恰同学少年!
一,简介
1. 什么是mybatis-plus
MyBatis-Plus(简称MP)是一个MyBatis的增强工具,旨在在MyBatis的基础上只做增强不做改变,以简化开发、提高效率。MyBatis-Plus保持了MyBatis原有的所有特性,同时增加了一些实用的功能,使得开发者能够更加便捷地进行数据库操作。以下是MyBatis-Plus的一些主要特点和功能:
2.mybatis-plus特点
- 无侵入:引入MyBatis-Plus不会对现有的MyBatis工程产生影响,可以无缝集成到现有的项目中。
- 损耗小:启动时自动注入基本的CRUD操作,几乎不消耗额外的性能,可以直接面向对象操作数据库。
- 强大的CRUD操作:内置通用Mapper、通用Service,通过少量配置即可实现单表的大部分CRUD操作。同时,MyBatis-Plus提供了强大的条件构造器,满足复杂的查询需求。
- 支持Lambda形式调用:利用Lambda表达式方便地编写查询条件,避免了字段名称错误的问题。
- 支持主键自动生成:提供了多种主键生成策略,包括分布式唯一ID生成器,解决了主键问题。
- 支持ActiveRecord模式:通过继承特定的基类,可以像操作对象一样操作数据库。
- 支持自定义全局通用操作:允许开发者注入自己的通用方法。
- 内置分页插件:基于MyBatis的物理分页,开发者可以轻松实现分页查询。
- 支持多种数据库:兼容MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、PostgreSQL、SQL Server等多种数据库。
- 内置性能分析插件:可以输出SQL语句及其执行时间,有助于快速定位慢查询。
- 内置全局拦截插件:提供全表删除、更新操作的智能分析阻断,防止误操作。
二,搭建基本环境
1. 导入基本依赖:
<!--mybatis-plus依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.7</version> </dependency> <!--mysql连接依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <!--连接池依赖--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.18</version> </dependency>
2. 编写配置文件
spring: data: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/mybatis_study?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root type: com.alibaba.druid.pool.DruidDataSource
3. 创建实体类
package org.example.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.util.Date; @TableName("student") public class Student { @TableId(type = IdType.AUTO) private int id; private String studentNumber; private String name; private int gender; // 0 表示女性,1 表示男性 private Date dateOfBirth; // Getters and Setters }
4. 编写controller层
package org.example.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/students") public class StudentController { }
5. 编写service接口
package org.example.service; import com.baomidou.mybatisplus.extension.service.IService; import org.example.pojo.Student; public interface StudentService extends IService<Student> { }
6. 编写service层
package org.example.service.serviceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.example.mapper.StudentMapper; import org.example.pojo.Student; import org.example.service.StudentService; import org.springframework.stereotype.Service; @Service public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService { }
7. 编写mapper层
package org.example.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.example.pojo.Student; @Mapper public interface StudentMapper extends BaseMapper<Student> { }
三,基本知识介绍
1. 基本注解 @TableName
主要用于指定表名,实现实体类与表名的绑定,作用于类上,适用于表名与实体类名称不统一的情况,统一的情况可以不用写。
import com.baomidou.mybatisplus.annotation.TableName; //此处表名称为t_user,实体类名称为User不统一 @TableName("t_user") public class User { private Long id; private String name; private Integer age; private String email; // Getters and Setters }
如果所有的表结构与实体类只是多了一个前缀,可以直接在配置文件里面配置全局的前缀,就可以不使用注解了,两种方式都可以,根据具体场景选择,配置如下:
mybatis-plus: global-config: db-config: table-prefix: t_
@TableId
作用于主键上,指明主键字段,并设置主键的生成方式。
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; @TableName("user_info") // 指定该实体类对应的数据表名 public class UserInfo { //此处value也可以作用于映射,当实体类中 //的id字段名和数据库中的字段名不相同时,可以使用其属性做增强 @TableId(value = "id", type = IdType.AUTO) // 标记为主键,并指定主键生成策略为自增 private Long id; private String username; private String password; // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
注解属性:
value:指定表中主键字段,多用于主键字段和实体类字段不同意
type:id生成策略
对于IdType做出如下说明:
属性 | 说明 | 适用场景 |
---|---|---|
AUTO | 数据库自增主键 | 适用于 MySQL、SQL Server 等支持自增主键的数据库 |
NONE | 不使用任何主键生成策略 | 通常用于主键已经存在的情况 |
ASSIGN_ID | 全局唯一ID(默认基于Snowflake算法生成) | 适用于分布式系统,确保全局唯一性 |
ASSIGN_UUID | 全局唯一UUID,生成32位的字符串 | 适用于需要字符串主键的场景 |
INPUT | 自定义输入主键值 | 适用于某些特殊场景,如导入数据时需要手动指定主键 |
改注解作用众多,多用于表字段和实体类字段名称不统一,做映射处理,也可用于零时字段,不存入数据库,或者是一些字段的填充处理(此处需要编写填充处理器)。
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; import java.util.Date; @TableName("user_info") public class UserInfo { @TableId(value = "id", type = IdType.AUTO) private Long id; @TableField("username") private String username; //此字段不参与查询 @TableField("password", select=false ) private String password; @TableField("email") private String email; //注意,此处应该编写相应的填充逻辑 @TableField(value = "create_time", fill = FieldFill.INSERT) private Date createTime; @TableField(value = "update_time", fill = FieldFill.UPDATE) private Date updateTime; @TableField(exist = false) private String tempField; // 临时字段,不在数据库中 // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } public String getTempField() { return tempField; } public void setTempField(String tempField) { this.tempField = tempField; } }
属性说明:
value:同上面注解一样,用于字段绑定,单个属性的时候可以不写
select:在值为false的情况下用于设置不参查询,查询之后不会返回回来
exist :用于类中的零时变量,数据库中没有该字段,只在java中使用
fill:用于自动填充,比如create_time,update_time这一类,但需要编写相应的处理器
对应处理器代码:
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.util.Date; @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); this.strictInsertFill(metaObject, "updateTime", Date.class, new Date()); } @Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); } }
@TableLogic
该字段用于指定逻辑删除的字段,当执行删除语句时,做更新操作,只改变当前字段的值,设置为删除状态,数据不做真实处理,查询时也只查询状态为未删除的数据(此过程不需要手动实现,mybatis-plus已经帮忙实现了,我们只需要添加字段,设置相应的状态值)注:该字段也需要加入到对应的表里
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; @TableName("user_info") public class UserInfo { @TableId(value = "id", type = IdType.AUTO) private Long id; private String username; private String password; private String email; @TableLogic private Integer isDeleted; // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getIsDeleted() { return isDeleted; } public void setIsDeleted(Integer isDeleted) { this.isDeleted = isDeleted; } }
在配置文件中添加如下配置:
mybatis-plus: global-config: db-config: # 逻辑删除字段名 logic-delete-field: deleted # 逻辑删除字面值:未删除为0 logic-not-delete-value: 0 # 逻辑删除字面值:删除为1 logic-delete-value: 1
@Version
用于配置乐观锁字段,配置之后的更新操作都会先去比较版本,然后在去操作,整体采用cas机制实现。注:该字段也需要加入到对应的表里
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.Version; @TableName("order_info") public class OrderInfo { @TableId(value = "id", type = IdType.AUTO) private Long id; private String orderNo; private Double amount; @Version private Integer version; // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getOrderNo() { return orderNo; } public void setOrderNo(String orderNo) { this.orderNo = orderNo; } public Double getAmount() { return amount; } public void setAmount(Double amount) { this.amount = amount; } public Integer getVersion() { return version; } public void setVersion(Integer version) { this.version = version; } }
此处需加相关的拦截器:
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } }
乐观锁的作用:
乐观锁假设在并发环境中冲突较少,因此在操作数据时不立即获取锁,而是等到提交更新时才检查是否有其他事务修改过数据。如果发现数据已被修改,则更新失败,通常会抛出异常。
特点:在提交更新时检查版本号,如果版本号匹配则更新成功,否则更新失败。
效果:多个事务可以同时读取和处理数据,但在提交更新时会检查版本号,确保数据的一致性。
@Transient
作用于实体类字段,使其不参与数据库的操作,其中包括(Insert,Update,Select),@TableField(exist=false)作用相同,充当零时变量。
@TableName("user") public class User { @TableId(type = IdType.AUTO) private Long id; private String name; @Transient private String tempField; // getters and setters }
2. Wrapper的介绍*
概念:MyBatisPlus提供了QueryWrapper、LambdaQueryWrapper、UpdateWrapper和LambdaUpdateWrapper等条件类,大大简化了我们的开发,可以使代码更加清晰和易于管理,其中包括多条件查询、排序、条件优先级以及有条件时才加入条件的场景,并提供了示例代码展示如何进行数据库查询和更新操作。
大致的条件(此处粗略列举):
方法 | 描述 |
---|---|
eq | 等于 |
ne | 不等于 |
gt | 大于 |
ge | 大于等于 |
lt | 小于 |
le | 小于等于 |
like | 模糊查询 |
notLike | 反向模糊查询 |
in | 在某集合内 |
notIn | 不在某集合内 |
isNull | 为空 |
isNotNull | 不为空 |
between | 在某个区间内 |
notBetween | 不在某个区间内 |
set | 设置字段值 |
QueryWrapper
作用于查询设置查询条件。
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; public class UserService { private UserMapper userMapper; public List<User> getUsersByConditions() { // 创建 QueryWrapper 对象 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); // 添加查询条件 queryWrapper.eq("name", "张三") .ge("age", 18) .orderByDesc("create_time"); // 执行查询 return userMapper.selectList(queryWrapper); } }
此处执行的sql语句:
SELECT * FROM user WHERE name = '张三' AND age >= 18 ORDER BY create_time DESC;
UpdateWrapper
作用于更新设置条件。
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; public class UserService { private UserMapper userMapper; public int updateUserById() { // 创建 UpdateWrapper 对象 UpdateWrapper<User> updateWrapper = new UpdateWrapper<>(); // 添加更新条件 updateWrapper.eq("id", 1); // 创建要更新的对象 User user = new User(); user.setName("李四"); // 执行更新 return userMapper.update(user, updateWrapper); } }
此处执行的sql语句:
UPDATE user SET name = '李四' WHERE id = 1;
LambdaQueryWrapper
在QueryWrapper做了增强,作用一样,用于设置查询条件。
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; public class UserService { private UserMapper userMapper; public List<User> getUsersByLambdaConditions() { // 创建 LambdaQueryWrapper 对象 LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>(); // 添加查询条件 lambdaQueryWrapper.eq(User::getName, "张三") .ge(User::getAge, 18) .orderByDesc(User::getCreateTime); // 执行查询 return userMapper.selectList(lambdaQueryWrapper); } }
此处执行的sql语句:
SELECT * FROM user WHERE name = '张三' AND age >= 18 ORDER BY create_time DESC;
LambdaUpdateWrapper
在UpdateWrapper做了增强,作用一样,用于设置跟新条件。
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; public class UserService { private UserMapper userMapper; public int updateUserByIdWithLambda() { // 创建 LambdaUpdateWrapper 对象 LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>(); // 添加更新条件 lambdaUpdateWrapper.eq(User::getId, 1); // 创建要更新的对象 User user = new User(); user.setName("李四"); // 执行更新 return userMapper.update(user, lambdaUpdateWrapper); } }
此处执行的sql语句:
UPDATE user SET name = '李四' WHERE id = 1;
Wrappers
用于更简便的条件设置
import com.baomidou.mybatisplus.core.toolkit.Wrappers; public class UserService { private UserMapper userMapper; public List<User> getUsersByConditionsUsingWrappers() { // 创建 QueryWrapper 对象 QueryWrapper<User> queryWrapper = Wrappers.<User>query() .eq("name", "张三") .ge("age", 18) .orderByDesc("create_time"); // 执行查询 return userMapper.selectList(queryWrapper); } }
此处执行的sql语句:
SELECT * FROM user WHERE name = '张三' AND age >= 18 ORDER BY create_time DESC;
3. 分页查询
1. 配置相应的拦截器
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } }
2. 实现分页逻辑
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.example.entity.User; import com.example.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserService { @Autowired private UserMapper userMapper; public IPage<User> getUserPage(int current, int size) { // 创建 Page 对象,传入当前页码和每页大小 Page<User> page = new Page<>(current, size); // 创建 QueryWrapper 对象,添加查询条件 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("status", 1) .orderByDesc("create_time"); // 执行分页查询 IPage<User> userPage = userMapper.selectPage(page, queryWrapper); // 获取分页数据 List<User> users = userPage.getRecords(); // 获取总记录数 long total = userPage.getTotal(); // 获取当前页码 int current = userPage.getCurrent(); // 获取每页大小 int size = userPage.getSize(); // 获取总页数 int pages = userPage.getPages(); return userPage; } }
执行对应的sql语句是:
-- 分页查询 SELECT * FROM user WHERE status = 1 ORDER BY create_time DESC LIMIT 0, 10; -- 当前页码为1,每页大小为10
四,结语
在本文中,我们详细介绍了 MyBatis-Plus 的核心功能和使用方法,包括如何配置分页插件、编写分页查询代码、使用各种 Wrapper 构建复杂查询条件等。通过这些内容,相信你已经对 MyBatis-Plus 有了更深入的了解,并能够在实际项目中灵活应用这些功能。
MyBatis-Plus 作为一个强大的 MyBatis 增强工具,不仅简化了数据访问层的开发工作,还提供了许多便捷的功能,如分页查询、链式编程、乐观锁等。它能够显著提升开发效率,减少重复代码,使你的项目更加简洁和高效。
如果你在阅读本文后对 MyBatis-Plus 感兴趣,不妨在自己的项目中尝试一下。实践是最好的老师,通过实际操作,你会更加深刻地理解这些功能的奥妙。同时,也欢迎你在评论区分享你的使用经验和遇到的问题,我们一起探讨和解决。
最后,感谢你花时间阅读本文,希望本文能为你带来帮助。如果你觉得本文对你有帮助,别忘了点赞和分享,让更多的人受益。让我们一起在技术的道路上不断前行,共同成长!
您可能感兴趣的文章:
- SpringBoot整合Mybatis-plus实现多级评论功能
- SpringBoot3整合mybatis-plus的实现
- Springboot3整合Mybatis-plus3.5.3报错问题解决
- SpringBoot整合mybatis-plus实现分页查询功能
- springboot3.2整合mybatis-plus详细代码示例
- SpringBoot3和mybatis-plus整合出现的问题解决办法
- SpringBoot3.2.2整合MyBatis-Plus3.5.5依赖不兼容的问题解决
- SpringBoot整合Mybatis-Plus实现关联查询
- SpringBoot3.3.X整合Mybatis-Plus的实现示例