zoukankan      html  css  js  c++  java
  • mybatis拦截器修改sql重新set后不生效?

    利用mybatis拦截器做数据权限管理,拦截sql并分析、修改然后重新set。然而有的生效有的不生效。控制台打印的信息表示所有的sql都是修改成功的,那么问题在于重新set的方法。

    一开始用的方法是这个:

    private void setCurrentSql(Invocation invo, String sql) {
    MappedStatement mappedStatement = getMappedStatement(invo);
    Object[] args = invo.getArgs();
    Object paramObj = args[PARAM_OBJ_INDEX];
    BoundSql boundSql = mappedStatement.getBoundSql(paramObj);
    ReflectUtil.setFieldValue(boundSql, "sql", sql);
    }

    通过反射去修改boundSql的sql属性的值,但是有问题。
    后来改用这个方法:
    private void setCurrentSql(Invocation invo, String sql) {
    BoundSql boundSql = getBoundSql(invo);
    List<ParameterMapping> parameterMappings = boundSql.
    getParameterMappings();
    Object paramObj = boundSql.getParameterObject();
    MappedStatement mappedStatement = getMappedStatement(invo);
    Configuration configuration = mappedStatement.getConfiguration();
    BoundSql newBoundSql = new BoundSql(configuration, sql,
    parameterMappings, paramObj);
    for (ParameterMapping parameterMapping : parameterMappings) {
    String prop = parameterMapping.getProperty();
    if (boundSql.hasAdditionalParameter(prop)) {
    Object param = boundSql.getAdditionalParameter(prop);
    newBoundSql.setAdditionalParameter(prop, param);
    }
    }

    BoundSqlSource newSqlSource = new BoundSqlSource(newBoundSql);
    MappedStatement newMappedStatement = copyFromMappedStatement(
    mappedStatement, newSqlSource);
    Object[] args = invo.getArgs();
    args[MAPPED_STATEMENT_INDEX] = newMappedStatement;
    }

    问题解决。还有一种方法,看起来更简洁:
    private void setCurrentSql(Invocation invo, String sql) {
    MappedStatement mappedStatement = getMappedStatement(invo);
    Object[] args = invo.getArgs();
    Object paramObj = args[PARAM_OBJ_INDEX];
    BoundSql boundSql = mappedStatement.getBoundSql(paramObj);
    BoundSqlSource boundSqlSource = new BoundSqlSource(boundSql);
    MappedStatement newMappedStatement = copyFromMappedStatement(
    mappedStatement, boundSqlSource);
    MetaObject metaObject = MetaObject.forObject(newMappedStatement,
    new DefaultObjectFactory(), new DefaultObjectWrapperFactory(),
    new DefaultReflectorFactory());
    metaObject.setValue("sqlSource.boundSql.sql", sql);
    args[MAPPED_STATEMENT_INDEX] = newMappedStatement;
    }

    上面用到的方法getMappedStatement:
    private MappedStatement getMappedStatement(Invocation invo) {
    Object[] args = invo.getArgs();
    Object mappedStatement = args[MAPPED_STATEMENT_INDEX];
    return (MappedStatement) mappedStatement;
    }
    私有内部类BoundSqlSource:
    private class BoundSqlSource implements SqlSource {

    private BoundSql boundSql;

    private BoundSqlSource(BoundSql boundSql) {
    this.boundSql = boundSql;
    }

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

    另外还有:
    private static final int MAPPED_STATEMENT_INDEX = 0;
    private static final int PARAM_OBJ_INDEX = 1;
    龙门之桐,高百尺而无枝,其根半死半生。
  • 相关阅读:
    常见的代码报错信息总结(持续更新ing)
    ASCII码对照表
    python ord()与chr()用法以及区别
    Python random模块sample、randint、shuffle、choice随机函数
    日志相关
    tensorflow学习笔记
    tar 解压缩命令详解
    pandas使用
    相似度与距离计算python代码实现
    逻辑回归原理(python代码实现)
  • 原文地址:https://www.cnblogs.com/longmenzhitong/p/11271909.html
Copyright © 2011-2022 走看看