提纲
1 顶层pom中引入mybatis-plus
2 ruoyi-common中引入mybatis-plus
3 ruoyi-framework中引入mybatis-plus
4 ruoyi-admin项目下application.yml中配置mybatis-plus
1 顶层pom中引入mybatis-plus
有些文章中说要家pagehelper,但是我发现ruoyi-vue后端项目中已经有pagehelper了,所以就不加了。
<mybatis-plus.version>3.5.2</mybatis-plus.version>
<lombok.version>1.18.12</lombok.version>
<!-- mybatis-plus依赖 -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version>
</dependency>
<!--lombok-->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version>
</dependency>
2 ruoyi-common项目下pom中引入mybatis-plus
<!-- mybatis-plus依赖 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
3 ruoyi-framework下的pom中引入mybatis-plus
<!-- mybatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
ruoyi-framework/src/main/java/com.ruoyi.framework/config中删除MybatisConfig类,增加MybatisPlusConfig类
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.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;@Configuration
public class MybatisPlusConfig {static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";@Autowiredprivate Environment env;public static String setTypeAliasesPackage(String typeAliasesPackage) {ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);List<String> allResult = new ArrayList<String>();try {for (String aliasesPackage : typeAliasesPackage.split(",")) {List<String> result = new ArrayList<String>();aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX+ ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;Resource[] resources = resolver.getResources(aliasesPackage);if (resources != null && resources.length > 0) {MetadataReader metadataReader = null;for (Resource resource : resources) {if (resource.isReadable()) {metadataReader = metadataReaderFactory.getMetadataReader(resource);try {result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());} catch (ClassNotFoundException e) {e.printStackTrace();}}}}if (result.size() > 0) {HashSet<String> hashResult = new HashSet<String>(result);allResult.addAll(hashResult);}}if (allResult.size() > 0) {typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));} else {throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");}} catch (IOException e) {e.printStackTrace();}return typeAliasesPackage;}public Resource[] resolveMapperLocations(String[] mapperLocations) {ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();List<Resource> resources = new ArrayList<Resource>();if (mapperLocations != null) {for (String mapperLocation : mapperLocations) {try {Resource[] mappers = resourceResolver.getResources(mapperLocation);resources.addAll(Arrays.asList(mappers));} catch (IOException e) {// ignore}}}return resources.toArray(new Resource[resources.size()]);}/*** 新版配置** @return*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//能够添加很多拦截器实现mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//乐观锁拦截器mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;}
}
ruoyi-framework/src/main/java/com.ruoyi.framework/下创建mybatisplus包,包下创建MyMetaObjectHandler类
package com.ruoyi.framework.mybatisplus;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.ruoyi.common.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.util.Date;
import java.time.LocalDateTime;@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {public static final String CREATE_BY = "createBy";public static final String CREATE_TIME = "createTime";public static final String UPDATE_BY = "updateBy";public static final String UPDATE_TIME = "updateTime";public static final String DELETED = "delFlag";/*** 插入时的填充策略*/@Overridepublic void insertFill(MetaObject metaObject) {// 起始版本 3.3.0(推荐使用)this.setFieldValByName(CREATE_BY, SecurityUtils.getUsername(), metaObject);this.setFieldValByName(CREATE_TIME, formatDate(metaObject.getSetterType(CREATE_TIME)), metaObject);this.setFieldValByName(UPDATE_BY, SecurityUtils.getUsername(), metaObject);this.setFieldValByName(UPDATE_TIME, formatDate(metaObject.getSetterType(CREATE_TIME)), metaObject);this.setFieldValByName(DELETED, "0", metaObject);}/*** 更新时的填充策略*/@Overridepublic void updateFill(MetaObject metaObject) {this.setFieldValByName(UPDATE_BY, SecurityUtils.getUsername(), metaObject);this.setFieldValByName(UPDATE_TIME, formatDate(metaObject.getSetterType(CREATE_TIME)), metaObject);}/*** 处理特殊日期** @param setterType 参数类型* @return 日期类型*/private Object formatDate(Class<?> setterType) {if (Date.class.equals(setterType)) {return new Date();} else if (LocalDateTime.class.equals(setterType)) {return LocalDateTime.now();} else if (Long.class.equals(setterType)) {return System.currentTimeMillis();}return null;}
}
4 ruoyi-admin项目下application.yml中配置mybatis-plus
ruoyi-admin下application.yml中一定要注释掉mybatis配置,加上mybatis-plus的配置
# MyBatis配置
#mybatis:
# # 搜索指定包别名
# typeAliasesPackage: com.ruoyi.**.domain
# # 配置mapper的扫描,找到所有的mapper.xml映射文件
# mapperLocations: classpath*:mapper/**/*Mapper.xml
# # 加载全局的配置文件
# configLocation: classpath:mybatis/mybatis-config.xml# Mybatis-plus的配置
mybatis-plus:# 对应的 XML 文件位置mapperLocations: classpath*:mapper/**/*Mapper.xml# 实体扫描,多个package用逗号或者分号分隔typeAliasesPackage: com.ruoyi.**.domain# 针对 typeAliasesPackage,如果配置了该属性,则仅仅会扫描路径下以该类作为父类的域对象#typeAliasesSuperType: Class<?># 如果配置了该属性,SqlSessionFactoryBean 会把该包下面的类注册为对应的 TypeHandler#typeHandlersPackage: null# 如果配置了该属性,会将路径下的枚举类进行注入,让实体类字段能够简单快捷的使用枚举属性#typeEnumsPackage: null# 启动时是否检查 MyBatis XML 文件的存在,默认不检查checkConfigLocation: false# 通过该属性可指定 MyBatis 的执行器,MyBatis 的执行器总共有三种:# SIMPLE:该执行器类型不做特殊的事情,为每个语句的执行创建一个新的预处理语句(PreparedStatement)# REUSE:该执行器类型会复用预处理语句(PreparedStatement)# BATCH:该执行器类型会批量执行所有的更新语句executorType: SIMPLE# 指定外部化 MyBatis Properties 配置,通过该配置可以抽离配置,实现不同环境的配置部署configurationProperties: nullconfiguration:# 自动驼峰命名规则(camel case)映射# 如果您的数据库命名符合规则无需使用 @TableField 注解指定数据库字段名mapUnderscoreToCamelCase: true# 默认枚举处理类,如果配置了该属性,枚举将统一使用指定处理器进行处理# org.apache.ibatis.type.EnumTypeHandler : 存储枚举的名称# org.apache.ibatis.type.EnumOrdinalTypeHandler : 存储枚举的索引# com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler : 枚举类需要实现IEnum接口或字段标记@EnumValue注解.defaultEnumTypeHandler: org.apache.ibatis.type.EnumTypeHandler# 当设置为 true 的时候,懒加载的对象可能被任何懒属性全部加载,否则,每个属性都按需加载。需要和 lazyLoadingEnabled 一起使用。aggressiveLazyLoading: true# MyBatis 自动映射策略# NONE:不启用自动映射# PARTIAL:只对非嵌套的 resultMap 进行自动映射# FULL:对所有的 resultMap 都进行自动映射autoMappingBehavior: PARTIAL# MyBatis 自动映射时未知列或未知属性处理策# NONE:不做任何处理 (默认值)# WARNING:以日志的形式打印相关警告信息# FAILING:当作映射失败处理,并抛出异常和详细信息autoMappingUnknownColumnBehavior: NONE# Mybatis一级缓存,默认为 SESSION# SESSION session级别缓存,同一个session相同查询语句不会再次查询数据库# STATEMENT 关闭一级缓存localCacheScope: SESSION# 开启Mybatis二级缓存,默认为 truecacheEnabled: trueglobal-config:# 是否打印 Logo bannerbanner: true# 是否初始化 SqlRunnerenableSqlRunner: falsedbConfig:# 主键类型# AUTO 数据库ID自增# NONE 空# INPUT 用户输入ID# ASSIGN_ID 全局唯一ID# ASSIGN_UUID 全局唯一ID UUIDidType: AUTO# 表名前缀tablePrefix: null# 字段 format,例: %s,(对主键无效)columnFormat: null# 表名是否使用驼峰转下划线命名,只对表名生效tableUnderline: true# 大写命名,对表名和字段名均生效capitalMode: false# 全局的entity的逻辑删除字段属性名logicDeleteField: null# 逻辑已删除值logicDeleteValue: 2# 逻辑未删除值logicNotDeleteValue: 0# 字段验证策略之 insert,在 insert 的时候的字段验证策略# IGNORED 忽略判断# NOT_NULL 非NULL判断# NOT_EMPTY 非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断)# DEFAULT 默认的,一般只用于注解里# NEVER 不加入 SQLinsertStrategy: NOT_NULL# 字段验证策略之 update,在 update 的时候的字段验证策略updateStrategy: NOT_NULL# 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件selectStrategy: NOT_NULL
参考资料
1、https://blog.csdn.net/qq_27480007/article/details/130522139
2、https://www.jb51.net/program/330752f1y.htm