mybatis @Intercepts的用法2:限制sql查询数量

Interceptor 1 :

@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 SelectLimitInterceptor implements Interceptor {

    public SelectLimitInterceptor() {
    }

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        DataSourceType dataSource = DataSourceContextHolder.getDataSource();
        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) {
            boundSql = ms.getBoundSql(parameter);
            cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);

        } else {
            cacheKey = (CacheKey) args[4];
            boundSql = (BoundSql) args[5];

        }

        String sql = boundSql.getSql();
        if (DataSourceEnum.TIMESTEN.equals(dataSource)){
            sql = "Select * from (" + sql + ") t where rownum < 10000";
        } else {
            sql = "Select * from (" + sql + ") t limit 10000";
        }

        ReflectUtil.setFieldValue(boundSql, "sql", sql);
        return executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql);
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

Interceptor 2 : 给默认字段赋值


@Intercepts(
    {
        @Signature(
                type = Executor.class,
                method = "update",
                args = {MappedStatement.class, Object.class}
        )
    }
)
public class FieldInterceptor implements Interceptor {

    public FieldInterceptor() {
    }

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        try {

            Object parameter = invocation.getArgs()[1];
            MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
            SqlCommandType sqlCommandType = ms.getSqlCommandType();
            if (parameter instanceof MapperMethod.ParamMap) {
                MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap)parameter;
                final int size = paramMap.size();

                for (int i = 0; i < size/2; ++i) {
                    this.checkAndSet(paramMap.get("param"+ i), sqlCommandType);
                }

            } else if (parameter instanceof DefaultSqlSession.StrictMap) {
                List collection = (List)((DefaultSqlSession.StrictMap)parameter).get("collection");
                Iterator iterator = collection.iterator();

                while (iterator.hasNext()) {
                    Object obj = iterator.next();
                    this.checkAndSet(obj, sqlCommandType);
                }

            } else {
                this.checkAndSet(parameter, sqlCommandType);
            }

        }catch (Exception e){
            //log
        }

        return invocation.proceed();
    }

    private void checkAndSet(Object parameter, SqlCommandType sqlCommandType){
        if (parameter instanceof BaseDTO && (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType))){
            String currentName = "SYSTEM";

            BaseDTO baseDTO = (BaseDTO)parameter;
            if (StringUtils.isEmpty(baseDTO.getUpdateBy())){
                baseDTO.setUpdateBy(currentName);
            }

            if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)){
                baseDTO.setCreateBy(currentName);
            }

            if (parameter instanceof List) {
                Iterator it = ((List<?>) parameter).iterator();
                while (it.hasNext()) {
                    Object obj = it.next();
                    this.checkAndSet(obj, sqlCommandType);
                }
            }
        }
    }


    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

将Interceptor使用Spring容器管理:


@Configuration
public class MybatisConfig {


    @Bean
    public FieldInterceptor fieldInterceptor(){
        FieldInterceptor interceptor = new FieldInterceptor();
        Properties prop = new Properties();
        prop.put("dialect", "mysql");
        interceptor.setProperties(prop);
        return interceptor;
    }

    @Bean
    public SelectLimitInterceptor selectLimitInterceptor(){
        SelectLimitInterceptor interceptor = new SelectLimitInterceptor();
        Properties prop = new Properties();
        prop.put("dialect", "mysql");
        interceptor.setProperties(prop);
        return interceptor;
    }

    @Bean(name = "dataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        List<Filter> filters = new ArrayList<>();
        filters.add(wallFilter);
        dataSource.setProxyFilters(filters);
        return dataSource;
    }

    @Bean(name = "wallFilter")
    @DependsOn("wallConfig")
    public WallFilter wallFilter(){
        WallFilter interceptor = new WallFilter();
        interceptor.setConfig(wallConfig());
        return interceptor;
    }

    @Bean(name = "wallConfig")
    public WallConfig wallConfig(){
        WallConfig wallConfig = new WallConfig();
        wallConfig.setMultiStatementAllow(true);
        return wallConfig;
    }
}

上面设置filters的地方有点问题,路过的大佬,可以提点建议;

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

time Friend

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值