日常踩坑记录2(mybatis多个拦截器加载问题)

mybatis多个拦截时配置问题

1.配置XML在这里插入图片描述






OffsetLimitInterceptor为mybatis自带的分页拦截器
AuthorityFilterPlugin为自定义拦截器
2.编写自定义拦截器
在这里插入图片描述
图中部分一定要这么写,千万不能用java反射来使用,否则当不走分页拦截器OffsetLimitInterceptor时自定义拦截器也无效

private static final Logger log = LoggerFactory.getLogger(AuthorityFilterPlugin.class);
	static int MAPPED_STATEMENT_INDEX = 0;// 这是对应上面的args的序号
	static int PARAMETER_INDEX = 1;
	static int ROWBOUNDS_INDEX = 2;
	static int RESULT_HANDLER_INDEX = 3;

	/**
	 * 这里是每次执行操作的时候,都会进行这个拦截器的方法内
	 *
	 * @param invocation
	 * @return
	 * @throws Throwable
	 */
	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		// 对sql进行处理
		Object[] queryArgs = invocation.getArgs();
		MappedStatement ms = (MappedStatement) queryArgs[MAPPED_STATEMENT_INDEX];
		Object parameter = queryArgs[PARAMETER_INDEX];
		BoundSql boundSql = ms.getBoundSql(parameter);
		// 获取到SQL ,进行调整
		String sql = boundSql.getSql();
		log.debug("原sql:" + sql);
		// 获取request信息,得到当前登录用户信息
		RequestAttributes req = RequestContextHolder.getRequestAttributes();
		if (req == null) {
			return invocation.proceed();
		}
		// 处理request
		HttpServletRequest request = ((ServletRequestAttributes) req).getRequest();
		List<String> roleComid = (List<String>) request.getSession().getAttribute("roleComid");
		if (roleComid == null || roleComid.size() <= 0) {
			return invocation.proceed();
		}
		String para = "comid";
		if ((sql.contains("limit ?") && (sql.indexOf("?") != sql.lastIndexOf("?"))) || (!sql.contains("limit ?") && sql.contains("?"))) {
			sql = this.permissionSqlOther(sql, roleComid, para);
		}else
			sql = this.permissionSql(sql, roleComid, para);
		log.debug("拼接后sql:" + sql);
	    BoundSqlSource boundSqlSource = new BoundSqlSource(boundSql);
	    MappedStatement newMappedStatement = copyFromMappedStatement(ms, boundSqlSource);
	    MetaObject metaObject = MetaObject.forObject(newMappedStatement,
	            new DefaultObjectFactory(), new DefaultObjectWrapperFactory(),
	            new DefaultReflectorFactory());
	    metaObject.setValue("sqlSource.boundSql.sql", sql);
	    queryArgs[MAPPED_STATEMENT_INDEX] = newMappedStatement;
		return invocation.proceed();
	}
private MappedStatement copyFromMappedStatement(MappedStatement ms,SqlSource newSqlSource) {
		Builder builder = new 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){
            StringBuffer keyProperties = new StringBuffer();
            for(String keyProperty : ms.getKeyProperties()){
                keyProperties.append(keyProperty).append(",");
            }
            keyProperties.delete(keyProperties.length()-1, keyProperties.length());
			builder.keyProperty(keyProperties.toString());
		}
		
		//setStatementTimeout()
		builder.timeout(ms.getTimeout());
		
		//setStatementResultMap()
		builder.parameterMap(ms.getParameterMap());
		
		//setStatementResultMap()
        builder.resultMaps(ms.getResultMaps());
		builder.resultSetType(ms.getResultSetType());
	    
		//setStatementCache()
		builder.cache(ms.getCache());
		builder.flushCacheRequired(ms.isFlushCacheRequired());
		builder.useCache(ms.isUseCache());
		
		return builder.build();
	}
	private class BoundSqlSource implements SqlSource {

	    private BoundSql boundSql;

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

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

	/**
	 * 主要是为了把这个拦截器生成一个代理放到拦截器链中
	 */
	@Override
	public Object plugin(Object target) {
		// 官方推荐写法
		return Plugin.wrap(target, this);
	}

	/**
	 * 插件初始化的时候调用,也只调用一次,插件配置的属性从这里设置进来
	 *
	 * @param properties
	 */
	@Override
	public void setProperties(Properties properties) {
	}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值