Mybatis-Plus是苞米豆组织开源的一款增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。具有无侵入、损耗小、强大的CRUD操作、支持主键自动生成等特点,同时也支持各种插件。具体Mybatis-Plus的更多特性可以查看官网:https://baomidou.com/pages/24112f/
目前对于多数据源适配市场上主流的技术主要有两种:Spring-Data-JPA
和Mybatis-Plus
。
Spring-Data-JPA
的底座是依赖于ORM框架Hibernate,查询语句是面向对象而非数据库,所以封装了很强大的CRUD操作,对简单SQL的处理很友好。但是因为是基于Hibernate,如果对其不熟悉的话,学习成本比较高。而且Spring-Data-JPA对复杂查询的支持并不友好。实现复杂查询可以依赖第三方框架QueryDsl,而QueryDsl又是有点面向SQL编程的感觉,感觉是违背了JPA
设计的初衷。
Mybatis-Plus
相比Spring-Data-JPA
提供了很多插件,比如内置分页插件、内置性能分析插件、全局拦截插件,预防误操作,对批处理的支持也比较友好。虽然也有一定的学习成本,但如果本身对Mybatis熟悉的人来说,会比较容易上手。依赖于IDEA插件MybatisX也可以自动生成Entity
、Mapper
、Service
,能够有效提高效率。内置通用Mapper
和Service
,也提供了简单的CRUD操作,但对于复杂查询和连表查询官方并没有给出标准的解决方案。
项目原先使用的是Mybatis,出于改造成本的考虑,最终选型Mybatis-Plus。
引入依赖
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.5.1version>
dependency>
增加Mybatis-Plus相关配置
# 指定当前的运行环境
spring:
profiles:
active: oracle
# Mybatis-Plus配置
mybatis-plus:
# 指定执行类型,默认是SIMPLE
executor-type: batch
# 去掉banner图
global-config:
banner: false
# 指定Mapper.xml扫描的目录
mapper-locations:
- classpath:${spring.profiles.active}/com/keduw/common/cache/mapper/*
- classpath:${spring.profiles.active}/com/keduw/dao/mapper/*
# 指定SQL打印日志为控制台
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
增加插件配置MybatisPlusConfig
,开启事务管理,指定Mapper扫描目录,增加分页插件、动态表名插件以及禁用全表更新插件。
@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@MapperScans({
@MapperScan("com.keduw.dao.mapper"),
@MapperScan("com.keduw.common.cache.dao.mapper")
})
public class MybatisPlusConfig {
@Value("${spring.profiles.active}")
private DbType dbType;
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(dbType));
//禁用全表更新插件
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
//动态表名插件
DynamicTableNameInnerInterceptor innerInterceptor = new DynamicTableNameInnerInterceptor();
innerInterceptor.setTableNameHandler((sql, tableName) -> {
// 获取参数方法
Map<Enum<TableSuffix>, String> paramMap = Parser.getRequestData();
if (MapUtils.isNotEmpty(paramMap)){
String tableSuffix = paramMap.get(TableSuffix.SUFFIX);
tableName += tableSuffix;
}
return tableName;
});
interceptor.addInnerInterceptor(innerInterceptor);
return interceptor;
}
}
如果需要扩展其他插件,可以查看官网文档【插件主体】:https://baomidou.com/pages/2976a3/
项目数据的改造在DAO层,对于上层Controller层和Service层是完全透明的。Mybatis-Plus内置通用的Mapper、Service、Wrapper(条件构造器)实现单表大部分的CRUD场景。核心在于Mapper,通过继承BaseMapper
,便能拿到整个表的元数据TableInfo,有了表的元数据,便可为所欲为。
但整体Mybatis-Plus提供的功能还是比较单一,并不能完全满足网关的改造,主要集中在连表查询和复杂查询。所以在其基础上封装了XwMapper
、XwService
、XwWrapper
以满足个性化查询,Wrapper中调用Mapper的方法,对于上层暴露出去的是Wrapper,最终指定了以下标准:
1:定义的Mapper统一继承XwMapper,对外暴露的条件构造器统一继承XwWrapper
2:对于简单的单表操作,可以通过Mapper或者Wrapper处理
3:对于连表查询(内连接、左连接、右连接),依赖第三方工具类mybatis-plus-join实现;
4:对于能剥离的复杂查询通过自定义SQL注入器实现;
5:没法剥离的复杂查询则从业务角度查看是否能优化SQL语句;
6:如果上面三种都没法处理,那就最后交由xml文件处理。
整体的代码结构如下:
文章主要分享关于Mybatis-Plus使用的配置和分层思考,后续还会有Mybatis-Plus使用过程的一些经验分享,包括单表、分表、连表、复杂查询等内容,有兴趣的可以留下你的关注,互相学习。