mybatis Interceptor拦截器实现自定义扩展查询兼容mybatis plus

位置:首页>文章>详情   分类: 教程分享 > Java教程   阅读(1814)   2024-03-03 11:18:12

mybatis Interceptor拦截器实现自定义扩展查询兼容mybatis plus
 

@Intercepts({
        @Signature(type = Executor.class,method = "query",args = {MappedStatement.class,Object.class, RowBounds.class, ResultHandler.class})
})
@Slf4j
public class MybatisListSelectFilterInterceptor implements Interceptor {

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

        // 获取原始sql语句
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        Object parameter = invocation.getArgs()[1];
        if (parameter instanceof SelectFilter){
            BoundSql boundSql = mappedStatement.getBoundSql(parameter);
            SelectFilter selectFilter =(SelectFilter)boundSql.getParameterObject();
            dealSelectFilter(mappedStatement,parameter,selectFilter,invocation);
        }
        // 继续执行
        Object result = invocation.proceed();
        return result;
    }

    private void dealSelectFilter(MappedStatement mappedStatement,Object parameter,SelectFilter selectFilter,Invocation invocation){
        BoundSql boundSql = mappedStatement.getBoundSql(parameter);
        String oldsql = boundSql.getSql();
        log.info("old:"+oldsql);

        Class entityClass = selectFilter.getEntityClass();
        TableName tableNameAnnotation = (TableName) entityClass.getDeclaredAnnotation(TableName.class);
        String tableName = tableNameAnnotation.value();
        Matcher matcher = Pattern.compile("^select\\s+\\*\\s+from\\s+" + tableName).matcher(oldsql.toLowerCase());
        if (matcher.find()){
            StringBuffer sqlBuilder=new StringBuffer();
            Field[] declaredFields = entityClass.getDeclaredFields();
            sqlBuilder.append("select ");
            List<String> fields=new ArrayList<>();
            for (Field declaredField : declaredFields) {
                TableField tableField = declaredField.getAnnotation(TableField.class);
                if (Objects.nonNull(tableField)&&tableField.exist()){
                    String name = declaredField.getName();
                    fields.add(tableField.value()+" "+name);
                }
            }
            String join = String.join(",", fields);
            sqlBuilder.append(join);
            sqlBuilder.append(" from ").append(tableName).append(" ");
            oldsql=sqlBuilder.toString();
        }

        selectFilter.buildWithWhere();
        List<ParameterMapping> parameterMappingList=new ArrayList<>();

        for (Object key : selectFilter.getSqlParamsMap().keySet()) {
            parameterMappingList.add(new ParameterMapping.Builder(mappedStatement.getConfiguration(),"sqlParamsMap."+key,Object.class).build());
        }

        BoundSql newBoundSql = new BoundSql(mappedStatement.getConfiguration(), oldsql + selectFilter.getSql(),
                parameterMappingList, boundSql.getParameterObject());
        MappedStatement newMs = copyFromMappedStatement(mappedStatement, new BoundSqlSqlSource(newBoundSql));
        invocation.getArgs()[0] = newMs;
    }


    /**
     * 复制原始MappedStatement
     * @param ms
     * @param newSqlSource
     * @return
     */
    private MappedStatement copyFromMappedStatement(MappedStatement 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) {
            for (String keyProperty : ms.getKeyProperties()) {
                builder.keyProperty(keyProperty);
            }
        }
        builder.timeout(ms.getTimeout());
        builder.parameterMap(ms.getParameterMap());
        builder.resultMaps(ms.getResultMaps());
        builder.cache(ms.getCache());
        builder.useCache(ms.isUseCache());
        return builder.build();
    }

    public static class BoundSqlSqlSource implements SqlSource {
        BoundSql boundSql;

        public BoundSqlSqlSource(BoundSql boundSql) {
            this.boundSql = boundSql;
        }

        public BoundSql getBoundSql(Object parameterObject) {
            return boundSql;
        }
    }

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


以上拦截器通过拦截 SelectFilter参数对象进行自定义扩展查询,通过SelectFilter来构建where后面的语句

拦截器注册:

@Configuration
public class MybatisSelectFilterConfiguration {
    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;

    @PostConstruct
    public void addInterceptor() {

        MybatisListSelectFilterInterceptor listSelectFilterInterceptor=new MybatisListSelectFilterInterceptor();
        MybatisPageSelectFilterInterceptor pageSelectFilterInterceptor=new MybatisPageSelectFilterInterceptor();
        sqlSessionFactoryList.forEach(sqlSessionFactory -> {
            sqlSessionFactory.getConfiguration().addInterceptor(listSelectFilterInterceptor);
            sqlSessionFactory.getConfiguration().addInterceptor(pageSelectFilterInterceptor);
        });
    }
}

 


Mapper 方法

 

    @Select("select * from cy_xlxw")
    List<Xlxw> list(SelectFilter<Xlxw> selectFilter);

 

 


SelectFilter 代码:

登录后查阅

此处内容已经隐藏,需要登录后刷新查阅

登录/注册


 

地址:https://www.leftso.com/article/1028.html

相关阅读

接上一篇:mybatis Interceptor拦截器实现自定义扩展查询兼容mybatis plus-左搜 (leftso.com)这里进行自定义分页查询扩展,基于mybatis plus,同样...
mybatis Interceptor拦截器实现自定义扩展查询兼容mybatis plus @Intercepts({ @Signature(type = Executor.c...
mybatis plus 逻辑删除使用说明全局逻辑值配置,application.properties# 逻辑已删除值(默认为 1) mybatis-plus.global-config.db...
mybatis plus 自增长主键如何获取注意在model对象里面配置以下注解即可在调用save()方法后通过对象get获取@TableId(type = IdType.AUTO) BigI...
引言    通过之前spring boot mybatis 整合的讲解: spring boot mybaties整合  (spring boot mybaties 整合 基于Java注解方式写...
某些情况下,我们使用mybaties时需要使用IN(虽然IN数据多了效率不高,但是少量还是可以用得)条件查询,这时候我们就需要传递参数了,下面是mybaties处理IN条件得参数使用方法首先Ma...
spring boot mybatis 整合使用讲解介绍,spring boot与mybaties的使用讲解介绍。spring boot mybatis xml mapper方式的入门和通过一个...
mybatis plus find_in_set 使用wrapper.apply(StrUtil.isNotBlank(clazz)," find_in_set('"+clazz+"',claz...
       本文主要讲解在使用mybaties中通过mybaties generator生成基本操作代码,然后通过 mybaties mapper 继承机制来解决某些情况下经常改表导致改map...
spring boot框架整合mybaties数据库暂时选用MySQL