- 自定义注解:标注到需要修改sql语句权限的mapper方法上
package com.pig4cloud.pig.common.mybatis.annotation;import java.lang.annotation.*;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DynamicSQL {String value() default ""; // 可传递参数
}
- mybatisplus3.5 自定义拦截器实现修改sql
package com.pig4cloud.pig.common.mybatis.plugins;import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.pig4cloud.pig.common.mybatis.annotation.DynamicSQL;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;import java.lang.reflect.Method;@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),}
)
public class DynamicSQLInterceptor implements InnerInterceptor {/*** 自定义查询预处理逻辑* @param executor* @param ms* @param parameter* @param rowBounds* @param resultHandler* @param boundSql*/public void beforeQuery(Executor executor, MappedStatement ms,Object parameter, RowBounds rowBounds,ResultHandler resultHandler, BoundSql boundSql) {String originalSql = boundSql.getSql();System.out.println("=========sql拦截器============== originalSql: " + originalSql);String methodId = ms.getId();try {String className = methodId.substring(0, methodId.lastIndexOf("."));Class<?> mapperClass = Class.forName(className);String methodName = methodId.substring(methodId.lastIndexOf(".") + 1);//关键修复:获取Mapper接口声明的参数类型 注意:由于Mapper接口不允许重载,所以我们可以通过方法名唯一确定方法Method[] methods = mapperClass.getMethods();for (Method method : methods) {if (method.getName().equals(methodName)) {// 检查注解if (method.isAnnotationPresent(DynamicSQL.class)) {System.out.println("======有@DynamicSQL注解");DynamicSQL annotation = method.getAnnotation(DynamicSQL.class);String dynamicValue = annotation.value();// 智能添加 WHERE/ANDString newSql=originalSql;if (originalSql.toUpperCase().contains(" WHERE ")) {newSql += " AND del_flag = 1";} else {newSql += " WHERE del_flag = 1";}// 动态修改SQL(示例:添加WHERE条件)boundSql.setAdditionalParameter("dynamicStatus", dynamicValue);PluginUtils.MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);mpBoundSql.sql(newSql);System.out.println("=======动态修改sql之后SQL:======="+boundSql.getSql());}break; // 找到后退出循环}}} catch (ClassNotFoundException e) {throw new RuntimeException("Mapper接口类不存在: " + e.getMessage(), e);}}/*** 自定义更新预处理逻辑* @param executor* @param ms* @param parameter*/@Overridepublic void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) {// 自定义更新预处理逻辑}}
package com.pig4cloud.pig.admin.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pig.admin.api.entity.SysRole;
import com.pig4cloud.pig.common.mybatis.annotation.DynamicSQL;
import org.apache.ibatis.annotations.Mapper;import java.util.List;/*** <p>* Mapper 接口* </p>** @author lengleng* @since 2017-10-29*/
@Mapper
public interface SysRoleMapper extends BaseMapper<SysRole> {/*** 通过用户ID查询角色信息* @param userId 用户ID* @return 角色信息列表*/List<SysRole> listRolesByUserId(Long userId);@DynamicSQL("1")SysRole queryById(Long roleId);}
/** Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.pig4cloud.pig.common.mybatis;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.pig4cloud.pig.common.mybatis.config.MybatisPlusMetaObjectHandler;
import com.pig4cloud.pig.common.mybatis.plugins.DynamicSQLInterceptor;
import com.pig4cloud.pig.common.mybatis.plugins.PigPaginationInnerInterceptor;
import com.pig4cloud.pig.common.mybatis.resolver.SqlFilterArgumentResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.List;/*** MyBatis Plus 统一自动配置类* <p>* 提供SQL过滤器、分页插件及审计字段自动填充等配置** @author lengleng* @date 2025/05/31*/
@Configuration(proxyBeanMethods = false)
public class MybatisAutoConfiguration implements WebMvcConfigurer {/*** 添加SQL过滤器参数解析器,避免SQL注入* @param argumentResolvers 方法参数解析器列表*/@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {argumentResolvers.add(new SqlFilterArgumentResolver());}/*** 创建并配置MybatisPlus分页拦截器* @return 配置好的MybatisPlus拦截器实例*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new DynamicSQLInterceptor());interceptor.addInnerInterceptor(new PigPaginationInnerInterceptor());return interceptor;}/*** 创建并返回MybatisPlusMetaObjectHandler实例,用于审计字段自动填充* @return MybatisPlusMetaObjectHandler实例*/@Beanpublic MybatisPlusMetaObjectHandler mybatisPlusMetaObjectHandler() {return new MybatisPlusMetaObjectHandler();}}