docs 补充项目注释

This commit is contained in:
AprilWind
2026-06-01 11:50:59 +08:00
parent 941c0b9032
commit 107d3326b4
66 changed files with 1079 additions and 110 deletions
@@ -37,17 +37,36 @@ import java.util.function.Supplier;
@Getter
public class MPJSqlInjector extends DefaultSqlInjector {
/**
* 原始 SQL 注入器,用于兼容项目自定义注入逻辑。
*/
private AbstractSqlInjector sqlInjector;
/**
* 构造 MPJ SQL 注入器。
*/
public MPJSqlInjector() {
}
/**
* 构造带原始注入器的 MPJ SQL 注入器。
*
* @param sqlInjector 原始 SQL 注入器
*/
public MPJSqlInjector(ISqlInjector sqlInjector) {
if (Objects.nonNull(sqlInjector) && sqlInjector instanceof AbstractSqlInjector) {
this.sqlInjector = (AbstractSqlInjector) sqlInjector;
}
}
/**
* 获取 Mapper 可用的注入方法列表。
*
* @param configuration MyBatis 配置
* @param mapperClass Mapper 类型
* @param tableInfo 表信息
* @return 注入方法列表
*/
@Override
public List<AbstractMethod> getMethodList(Configuration configuration, Class<?> mapperClass, TableInfo tableInfo) {
if (!isJoinMapper(mapperClass)) {
@@ -62,6 +81,12 @@ public class MPJSqlInjector extends DefaultSqlInjector {
return methodFilter(super.getMethodList(configuration, mapperClass, tableInfo));
}
/**
* 过滤并追加 MPJ 需要的 SQL 注入方法。
*
* @param list 原始注入方法列表
* @return 过滤后的注入方法列表
*/
private List<AbstractMethod> methodFilter(List<AbstractMethod> list) {
String packageStr = SelectList.class.getPackage().getName();
List<String> methodList = Arrays.asList(
@@ -81,6 +106,11 @@ public class MPJSqlInjector extends DefaultSqlInjector {
return list;
}
/**
* 获取 MPJ 联表操作注入方法。
*
* @return 联表操作注入方法列表
*/
private List<AbstractMethod> getJoinMethod() {
List<AbstractMethod> list = new ArrayList<>();
if (VersionUtils.compare(VersionUtils.getVersion(), "3.5.0") >= 0) {
@@ -103,6 +133,11 @@ public class MPJSqlInjector extends DefaultSqlInjector {
return list;
}
/**
* 获取 MPJ 覆盖 MyBatis-Plus 默认 Wrapper 的注入方法。
*
* @return Wrapper 注入方法列表
*/
private List<AbstractMethod> getWrapperMethod() {
List<AbstractMethod> list = new ArrayList<>();
list.add(new com.github.yulichang.method.mp.Delete());
@@ -117,6 +152,12 @@ public class MPJSqlInjector extends DefaultSqlInjector {
return list;
}
/**
* 将新增注入方法追加到原始列表中,已存在同名方法时不重复追加。
*
* @param source 原始方法列表
* @param addList 待追加方法列表
*/
private void addAll(List<AbstractMethod> source, List<AbstractMethod> addList) {
for (AbstractMethod method : addList) {
if (source.stream().noneMatch(m -> m.getClass().getSimpleName().equals(method.getClass().getSimpleName()))) {
@@ -125,6 +166,12 @@ public class MPJSqlInjector extends DefaultSqlInjector {
}
}
/**
* 初始化 Mapper 注入信息,并为 JoinMapper 注册 MPJ 表映射缓存。
*
* @param builderAssistant Mapper 构建助手
* @param mapperClass Mapper 类型
*/
@Override
public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
super.inspectInject(builderAssistant, mapperClass);
@@ -172,6 +219,12 @@ public class MPJSqlInjector extends DefaultSqlInjector {
return target == null ? null : (Class<?>) target.getActualTypeArguments()[0];
}
/**
* 判断 Mapper 是否继承 MPJ JoinMapper。
*
* @param mapperClass Mapper 类型
* @return true 是 JoinMapper false 不是 JoinMapper
*/
private boolean isJoinMapper(Class<?> mapperClass) {
return JoinMapper.class.isAssignableFrom(mapperClass);
}
@@ -15,6 +15,13 @@ import java.lang.reflect.Proxy;
*/
public class DataPermissionAdvice implements MethodInterceptor {
/**
* 拦截带有数据权限注解的方法调用,设置当前线程的数据权限上下文。
*
* @param invocation 方法调用上下文
* @return 代理方法执行结果
* @throws Throwable 代理方法执行异常
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Object target = invocation.getThis();
@@ -32,6 +39,10 @@ public class DataPermissionAdvice implements MethodInterceptor {
/**
* 获取数据权限注解
*
* @param target 目标对象
* @param method 当前执行方法
* @return 数据权限注解,未配置时返回 null
*/
private DataPermission getDataPermissionAnnotation(Object target, Method method) {
DataPermission dataPermission = method.getAnnotation(DataPermission.class);
@@ -48,6 +59,12 @@ public class DataPermissionAdvice implements MethodInterceptor {
return targetClass.getAnnotation(DataPermission.class);
}
/**
* 从 JDK 动态代理接口上获取数据权限注解。
*
* @param targetClass 代理类
* @return 数据权限注解,未配置时返回 null
*/
private DataPermission getProxyClassDataPermission(Class<?> targetClass) {
for (Class<?> interfaceClass : targetClass.getInterfaces()) {
DataPermission dataPermission = interfaceClass.getAnnotation(DataPermission.class);
@@ -13,6 +13,13 @@ import java.lang.reflect.Proxy;
*/
public class DataPermissionPointcut extends StaticMethodMatcherPointcut {
/**
* 判断当前方法或目标类型是否命中数据权限切点。
*
* @param method 当前执行方法
* @param targetClass 目标类型
* @return true 命中数据权限切点 false 未命中
*/
@Override
public boolean matches(Method method, Class<?> targetClass) {
// 优先匹配方法
@@ -26,6 +33,12 @@ public class DataPermissionPointcut extends StaticMethodMatcherPointcut {
return targetClassRef.isAnnotationPresent(DataPermission.class);
}
/**
* 解析真实目标类型,兼容 MyBatis Mapper 的 JDK 动态代理类。
*
* @param targetClass Spring AOP 传入的目标类型
* @return 真实目标类型或可匹配数据权限注解的接口类型
*/
private Class<?> resolveTargetClass(Class<?> targetClass) {
if (!Proxy.isProxyClass(targetClass)) {
return targetClass;
@@ -12,19 +12,39 @@ import org.springframework.aop.support.AbstractPointcutAdvisor;
@SuppressWarnings("all")
public class DataPermissionPointcutAdvisor extends AbstractPointcutAdvisor {
/**
* 数据权限通知逻辑。
*/
private final Advice advice;
/**
* 数据权限切点匹配器。
*/
private final Pointcut pointcut;
/**
* 构造数据权限切面定义。
*/
public DataPermissionPointcutAdvisor() {
this.advice = new DataPermissionAdvice();
this.pointcut = new DataPermissionPointcut();
}
/**
* 获取数据权限切点。
*
* @return 数据权限切点
*/
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
/**
* 获取数据权限通知。
*
* @return 数据权限通知
*/
@Override
public Advice getAdvice() {
return this.advice;
@@ -9,6 +9,8 @@ import java.util.Set;
/**
* 当前请求的数据权限访问上下文
*
* @param perms 当前请求接口权限标识集合
* @param roleKeys 当前请求角色标识集合
* @author Lion Li
*/
public record DataPermissionAccess(Set<String> perms, Set<String> roleKeys) implements Serializable {
@@ -16,6 +18,9 @@ public record DataPermissionAccess(Set<String> perms, Set<String> roleKeys) impl
@Serial
private static final long serialVersionUID = 1L;
/**
* 空访问上下文,表示不按接口权限或角色约束数据权限角色。
*/
public static final DataPermissionAccess EMPTY = new DataPermissionAccess(Set.of(), Set.of());
/**
@@ -33,9 +33,21 @@ import java.util.function.Function;
@SuppressWarnings("unchecked")
public interface BaseMapperPlus<T, V> extends BaseMapper<T> {
/**
* Mapper 日志对象。
*/
Log log = LogFactory.getLog(BaseMapperPlus.class);
/**
* Mapper 泛型类型缓存,避免重复解析实体与 VO 类型。
*/
ClassValue<Class<?>[]> TYPE_ARGUMENT_CACHE = new ClassValue<>() {
/**
* 解析指定 Mapper 类型的实体与 VO 泛型。
*
* @param type Mapper 类型
* @return 泛型类型数组
*/
@Override
protected Class<?>[] computeValue(Class<?> type) {
return GenericTypeUtils.resolveTypeArguments(type, BaseMapperPlus.class);
@@ -40,8 +40,19 @@ public class LambdaCrudChainWrapper<T, V> extends AbstractLambdaWrapper<T, Lambd
Update<LambdaCrudChainWrapper<T, V>, SFunction<T, ?>>,
LambdaQueryCondition<T, LambdaCrudChainWrapper<T, V>> {
/**
* 当前链式操作绑定的 Mapper。
*/
private final BaseMapperPlus<T, V> crudMapper;
/**
* 更新 SET 片段集合。
*/
private final List<String> sqlSet;
/**
* 查询字段 SQL 片段。
*/
private SharedString sqlSelect = new SharedString();
/**
@@ -59,7 +59,10 @@ public class PageQuery implements Serializable {
public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;
/**
* 构建分页对象
* 构建分页对象
*
* @param <T> 分页记录类型
* @return MyBatis-Plus 分页对象
*/
public <T> Page<T> build() {
Integer pageNum = ObjectUtil.defaultIfNull(getPageNum(), DEFAULT_PAGE_NUM);
@@ -77,7 +80,7 @@ public class PageQuery implements Serializable {
/**
* 构建排序
*
* <p>
* 支持的用法如下:
* {isAsc:"asc",orderByColumn:"id"} order by id asc
* {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc
@@ -11,8 +11,16 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
*/
class AggregateLambdaQueryWrapper<T> extends LambdaQueryWrapper<T> {
/**
* 追加后的聚合查询字段 SQL。
*/
private String aggregateSqlSelect;
/**
* 构造聚合查询包装器。
*
* @param entityClass 实体类型
*/
AggregateLambdaQueryWrapper(Class<T> entityClass) {
super(entityClass);
}
@@ -75,6 +83,11 @@ class AggregateLambdaQueryWrapper<T> extends LambdaQueryWrapper<T> {
return columnToString(column);
}
/**
* 获取最终查询字段 SQL。
*
* @return 查询字段 SQL
*/
@Override
public String getSqlSelect() {
if (aggregateSqlSelect != null) {
@@ -83,6 +96,9 @@ class AggregateLambdaQueryWrapper<T> extends LambdaQueryWrapper<T> {
return super.getSqlSelect();
}
/**
* 清空查询条件与聚合查询字段。
*/
@Override
public void clear() {
super.clear();
@@ -16,8 +16,14 @@ import java.util.regex.Pattern;
*/
public final class AggregateSelectUtils {
/**
* 查询别名合法性匹配规则。
*/
private static final Pattern ALIAS_PATTERN = Pattern.compile("[A-Za-z_][A-Za-z0-9_]*");
/**
* 工具类不允许实例化。
*/
private AggregateSelectUtils() {
}
@@ -916,12 +916,28 @@ public final class LambdaJoinQueryBuilder<T> {
return wrapper;
}
/**
* 构建使用占位参数模式的子查询。
*
* @param entityClass 子查询实体类型
* @param consumer 子查询构造逻辑
* @param <Q> 子查询实体类型
* @return 子查询构造器
*/
private <Q> SubQuery<Q> buildPlaceholderSubQuery(Class<Q> entityClass, Consumer<SubQuery<Q>> consumer) {
SubQuery<Q> subQuery = SubQuery.ofPlaceholders(entityClass);
consumer.accept(subQuery);
return subQuery;
}
/**
* 解析带表别名的数据库列名。
*
* @param alias 表别名
* @param column 字段引用
* @param <S> 字段所属实体类型
* @return 表别名限定列名
*/
private <S> String qualifiedColumn(String alias, SFunction<S, ?> column) {
return AggregateSelectUtils.checkAlias(alias) + StringPool.DOT + ColumnCache.getMapField(LambdaUtils.getEntityClass(column))
.get(LambdaUtils.getName(column)).getColumn();
@@ -9,6 +9,9 @@ import com.github.yulichang.toolkit.JoinWrappers;
*/
public final class QueryBuilder {
/**
* 工具入口类不允许实例化。
*/
private QueryBuilder() {
}
@@ -32,8 +32,16 @@ public enum SqlAggregateFunction {
*/
COUNT("COUNT");
/**
* 聚合函数名称。
*/
private final String name;
/**
* 构造 SQL 聚合函数。
*
* @param name 聚合函数名称
*/
SqlAggregateFunction(String name) {
this.name = name;
}
@@ -51,18 +51,58 @@ import java.util.stream.Collectors;
*/
public final class SubQuery<T> {
/**
* 子查询实体类型。
*/
private final Class<T> entityClass;
/**
* 外层查询传入的 SQL 参数格式化器。
*/
private final SqlParamFormatter paramFormatter;
/**
* 是否使用 {@code {0}} 形式的占位参数模式。
*/
private final boolean placeholderParamMode;
/**
* 子查询 SELECT 字段集合。
*/
private final List<String> selects = new ArrayList<>();
/**
* 子查询 WHERE 条件集合。
*/
private final List<String> conditions = new ArrayList<>();
/**
* 占位参数模式下收集的参数值集合。
*/
private final List<Object> params = new ArrayList<>();
/**
* 是否追加逻辑删除条件。
*/
private boolean withLogicDelete = true;
/**
* 构造子查询。
*
* @param entityClass 子查询实体类型
* @param paramFormatter SQL 参数格式化器
*/
private SubQuery(Class<T> entityClass, SqlParamFormatter paramFormatter) {
this(entityClass, paramFormatter, false);
}
/**
* 构造子查询。
*
* @param entityClass 子查询实体类型
* @param paramFormatter SQL 参数格式化器
* @param placeholderParamMode 是否使用占位参数模式
*/
private SubQuery(Class<T> entityClass, SqlParamFormatter paramFormatter, boolean placeholderParamMode) {
this.entityClass = entityClass;
this.paramFormatter = paramFormatter;
@@ -381,16 +421,37 @@ public final class SubQuery<T> {
return params.toArray();
}
/**
* 追加聚合查询字段。
*
* @param function 聚合函数
* @param column 聚合字段
* @return 当前子查询构造器
*/
private SubQuery<T> selectAggregate(SqlAggregateFunction function, SFunction<T, ?> column) {
selects.add(function.format(columnName(column)));
return this;
}
/**
* 追加普通比较条件。
*
* @param column 条件字段
* @param operator 比较操作符
* @param value 条件值
* @return 当前子查询构造器
*/
private SubQuery<T> condition(SFunction<T, ?> column, String operator, Object value) {
conditions.add(columnName(column) + StringPool.SPACE + operator + StringPool.SPACE + formatParam(value));
return this;
}
/**
* 格式化 SQL 参数。
*
* @param value 参数值
* @return SQL 参数占位符
*/
private String formatParam(Object value) {
if (placeholderParamMode) {
params.add(value);
@@ -400,10 +461,20 @@ public final class SubQuery<T> {
return paramFormatter.format(value);
}
/**
* 获取子查询实体表名。
*
* @return 表名
*/
private String tableName() {
return tableInfo().getTableName();
}
/**
* 构建最终 WHERE 条件集合。
*
* @return WHERE 条件集合
*/
private List<String> buildWhereConditions() {
List<String> whereConditions = new ArrayList<>();
String logicDeleteSql = logicDeleteSql();
@@ -414,6 +485,11 @@ public final class SubQuery<T> {
return whereConditions;
}
/**
* 获取逻辑删除 SQL 条件。
*
* @return 逻辑删除 SQL 条件,禁用时返回空字符串
*/
private String logicDeleteSql() {
if (!withLogicDelete) {
return StringPool.EMPTY;
@@ -421,12 +497,23 @@ public final class SubQuery<T> {
return tableInfo().getLogicDeleteSql(false, true);
}
/**
* 获取子查询实体对应的 MyBatis-Plus 表信息。
*
* @return 表信息
*/
private TableInfo tableInfo() {
TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
Assert.notNull(tableInfo, "无法获取实体表信息: %s", entityClass.getName());
return tableInfo;
}
/**
* 获取外层查询字段的表名限定列名。
*
* @param column 外层查询字段
* @return 表名限定列名
*/
private String qualifiedColumnName(SFunction<?, ?> column) {
Class<?> columnEntityClass = LambdaUtils.extract(column).getInstantiatedClass();
TableInfo tableInfo = TableInfoHelper.getTableInfo(columnEntityClass);
@@ -434,6 +521,12 @@ public final class SubQuery<T> {
return tableInfo.getTableName() + StringPool.DOT + columnName(column);
}
/**
* 从 Lambda 字段引用解析数据库列名。
*
* @param column 字段引用
* @return 数据库列名
*/
private static String columnName(SFunction<?, ?> column) {
LambdaMeta meta = LambdaUtils.extract(column);
String fieldName = PropertyNamer.methodToProperty(meta.getImplMethodName());
@@ -55,6 +55,9 @@ public enum DataScopeType {
*/
DEPT_AND_CHILD_OR_SELF("6", " #{#deptName} IN ( #{@sdss.getDeptAndChild( #user.deptId )} ) OR #{#userName} = #{#user.userId} ", " 1 = 0 ");
/**
* 数据权限类型编码
*/
private final String code;
/**
@@ -51,7 +51,12 @@ public class PlusDataPermissionHandler {
* spel 解析器
*/
private final ExpressionParser parser = new SpelExpressionParser();
/**
* SpEL 模板解析上下文
*/
private final ParserContext parserContext = new TemplateParserContext();
/**
* bean解析器 用于处理 spel 表达式中对 bean 的调用
*/
@@ -189,6 +194,11 @@ public class PlusDataPermissionHandler {
return currentUser;
}
/**
* 获取当前请求已解析的数据权限访问控制对象
*
* @return 数据权限访问控制对象
*/
private DataPermissionAccess currentAccess() {
DataPermissionAccess access = DataPermissionHelper.getAccess();
if (access != null) {
@@ -199,6 +209,13 @@ public class PlusDataPermissionHandler {
return resolvedAccess;
}
/**
* 根据当前接口权限约束筛选参与数据权限计算的角色
*
* @param user 当前登录用户
* @param access 当前接口访问约束
* @return 参与数据权限计算的角色集合
*/
private List<RoleDTO> scopeRoles(LoginUser user, DataPermissionAccess access) {
List<RoleDTO> roles = user.getRoles();
if (!access.constrained()) {
@@ -232,6 +249,11 @@ public class PlusDataPermissionHandler {
return new ArrayList<>(roleMap.values());
}
/**
* 从当前请求处理器上解析接口权限和角色约束
*
* @return 数据权限访问控制对象
*/
private DataPermissionAccess resolveAccess() {
HttpServletRequest request = ServletUtils.getRequest();
if (request == null) {
@@ -258,6 +280,14 @@ public class PlusDataPermissionHandler {
return new DataPermissionAccess(Set.copyOf(perms), Set.copyOf(roleKeys));
}
/**
* 优先从方法再从类上查找指定注解
*
* @param handlerMethod 当前请求处理方法
* @param annotationType 注解类型
* @param <A> 注解类型
* @return 注解对象未配置时返回 null
*/
private <A extends Annotation> A findAnnotation(HandlerMethod handlerMethod, Class<A> annotationType) {
A annotation = AnnotationUtil.getAnnotation(handlerMethod.getMethod(), annotationType);
if (annotation != null) {
@@ -266,6 +296,12 @@ public class PlusDataPermissionHandler {
return AnnotationUtil.getAnnotation(handlerMethod.getBeanType(), annotationType);
}
/**
* 将注解中的字符串数组转换为去空后的集合
*
* @param values 注解值数组
* @return 字符串集合
*/
private Set<String> toSet(String[] values) {
if (values == null || values.length == 0) {
return Set.of();
@@ -299,8 +335,17 @@ public class PlusDataPermissionHandler {
@AllArgsConstructor
private static class NullSafeStandardEvaluationContext extends StandardEvaluationContext {
/**
* 变量值为空时返回的默认值
*/
private final Object defaultValue;
/**
* 查找 SpEL 变量变量为空时返回默认值
*
* @param name 变量名
* @return 变量值或默认值
*/
@Override
public Object lookupVariable(String name) {
Object obj = super.lookupVariable(name);
@@ -319,19 +364,49 @@ public class PlusDataPermissionHandler {
@AllArgsConstructor
private static class NullSafePropertyAccessor implements PropertyAccessor {
/**
* 原始属性访问器
*/
private final PropertyAccessor delegate;
/**
* 属性值为空时返回的默认值
*/
private final Object defaultValue;
/**
* 获取当前访问器支持的目标类型
*
* @return 目标类型数组
*/
@Override
public Class<?>[] getSpecificTargetClasses() {
return delegate.getSpecificTargetClasses();
}
/**
* 判断指定属性是否可读
*
* @param context 表达式上下文
* @param target 目标对象
* @param name 属性名
* @return true 可读 false 不可读
* @throws AccessException 属性访问异常
*/
@Override
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
return delegate.canRead(context, target, name);
}
/**
* 读取属性值属性值为空时返回默认值
*
* @param context 表达式上下文
* @param target 目标对象
* @param name 属性名
* @return 属性值
* @throws AccessException 属性访问异常
*/
@Override
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
TypedValue value = delegate.read(context, target, name);
@@ -342,11 +417,29 @@ public class PlusDataPermissionHandler {
return value;
}
/**
* 判断指定属性是否可写
*
* @param context 表达式上下文
* @param target 目标对象
* @param name 属性名
* @return true 可写 false 不可写
* @throws AccessException 属性访问异常
*/
@Override
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
return delegate.canWrite(context, target, name);
}
/**
* 写入属性值
*
* @param context 表达式上下文
* @param target 目标对象
* @param name 属性名
* @param newValue 新属性值
* @throws AccessException 属性访问异常
*/
@Override
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
delegate.write(context, target, name, newValue);
@@ -15,6 +15,12 @@ import org.dromara.common.core.utils.reflect.ReflectUtils;
*/
public class PlusPostInitTableInfoHandler implements PostInitTableInfoHandler {
/**
* 表信息初始化后统一调整逻辑删除开关
*
* @param tableInfo 表信息
* @param configuration MyBatis 配置
*/
@Override
public void postTableInfo(TableInfo tableInfo, Configuration configuration) {
String flag = SpringUtils.getProperty("mybatis-plus.enableLogicDelete", "true");
@@ -27,7 +27,14 @@ import java.util.concurrent.ConcurrentHashMap;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DataBaseHelper {
/**
* 动态数据源路由对象
*/
private static final DynamicRoutingDataSource DS = SpringUtils.getBean(DynamicRoutingDataSource.class);
/**
* 数据源对应数据库类型缓存
*/
private static final Map<String, DataBaseType> DB_TYPE_CACHE = new ConcurrentHashMap<>();
/**
@@ -22,9 +22,19 @@ import java.util.function.Supplier;
@SuppressWarnings("unchecked")
public class DataPermissionHelper {
/**
* Sa-Token Storage 中保存数据权限上下文的键
*/
private static final String DATA_PERMISSION_KEY = "data:permission";
/**
* 数据权限访问控制对象在上下文中的键
*/
private static final String ACCESS_KEY = "data:permission:access";
/**
* 当前线程正在执行的 Mapper 数据权限注解缓存
*/
private static final ThreadLocal<DataPermission> PERMISSION_CACHE = new ThreadLocal<>();
/**
@@ -17,6 +17,9 @@ import java.util.Deque;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
final class DataPermissionIgnoreContext {
/**
* 数据权限忽略状态栈用于支持嵌套忽略并恢复进入前状态
*/
private static final ThreadLocal<Deque<Boolean>> DATA_PERMISSION_STACK = ThreadLocal.withInitial(ArrayDeque::new);
/**
@@ -53,6 +56,11 @@ final class DataPermissionIgnoreContext {
}
}
/**
* 获取 MyBatis-Plus 当前线程中的拦截器忽略策略
*
* @return 当前忽略策略未设置时返回 null
*/
private static IgnoreStrategy getIgnoreStrategy() {
Object ignoreStrategyLocal = ReflectUtils.getStaticFieldValue(ReflectUtils.getField(InterceptorIgnoreHelper.class, "IGNORE_STRATEGY_LOCAL"));
if (ignoreStrategyLocal instanceof ThreadLocal<?> ignoreStrategyThreadLocal
@@ -62,6 +70,12 @@ final class DataPermissionIgnoreContext {
return null;
}
/**
* 判断当前忽略策略是否只忽略了数据权限插件
*
* @param ignoreStrategy 忽略策略
* @return true 仅忽略数据权限 false 还忽略了其他插件能力
*/
private static boolean isOnlyDataPermissionIgnored(IgnoreStrategy ignoreStrategy) {
return !Boolean.TRUE.equals(ignoreStrategy.getDynamicTableName())
&& !Boolean.TRUE.equals(ignoreStrategy.getBlockAttack())
@@ -35,6 +35,9 @@ import java.util.List;
@Slf4j
public class PlusDataPermissionInterceptor extends BaseMultiTableInnerInterceptor implements InnerInterceptor {
/**
* 数据权限 SQL 处理器
*/
private final PlusDataPermissionHandler dataPermissionHandler = new PlusDataPermissionHandler();
/**
@@ -169,4 +172,3 @@ public class PlusDataPermissionInterceptor extends BaseMultiTableInnerIntercepto
return handler.getSqlSegment(table, where, whereSegment);
}
}
@@ -14,6 +14,9 @@ import org.dromara.common.core.utils.SpringUtils;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class IdGeneratorUtil {
/**
* MyBatis-Plus 主键生成器
*/
private static final IdentifierGenerator GENERATOR = SpringUtils.getBean(IdentifierGenerator.class);
/**