ibatis 缓存导致的一个问题
来源:互联网 发布:国际贸易数据 编辑:程序博客网 时间:2024/05/02 02:03
最近由于业务的需要(系统对数据的操作用的是mybatis),需要对数据库中的某些字段进行加密。为了保证对外层应用的透明性,对SqlSessionTemplate 的部分方法进行了重写.一般对inser update 的时候,对插入的部分列加密,对select 的时候对加密的字段进行解密
如对update方法重写如下
@Override public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) { // TODO Auto-generated method stub return (List<E>) returnDeCryption(statement, super.selectList(statement, parameter, rowBounds)); }
开始用的时候都加密解密的时候很正常。但是有时候操作在做解密的时候,解密失败。
通过分析,是在一个功能中,对同一个select 方法调用两次的时候解密失败.通过分析,原来是mybatis 的缓存导致的。
具体分析如下:
mybatis中有一个缓存类
public class PerpetualCache implements Cache { private String id;//缓存key value 数据的map 对象 private Map<Object, Object> cache = new HashMap<Object, Object>();
真正使用缓存的对象在下边类中,
public abstract class BaseExecutor implements Executor { private static final Log log = LogFactory.getLog(BaseExecutor.class); protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads;//缓存 protected PerpetualCache localCache;//缓存 protected PerpetualCache localOutputParameterCache; protected Configuration configuration;
localCache 缓存查询的结果
<pre name="code" class="java">localOutputParameterCache 缓存执行的参数
//清楚缓存public void clearLocalCache() { if (!closed) { localCache.clear(); localOutputParameterCache.clear(); } }
//update 数据的时候会调用clearLocalCache方法清楚缓存,这样保证update 后,如果调用同一个select 查询到的是最新的结果public int update(MappedStatement ms, Object parameter) throws SQLException { ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId()); if (closed) throw new ExecutorException("Executor was closed."); clearLocalCache(); return doUpdate(ms, parameter); }
//查询的时候,如果是同一条sql 并且是同样的参数,就会把查询结果以及查询语句放到缓存中private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { List<E> list; localCache.putObject(key, EXECUTION_PLACEHOLDER); try { list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql); } finally { localCache.removeObject(key); } localCache.putObject(key, list); if (ms.getStatementType() == StatementType.CALLABLE) { localOutputParameterCache.putObject(key, parameter); } return list; }
通过查看BaseExecutor的源码,对导致问题的原因一目了然了。
1:mybatis 对同一个select (执行sql以及对应的sql参数的值都一样时才是同一次select),执行多次时,只有第一次去查询数据库,后续的查询是直接从缓存中把结果取出
2:由于重写了selectList方法,对每次查询的结果都进行解密,但是实际上第一次查询时就对结果进行了解密,此时mybatis 已经是缓存的明文数据,当第二查询的时候,查询到的已经是明文数据,所以解密出错。
0 0
- ibatis 缓存导致的一个问题
- Ibatis缓存应用的一个小问题
- Spring对iBatis封装导致的缓存问题
- 不经意间用了ibatis的缓存引发的一个问题
- 关于ibatis的一个错误写法导致的思考
- Hibernate3导致的一个问题
- 一个疏忽导致的问题
- iBATIS缓存的使用方法
- IBatis 的缓存机制
- ibatis的缓存例子
- Ibatis的缓存机制
- Ibatis 连接 Timesten 的一个诡异问题
- 今天遇到一个问题,关于ibatis的
- Ibatis缓存select字段名引起的问题
- 一个关于缓存的问题
- Windows图标缓存导致的一个诡异BUG
- ajax缓存导致的一个错误,使用时间戳完美解决
- @Controller的一个错误导致的问题
- Triangle LeetCode |My solution
- Linux常用命令英文全称与中文解释Linux系统
- jquery合并单元格(表格相邻列内容相同合并)
- 物理层的接口有哪几个方面的特性?各包含些什么内容?
- Java内存溢出的详细解决方案
- ibatis 缓存导致的一个问题
- 从C到C++(上)
- nfs常见问题解决方法
- linux的启动过程以及/etc/inittab详解
- 为什么要使用信道复用技术?常用的信道复用技术有哪些?
- 常用算法之动态规划法
- c3p0出现 An attempt by a client to checkout a Connection has timed out
- C#中判断密码字符强度 并设置对应颜色
- java自带线程池和队列详细讲解