写点什么

MyBatis 自定义 SQL 拦截器,java 数据可视化技术

用户头像
极客good
关注
发布于: 刚刚

2. 限制登录用户只能访问当前机构数据。


定义是否开启注解


========


定义是否开启注解, 主要做的一件事情就是是否添加 SQL 拦截器。


// 全局开启


@Retention(RetentionPolicy.RUNTIME)


@Target(ElementType.TYPE)


@Documented


@Import(MyBatisSqlInterceptorConfiguration.class)


public @interface EnableSqlInterceptor {


}


// 自定义注解


@Target({ElementType.METHOD })


@Retention(RetentionPolicy.RUNTIME)


public @interface DataScope {


}


复制代码


注册 SQL 拦截器


=========


注册一个 SQL 拦截器,会对符合条件的 SQL 查询操作进行拦截。


public class MyBatisSqlInterceptorConfiguration implements ApplicationContextAware {


@Override


public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {


SqlSessionFactory sqlSessionFactory = applicationContext.getBean(SqlSessionFactory.class);


sqlSessionFactory.getConfiguration().addInterceptor(new MyBatisInterceptor());


}


}


复制代码


处理逻辑


====


在处理逻辑中,我主要是做一个简单的 limit 1 案例,如果是自己需要做其他的逻辑需要修改


@Slf4j


@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}),


})


public class MyBatisInterceptor implements Interceptor {


private static final Logger LOGGER = LoggerFactory.getLogger(MyBatisInterceptor.class);


@Override


public Object intercept(Invocation invocation) throws Throwable {


// TODO Auto-generated method stub


Object[] args = invocation.getArgs();


MappedStatement ms = (MappedStatement) args[0];


Object parameter = args[1];


RowBounds rowBounds = (RowBounds) args[2];


ResultHandler resultHandler = (ResultHandler) args[3];


Executor executor = (Executor) invocation.getTarget();


CacheKey cacheKey;


BoundSql boundSql;


//由于逻辑关系,只会进入一次


if (args.length == 4) {


//4 个参数时


boundSql = ms.getBoundSql(parameter);


cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);


} else {


//6 个参数时


cacheKey = (CacheKey) args[4];


boundSql = (BoundSql) args[5];


}


DataScope dataScope = getDataScope(ms);


if (Objects.nonNull(dataScope)) {


String origSql = boundSql.getSql();


log.info("origSql : {}", origSql);


// 组装新的 sql


// todo you weaving business


String newSql = origSql + " limit 1";


// 重新 new 一个查询语句对象


BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), newSql,


boundSql.getParameterMappings(), boundSql.getParameterObject());


// 把新的查询放到 statement 里


MappedStatement newMs = newMappedStatement(ms, new BoundSqlSource(newBoundSql));


for (ParameterMapping mapping : boundSql.getParameterMappings()) {


String prop = mapping.getProperty();


if (boundSql.hasAdditionalParameter(prop)) {


newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop));


}


}


args[0] = newMs;


if (args.length == 6) {


args[5] = newMs.getBoundSql(parameter);


}


}


LOGGER.info("mybatis intercept sql:{},Mapper 方法是:{}", boundSql.getSql(), ms.getId());


return invocation.proceed();


}


private MappedStatement newMappedStatement(Mapp


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


edStatement ms, SqlSource newSqlSource) {


MappedStatement.Builder builder = new


MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType());


builder.resource(ms.getResource());


builder.fetchSize(ms.getFetchSize());


builder.statementType(ms.getStatementType());


builder.keyGenerator(ms.getKeyGenerator());


if (ms.getKeyProperties() != null && ms.getKeyProperties().length > 0) {


builder.keyProperty(ms.getKeyProperties()[0]);


}


builder.timeout(ms.getTimeout());

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
MyBatis 自定义 SQL 拦截器,java数据可视化技术