MyBatis Plus,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。官网:https://baomidou.com/ ,下面功能及使用都可从官网找到
MyBatis Plus 具有以下特性:
创建Maven工程
添加依赖,这里给一份 springboot3 较为完整依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.20</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
启动类配置 @MapperScan("com.springboot.mapper")
mapper接口扫描注解
配置文件 application.yaml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
username: root
password: root
url: jdbc:mysql:///mybatisplus
driver-class-name: com.mysql.cj.jdbc.Driver
编写 mapper 接口,继承 BaseMapper
,继承mybatis-plus提供的基础Mapper接口,将自带crud方法
部分约定配置:
map-underscore-to-camel-case
:下划线驼峰命名,默认开启
mapper扫描:classpath*:/mapper/**/*.xml
官网:https://baomidou.com/pages/49cc81/#mapper-crud-接口
使用时:ScheduleMapper extends BaseMapper<Schedule>
BaseMapper
接口,为 Mybatis-Plus
启动时自动解析实体表关系映射转换为 Mybatis
内部对象注入容器T
为任意实体对象Serializable
为任意类型主键 Mybatis-Plus
不推荐使用复合主键约定每一张表都有自己的唯一 id
主键Wrapper
为 条件构造器ScheduleMapper
将包含 BaseMapper
中的一系列增删改查及分页查询方法
官网:https://baomidou.com/pages/49cc81/#service-crud-接口
get 查询单行
remove 删除
list 查询集合
page 分页
前缀命名方式区分 Mapper
层避免混淆T
为任意实体对象IBaseService
继承 Mybatis-Plus
提供的基类Wrapper
为 条件构造器Wrapper : 条件构造抽象类,最顶端父类
组装条件:
这里仅介绍基于 Lambda 的条件封装的使用,非 Lambda 自行创建对象 QueryWrapper 用类似方法进行拼接即可
LambdaQueryWrapper
@RequestMapping("query")
public Result<List<Schedule>> query() {
LambdaQueryWrapper<Schedule> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Schedule::getId, 2);
return new Result<>(scheduleService.list(queryWrapper));
}
LambdaUpdateWrapper :使用 set()
方法设置属性
@RequestMapping("update")
public Result<Boolean> update() {
LambdaUpdateWrapper<Schedule> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Schedule::getId, 2).eq(Schedule::getCompleted, 0);
updateWrapper.set(Schedule::getCompleted, 1).set(Schedule::getTitle, "学个P呀");
return new Result<>(scheduleService.update(updateWrapper));
}
配置方法:配置类中,将 MybatisPlusInterceptor
注入 IoC容器中,注入前添加 PaginationInnerInterceptor
拦截器
@MapperScan("com.springboot.mapper")
@SpringBootApplication
public class SpringBootApplicationMain {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplicationMain.class);
}
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加
//interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 如果有多数据源可以不配具体类型 否则都建议配上具体的DbType
return interceptor;
}
}
使用默认实现的分页:scheduleService.page
返回的是 Page
对象,与 new Page
是同一个,只是对象中有了更多信息
@RequestMapping("query")
public Result<Page<Schedule>> query() {
Page<Schedule> page = new Page<>(1,5);
return new Result<>(scheduleService.page(page));
}
Page :该类继承了 IPage
类,实现了 简单分页模型
如果你要实现自己的分页模型可以继承 Page
类或者实现 IPage
类
属性名 | 类型 | 默认值 | 描述 |
---|---|---|---|
records | List | emptyList | 查询数据列表 |
total | Long | 0 | 查询列表总记录数 |
size | Long | 10 | 每页显示条数,默认 10 |
current | Long | 1 | 当前页 |
orders | List | emptyList | 排序字段信息,允许前端传入的时候,注意 SQL 注入问题,可以使用 SqlInjectionUtils.check(...) 检查文本 |
optimizeCountSql | boolean | true | 自动优化 COUNT SQL 如果遇到 jSqlParser 无法解析情况,设置该参数为 false |
optimizeJoinOfCountSql | boolean | true | 自动优化 COUNT SQL 是否把 join 查询部分移除 |
searchCount | boolean | true | 是否进行 count 查询,如果只想查询到列表不要查询总记录数,设置该参数为 false |
maxLimit | Long | 单页分页条数限制 | |
countId | String | xml 自定义 count 查询的 statementId 也可以不用指定在分页 statementId 后面加上 _mpCount 例如分页 selectPageById 指定 count 的查询 statementId 设置为 selectPageById_mpCount 即可默认找到该 SQL 执行 |
自定义分页方法接口:
//传入参数携带Ipage接口
//返回结果为IPage
IPage<User> selectPageVo(IPage<?> page, Integer id);
<select id="selectPageVo" resultType="xxx.xxx.xxx.User">
SELECT * FROM user WHERE id > #{id}
</select>
如果返回类型是 IPage 则入参的 IPage 不能为null,因为 返回的 IPage == 入参的IPage;如果想临时不分页,可以在初始化 IPage 时 size 参数传 <0 的值;
如果返回类型是 List 则入参的 IPage 可以为 null(为 null 则不分页),但需要你手动 入参的IPage.setRecords(返回的 List);
如果 xml 需要从 page 里取值,需要page.属性
获取
注意:多个插件使用的情况,请将分页插件放到 插件执行链
最后面。如在租户插件前面,会出现 COUNT
执行 SQL
不准确问题
详情可参考官网:https://baomidou.com/pages/223848/#tablename
@TableName
:表名注解,标识实体类对应的表@TableId
:主键注解。type指定为 ASSIGN_ID
会调用主键生成默认实现类,以雪花算法生成 ID@TableField
:字段注解(非主键)@Version
:乐观锁注解@TableLogic
:逻辑处理注解,增加注解后删除会进行逻辑删除。默认逻辑删除属性已删除值为 1,未删除值为 0。也可通过 mybatis-plus.global-config.db-config.logic-delete-field
配置全局逻辑删除属性。二者必须配置一个逻辑删除才会生效,注意也会影响默认查询逻辑,查询中会过滤逻辑删除的数据@OrderBy
:内置 SQL 默认指定排序,优先级低于 wrapper 条件查询application.yaml
,从 3.3.0 版本开始,可以忽略不配置 @TableLogic
注解mybatis-plus:
global-config:
db-config:
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
@TableLogic
注解在 idea 插件中搜索 MybatisX
,安装后右侧导航栏(Datasbase
)连接数据源后,即可选择表右键直接生成代码
如果需要生成是子模块代码,这里需要手动填一下子模块目录,目前版本选中子模块不会自动填入,如我这里是 T01
relative package
:实体类的生成包之后需选中 Model
才会生成实体类
目前已有的功能:
插件配置:注入 MybatisPlusInterceptor
对象即可,注入前把需要的对应拦截器添加到该对象中
@MapperScan("com.springboot.mapper")
@SpringBootApplication
public class SpringBootApplicationMain {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplicationMain.class);
}
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加
//interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 如果有多数据源可以不配具体类型 否则都建议配上具体的DbType
return interceptor;
}
}
注意:
使用多个功能需要注意顺序关系,建议使用如下顺序
总结: 对 sql 进行单次改造的优先放入,不对 sql 进行改造的最后放入
具体可参考官网使用:https://baomidou.com/pages/2976a3/
配置完拦截器后在实体类的字段上加上 @Version
注解即可
说明:
newVersion = oldVersion + 1
, newVersion
会回写到 entity
中updateById(id)
与 update(entity, wrapper)
方法update(entity, wrapper)
方法下, wrapper
不能复用!!!