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;
    龙门之桐,高百尺而无枝,其根半死半生。
  • 相关阅读:
    linux并发控制之读写信号量
    linux并发控制之原子操作
    JAVA IntelliJ IDEA for mac/jdk的安装及环境配置、运行
    HDU2553 N皇后问题dfs
    LightOJ1282Leading and Trailing快速幂+数学
    HDU1226超级密码队列+广搜+大数取模
    Aizu ALDS1_13_A8 Queens Problem八皇后的路径输出
    HDU1548 A strange lift BFS
    POJ1182 食物链 并查集
    UVA10200Prime Time判断素数个数(打表预处理)+精度控制
  • 原文地址:https://www.cnblogs.com/longmenzhitong/p/11271909.html
Copyright © 2011-2022 走看看