使用若依的时候,打算记录下他的mybatis配置用法,包括了分页,数据范围拦截器,乐观锁插件,字段填充控制器和雪花生成器
配置类
@EnableTransactionManagement(proxyTargetClass = true)
@Configuration
@MapperScan("${mybatis-plus.mapperPackage}")
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 数据范围拦截器
interceptor.addInnerInterceptor(dataFieldInterceptor());
// 数据权限处理
interceptor.addInnerInterceptor(dataPermissionInterceptor());
// 分页插件
interceptor.addInnerInterceptor(paginationInnerInterceptor());
// 乐观锁插件
interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
return interceptor;
}
/**
* 数据权限拦截器
*/
public PlusDataPermissionInterceptor dataPermissionInterceptor() {
return new PlusDataPermissionInterceptor();
}
/**
* 数据范围拦截器
*/
public PlusDataFieldInterceptor dataFieldInterceptor() {
return new PlusDataFieldInterceptor();
}
/**
* 分页插件,自动识别数据库类型
*/
public PaginationInnerInterceptor paginationInnerInterceptor() {
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
// 设置最大单页限制数量,默认 500 条,-1 不受限制
paginationInnerInterceptor.setMaxLimit(-1L);
// 分页合理化
paginationInnerInterceptor.setOverflow(true);
return paginationInnerInterceptor;
}
/**
* 乐观锁插件
*/
public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() {
return new OptimisticLockerInnerInterceptor();
}
/**
* 元对象字段填充控制器
*/
@Bean
public MetaObjectHandler metaObjectHandler() {
return new CreateAndUpdateMetaObjectHandler();
}
/**
* 使用网卡信息绑定雪花生成器
* 防止集群雪花ID重复
*/
@Bean
public IdentifierGenerator idGenerator() {
return new DefaultIdentifierGenerator(NetUtil.getLocalhost());
}
/**
* PaginationInnerInterceptor 分页插件,自动识别数据库类型
* https://baomidou.com/pages/97710a/
* OptimisticLockerInnerInterceptor 乐观锁插件
* https://baomidou.com/pages/0d93c0/
* MetaObjectHandler 元对象字段填充控制器
* https://baomidou.com/pages/4c6bcf/
* ISqlInjector sql注入器
* https://baomidou.com/pages/42ea4a/
* BlockAttackInnerInterceptor 如果是对全表的删除或更新操作,就会终止该操作
* https://baomidou.com/pages/f9a237/
* IllegalSQLInnerInterceptor sql性能规范插件(垃圾SQL拦截)
* IdentifierGenerator 自定义主键策略
* https://baomidou.com/pages/568eb2/
* TenantLineInnerInterceptor 多租户插件
* https://baomidou.com/pages/aef2f2/
* DynamicTableNameInnerInterceptor 动态表名插件
* https://baomidou.com/pages/2a45ff/
*/
}
字段填充处理器
@Slf4j
public class CreateAndUpdateMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
try {
if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity) {
BaseEntity baseEntity = (BaseEntity) metaObject.getOriginalObject();
// Date current = ObjectUtil.isNotNull(baseEntity.getCreateTime())
// ? baseEntity.getCreateTime() : new Date();
Date current = new Date();
baseEntity.setCreateTime(current);
baseEntity.setUpdateTime(current);
String username = StringUtils.isNotBlank(baseEntity.getCreateUser())
? baseEntity.getCreateUser() : getLoginUsername();
// 当前已登录 且 创建人为空 则填充
baseEntity.setCreateUser(username);
// 当前已登录 且 更新人为空 则填充
baseEntity.setUpdateUser(username);
baseEntity.setIsDeleted("N");
}
} catch (Exception e) {
throw new ServiceException("自动注入异常 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
}
}
@Override
public void updateFill(MetaObject metaObject) {
try {
if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity) {
BaseEntity baseEntity = (BaseEntity) metaObject.getOriginalObject();
Date current = new Date();
// 更新时间填充(不管为不为空)
baseEntity.setUpdateTime(current);
// String username = getLoginUsername();
// // 当前已登录 更新人填充(不管为不为空)
// if (StringUtils.isNotBlank(username)) {
// baseEntity.setUpdateUser(username);
// }
String loginUserId = this.getLoginUserId();
if(loginUserId != null){
baseEntity.setUpdateUser(loginUserId);
}
}
} catch (Exception e) {
throw new ServiceException("自动注入异常 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
}
}
/**
* 获取登录用户名
*/
private String getLoginUsername() {
LoginUser loginUser;
try {
loginUser = LoginHelper.getLoginUser();
} catch (Exception e) {
log.warn("自动注入警告 => 用户未登录");
return null;
}
// return loginUser.getUsername();
//为了后续的相关操作
if(loginUser != null){
return loginUser.getUserId();
}
return null;
}
/**
* 获取登录用户名
*/
private String getLoginUserId() {
LoginUser loginUser;
try {
loginUser = LoginHelper.getLoginUser();
} catch (Exception e) {
log.warn("自动注入警告 => 用户未登录");
return null;
}
if(loginUser != null){
return loginUser.getUserId();
}
return null;
// return loginUser.getUsername();
}
}
数据范围处理器,详情见此文
改造若依数据范围拦截器
其余的都是直接new的maven自带的对象的,没有拓展,也就不记录了
附带配置文件,其中有附带逻辑删除的功能
mybatis-plus:
# 不支持多包, 如有需要可在注解配置 或 提升扫包等级
# 例如 com.**.**.mapper
mapperPackage: com.haoyu.**.mapper
# 对应的 XML 文件位置
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.haoyu.**.domain
# 启动时是否检查 MyBatis XML 文件的存在,默认不检查
checkConfigLocation: false
configuration:
# 自动驼峰命名规则(camel case)映射
mapUnderscoreToCamelCase: true
# MyBatis 自动映射策略
# NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射
autoMappingBehavior: PARTIAL
# MyBatis 自动映射时未知列或未知属性处理策
# NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息
autoMappingUnknownColumnBehavior: NONE
# 更详细的日志输出 会有性能损耗 org.apache.ibatis.logging.stdout.StdOutImpl
# 关闭日志记录 (可单纯使用 p6spy 分析) org.apache.ibatis.logging.nologging.NoLoggingImpl
# 默认日志输出 org.apache.ibatis.logging.slf4j.Slf4jImpl
logImpl: org.apache.ibatis.logging.slf4j.Slf4jImpl
global-config:
# 是否打印 Logo banner
banner: true
dbConfig:
# 主键类型
# AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
idType: ASSIGN_ID
# 逻辑已删除值
logicDeleteValue: Y
# 逻辑未删除值
logicNotDeleteValue: N
# 字段验证策略之 insert,在 insert 的时候的字段验证策略
# IGNORED 忽略 NOT_NULL 非NULL NOT_EMPTY 非空 DEFAULT 默认 NEVER 不加入 SQL
insertStrategy: NOT_NULL
# 字段验证策略之 update,在 update 的时候的字段验证策略
updateStrategy: NOT_NULL
# 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件
where-strategy: NOT_NULL
自动填充字典以及带逻辑删除字段的基类,基类里字段里有@TableLogic注解即表示逻辑删除字段
package com.haoyu.common.core.domain;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.haoyu.common.core.domain.entity.SysDepartment;
import com.haoyu.common.core.validate.EditGroup;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Entity基类
*
* @author Lion Li
*/
@Data
public class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
public static final String IS_DELETED_YES="Y";
public static final String IS_DELETED_NO="N";
/**
* ID
*/
@ExcelProperty(value = "ID")
@TableId(value = "id")
protected String id;
/**
* 搜索值
*/
@JsonIgnore
@TableField(exist = false)
protected String searchValue;
/**
* 创建者
*/
@TableField(fill = FieldFill.INSERT,updateStrategy = FieldStrategy.NOT_NULL)
protected String createUser;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
protected Date createTime;
/**
* 更新者
*/
@TableField(fill = FieldFill.INSERT_UPDATE,updateStrategy = FieldStrategy.NOT_NULL)
protected String updateUser;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
protected Date updateTime;
/**
* 删除标志(N代表存在 Y代表删除)
*/
@TableLogic
@TableField(fill = FieldFill.INSERT_UPDATE)
protected String isDeleted;
/**
* 乐观锁标记,不做强制设置,根据需要各自处理
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
protected Long version;
/**
* 请求参数
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@TableField(exist = false)
protected Map<String, Object> params = new HashMap<>();
}
配置里的insertStragy那些是可以在pojo里面再自定义的,不写就默认用配置文件里的,其中FieldStrategy是mybatis自带的类,
/**
* 密码
*/
@TableField(
insertStrategy = FieldStrategy.NOT_EMPTY,
updateStrategy = FieldStrategy.NOT_EMPTY,
whereStrategy = FieldStrategy.NOT_EMPTY
)
private String password;