MyBatis-Plus-Ext
是 MyBatis-Plus
的一个扩展库,尽管MybatisPlus
相比较Mybatis
丝滑了很多,但是,日常使用中,是否偶尔仍会怀念JPA(Hibernate)
的那种纵享丝滑的感受,更好的一心投入业务开发中,如果你也是如此,那么恭喜你发现了MybatisPlusExt
(后文简称MPE
)。
MPE
对MP
做了进一步的拓展封装,即保留MP
原功能,又添加更多有用便捷的功能。同样坚持与MP
对Mybatis
的原则,只做增强不做改变,所以,即便是在使用MPE
的情况下,也完全可以百分百的使用MP
的方式,因此MP
能做的,MPE
不仅能做还能做的更多。
增强功能具体体现在几个方面:免手写Mapper
、自动建表(mysql、pgsql、sqlite)
、数据自动填充(类似JPA的审计)
、关联查询(类似sql中的join)
、冗余数据自动更新
、动态条件
等功能做了补充完善。
在 RuoYi-Vue
项目中集成 MyBatis-Plus-Ext
,可以让我们更加方便地处理一些通用的业务场景。
MyBatis-Plus-Ext
依赖位置:ruoyi-common模块中的pom.xml文件
<dependency>
<groupId>com.tangzc</groupId>
<artifactId>mybatis-plus-ext-boot-starter</artifactId>
<version>最新版本号</version>
</dependency>
请替换最新版本号为实际的版本号,你可以在
Maven
仓库 中查找到最新版本。
由于MyBatis-Plus-Ext
已经引入了MybatisPlus
的包,自己框架中的需要去掉,切记!!!
PS:RuoYi-Vue
自带的pagehelper
插件依赖的mybatis
可能会和mybatis-plus-ext
存在版本冲突,这时可以去掉pagehelper
对mybatis
的依赖,即在ruoyi-common
中做如下处理:
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>
</dependency>
MyBatis-Plus-Ext
MybatisPlusConfig
类在
ruoyi-framework
模块的config
文件中删除MybatisConfig.java
,新增MybatisPlusConfig.java
package com.ruoyi.framework.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
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;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* Mybatis Plus 配置
*
* @author ruoyi
*/
@EnableTransactionManagement(proxyTargetClass = true)
@Configuration
public class MybatisPlusConfig
{
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor()
{
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
interceptor.addInnerInterceptor(paginationInnerInterceptor());
// 乐观锁插件
interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
// 阻断插件
interceptor.addInnerInterceptor(blockAttackInnerInterceptor());
return interceptor;
}
/**
* 分页插件,自动识别数据库类型 https://baomidou.com/guide/interceptor-pagination.html
*/
public PaginationInnerInterceptor paginationInnerInterceptor()
{
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
// 设置数据库类型为mysql
paginationInnerInterceptor.setDbType(DbType.MYSQL);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
paginationInnerInterceptor.setMaxLimit(-1L);
return paginationInnerInterceptor;
}
/**
* 乐观锁插件 https://baomidou.com/guide/interceptor-optimistic-locker.html
*/
public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor()
{
return new OptimisticLockerInnerInterceptor();
}
/**
* 如果是对全表的删除或更新操作,就会终止该操作 https://baomidou.com/guide/interceptor-block-attack.html
*/
public BlockAttackInnerInterceptor blockAttackInnerInterceptor()
{
return new BlockAttackInnerInterceptor();
}
}
这里我们添加了分页插件的配置,MyBatis-Plus-Ext
提供了很多其他的特性,根据需要进行配置即可。
ruoyi-admin
文件application.yml
,修改mybatis
配置为mybatis-plus
,如下:
# MyBatis Plus配置
mybatis-plus:
# 搜索指定包别名
typeAliasesPackage: com.ruoyi.**.domain
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
UsernameAutoFillHandler
类,处理自动填充操作人信息新增一个
UsernameAutoFillHandler.java
,内容如下:
import com.ruoyi.common.utils.SecurityUtils;
import com.tangzc.mpe.annotation.handler.AutoFillHandler;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
@Component
public class UsernameAutoFillHandler implements AutoFillHandler<String> {
/**
* @param object 当前操作的数据对象
* @param clazz 当前操作的数据对象的class
* @param field 当前操作的数据对象上的字段
* @return 当前登录用户id
*/
@Override
public String getVal(Object object, Class<?> clazz, Field field) {
return SecurityUtils.getUsername();
}
}
MyBatis-Plus-Ext
的功能Mapper
和Repository
@AutoMapper
和@AutoRepository
可自动生成对应的Mapper
与Repository
类,无需再编写或生成对应的文件,只需在Service
层直接调用即可。例如:import com.baomidou.mybatisplus.annotation.IdType;
import com.ruoyi.common.handler.UsernameAutoFillHandler;
import com.tangzc.mpe.annotation.InsertOptionDate;
import com.tangzc.mpe.annotation.InsertOptionUser;
import com.tangzc.mpe.annotation.InsertUpdateOptionDate;
import com.tangzc.mpe.annotation.InsertUpdateOptionUser;
import com.tangzc.mpe.automapper.AutoMapper;
import com.tangzc.mpe.automapper.AutoRepository;
import com.tangzc.mpe.autotable.annotation.ColumnComment;
import com.tangzc.mpe.autotable.annotation.ColumnId;
import com.tangzc.mpe.autotable.annotation.Table;
import com.tangzc.mpe.bind.metadata.annotation.BindField;
import com.tangzc.mpe.bind.metadata.annotation.JoinCondition;
import lombok.Data;
@Data
@Table(comment = "文章表")
@AutoMapper
@AutoRepository
public class Article {
@ColumnId(mode = IdType.AUTO, comment = "主键ID")
public Long id;
@ColumnComment("标题")
public String title;
@ColumnComment("内容")
public String content;
@ColumnComment("创建人")
@InsertOptionUser(UsernameAutoFillHandler.class)
public String createBy;
@ColumnComment("创建时间")
@InsertOptionDate
public String createTime;
@ColumnComment("修改人")
@InsertUpdateOptionUser(UsernameAutoFillHandler.class)
public String updateBy;
@ColumnComment("修改时间")
@InsertUpdateOptionDate
public String updateTime;
}
在
Controller
层直接调用(正常情况下应该加一个Service
层,只是为了演示效果直接跳过该层):
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.demo.domain.ArticleRepository;
import com.tangzc.mpe.bind.Binder;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.demo.domain.Article;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 文章Controller
*
* @date 2024-03-16
*/
@RestController
@RequestMapping("/demo/article")
public class ArticleController extends BaseController
{
@Autowired
private ArticleRepository articleRepository;
/**
* 查询文章列表
*/
@GetMapping("/list")
public TableDataInfo list(Article article)
{
startPage();
List<Article> list = articleRepository.list(new LambdaQueryWrapper<Article>()
.like(StringUtils.isNotEmpty(article.getTitle()), Article::getTitle, article.getTitle())
);
Binder.bind(list);
return getDataTable(list);
}
}
@InsertOptionUser
、@InsertOptionDate
、@InsertUpdateOptionUser
、@InsertUpdateOptionDate
等注解即可实现数据的自动填充。 @ColumnComment("创建人")
@InsertOptionUser(UsernameAutoFillHandler.class)
public String createBy;
@ColumnComment("创建时间")
@InsertOptionDate
public String createTime;
@ColumnComment("修改人")
@InsertUpdateOptionUser(UsernameAutoFillHandler.class)
public String updateBy;
@ColumnComment("修改时间")
@InsertUpdateOptionDate
public String updateTime;
这里的
UsernameAutoFillHandler
便是我们在上述讲到的UsernameAutoFillHandler
类。按照上述配置,在新增和修改操作时即可看到数据会自动写入到数据库中。
Mybatis-Plus-Ext
后我们可以基于@BindEntity
或者@BindField
实现这种需求。import com.baomidou.mybatisplus.annotation.IdType;
import com.tangzc.mpe.automapper.AutoMapper;
import com.tangzc.mpe.automapper.AutoRepository;
import com.tangzc.mpe.autotable.annotation.ColumnComment;
import com.tangzc.mpe.autotable.annotation.ColumnId;
import com.tangzc.mpe.autotable.annotation.Table;
import com.tangzc.mpe.bind.metadata.annotation.BindEntity;
import com.tangzc.mpe.bind.metadata.annotation.JoinCondition;
import com.tangzc.mpe.bind.metadata.annotation.JoinOrderBy;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@Table(comment = "作者表")
@AutoMapper
@AutoRepository
@Accessors(chain = true)
@ApiModel(value = "Author", description = "作者")
public class Author {
@ColumnId(mode = IdType.AUTO, comment = "主键ID")
public Long id;
@ApiModelProperty("编号")
@ColumnComment("编号")
public String code;
@ApiModelProperty("姓名")
@ColumnComment("姓名")
public String name;
@ApiModelProperty("地址")
@ColumnComment("地址")
public String address;
@BindEntity(entity = Article.class, conditions = @JoinCondition(selfField = "id", joinField = "createBy"), orderBy = @JoinOrderBy(field = "createTime", isAsc = false))
public List<Article> articleList;
}
在
Controller
层可以通过Binder.bind(obj)
;来处理关联关系,代码如下:
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable Long id) {
Author author = authorRepository.getById(id);
Binder.bind(author);
return AjaxResult.success(author);
}
前端接口返回的信息如下:
{
"msg": "操作成功",
"code": 200,
"data": {
"id": 1,
"code": "11",
"name": "11",
"address": "11",
"articleList": [{
"id": 2,
"title": "测试2",
"content": "<p>test2</p>",
"authorName": null,
"createBy": "1",
"createTime": "2024-03-16 14:13:34",
"updateBy": "admin",
"updateTime": "2024-03-16 14:13:34"
}, {
"id": 1,
"title": "测试1",
"content": "<p>test1</p>",
"authorName": null,
"createBy": "1",
"createTime": "2024-03-16 14:13:21",
"updateBy": "admin",
"updateTime": "2024-03-16 14:19:33"
}]
}
}
通过将 MyBatis-Plus-Ext
集成到 RuoYi-Vue
项目中,我们可以利用其提供的丰富功能来简化开发流程,提高效率。无论是处理动态表名、逻辑删除还是多租户等复杂业务场景,MyBatis-Plus-Ext
都能够提供强大支持。然而,需要注意的是,这些功能的引入可能会对系统的架构和设计产生影响。因此,在使用之前,应该充分考虑并进行合理规划。
请注意,本文提及的代码示例仅供参考,实际实现方式可能会因
RuoYi-Vue
项目版本或MyBatis-Plus-Ext
版本的不同而略有差异。在实际应用中,请根据具体需求和环境进行适当调整和优化。
powered by kaifamiao