0 0

mybatis 结合ehcache10

刚开始看mybatis ,在结合缓存的时候,遇到个问题,按照官方文档上面配置的ehcache配置,相应的jar包也加入进来,但是无路如何都没有成功

   数据每次都是从数据库里面读取的,命中要么为0 ,要么直接miss

  不知道啥原因,谁帮忙看下
代码如下 先看debug 信息

2012-07-17 12:47:47,124 [main] DEBUG [net.sf.ehcache.store.MemoryStore] - Initialized net.sf.ehcache.store.MemoryStore for com.ztiny.mybatis.dao.impl
2012-07-17 12:47:47,126 [main] DEBUG [net.sf.ehcache.Cache] - Initialised cache: com.ztiny.mybatis.dao.impl
2012-07-17 12:47:47,189 [main] DEBUG [net.sf.ehcache.Cache] - com.test.mybatis.dao.implCache: com.ztiny.mybatis.dao.implMemoryStore miss for 139696085:3585427282:com.ztiny.mybatis.dao.impl.selectAll:0:2147483647:select name as username ,age from employee
2012-07-17 12:47:47,189 [main] DEBUG [net.sf.ehcache.Cache] - com.test.mybatis.dao.impl cache - Miss
2012-07-17 12:47:47,391 [main] DEBUG [com.test.mybatis.dao.impl.selectAll] - ooo Using Connection [com.mysql.jdbc.Connection@6abde0]

2012-07-17 12:47:47,392 [main] DEBUG [com.test.mybatis.dao.impl.selectAll] - ==>  Preparing: select name as username ,age from employee
2012-07-17 12:47:47,419 [main] DEBUG [com.test.mybatis.dao.impl.selectAll] - ==> Parameters:
2012-07-17 12:47:47,666 [main] DEBUG [net.sf.ehcache.Cache] - com.test.mybatis.dao.implCache: com.test.mybatis.dao.implMemoryStore miss for 139696085:3585427282:com.ztiny.mybatis.dao.impl.selectAll:0:2147483647:select name as username ,age from employee
2012-07-17 12:47:47,666 [main] DEBUG [net.sf.ehcache.Cache] - com.test.mybatis.dao.impl cache - Miss
2012-07-17 12:47:47,674 [main] DEBUG [com.test.mybatis.dao.impl.selectAll] - ooo Using Connection [com.mysql.jdbc.Connection@9f45f4]
2012-07-17 12:47:47,674 [main] DEBUG [com.test.mybatis.dao.impl.selectAll] - ==>  Preparing: select name as username ,age from employee
2012-07-17 12:47:47,674 [main] DEBUG [com.test.mybatis.dao.impl.selectAll] - ==> Parameters:



上面的蓝色字体为第一次运行,第二次则,应该从缓存里面读数据,为什么这里还是从数据库里面读呢?

ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="../bin/ehcache.xsd">
	<defaultCache overflowToDisk="true" eternal="true"/>
	<diskStore path="f:/test/cache" />
</ehcache>

employee.xml
	<mapper namespace="com.test.mybatis.dao.impl">
	<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
  
    <select id="selectAll"  resultType="com.test.entity.Employee">
        select name as username ,age from employee 
    </select>


测试代码

@Override
	public List<Employee> selectList() {
		return super.getSession(false).selectList("selectAll");
	}
	
	public static void main(String args[]) throws Exception{
		EmployeeDaoImpl emplDao = new EmployeeDaoImpl();
		emplDao.selectList();//第一次
		emplDao.selectList();//第二次,应该从缓存里面读取
	}


mybatis 源码:
    BoundSql boundSql = ms.getBoundSql(parameterObject);
   //根据规则创建缓存对应的键,因为查询相同,所以第二次这个还是这个键,没错
    CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
   //在执行查询
    return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);


  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
    Cache cache = ms.getCache();
    if (cache != null) {
      flushCacheIfRequired(ms);
      if (ms.isUseCache() && resultHandler == null) { 
        ensureNoOutParams(ms, key, parameterObject, boundSql);
        if (!dirty) {
          cache.getReadWriteLock().readLock().lock();
          try {
            @SuppressWarnings("unchecked")
            List<E> cachedList = (List<E>) cache.getObject(key);
            if (cachedList != null) return cachedList;
          } finally {
            cache.getReadWriteLock().readLock().unlock();
          }
        }
        List<E> list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
//因为第一次没有缓存,所以创建了缓存然后再把数据放入缓存里面,但是这里有个问题,这个缓存每次都是重新创建的,大家可以去debug 看看,不知是我配置错了,还是怎么的,反正进入到这个方法里面,每次都是空的,看下面代码
        tcm.putObject(cache, key, list); // issue #578. Query must be not synchronized to prevent deadlocks
        return list;
      }
    }
//这里老是空对象,每次都是从新new 
    TransactionalCache txCache = transactionalCaches.get(cache);
    if (txCache == null) {
      txCache = new TransactionalCache(cache);
      transactionalCaches.put(cache, txCache);
    }


不知道有没有人碰到过类似的问题,谢谢

源码贴的可能不怎么规范,大家注意下,我只是截取了部分代码

问题补充:从贴下代码,好乱
这是 employee.xml

<mapper namespace="com.ztiny.mybatis.dao.impl">
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
 
    <select id="selectAll"  resultType="com.ztiny.test.entity.Employee">
        select name as username ,age from employee
    </select>
===============================================================
测试java代码
@Override
public List<Employee> selectList() {
return super.getSession(false).selectList("selectAll");
}

public static void main(String args[]) throws Exception{
EmployeeDaoImpl emplDao = new EmployeeDaoImpl();
emplDao.selectList();
emplDao.selectList();
}

=======================================================
ehcache.xml
   <diskStore path="D:/cache" />
   <defaultCache overflowToDisk="true" eternal="true"/>

=========================================================
部分源码
  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
    Cache cache = ms.getCache();
    if (cache != null) {
      flushCacheIfRequired(ms);
      if (ms.isUseCache() && resultHandler == null) {
        ensureNoOutParams(ms, key, parameterObject, boundSql);
        if (!dirty) {
          cache.getReadWriteLock().readLock().lock();
          try {
            @SuppressWarnings("unchecked")
            List<E> cachedList = (List<E>) cache.getObject(key);
            if (cachedList != null) return cachedList;
          } finally {
            cache.getReadWriteLock().readLock().unlock();
          }
        }
        List<E> list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
        tcm.putObject(cache, key, list); // issue #578. Query must be not synchronized to prevent deadlocks
        return list;
      }
    }
    return delegate.<E>query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }

  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
    BoundSql boundSql = ms.getBoundSql(parameterObject);
    CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
    return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }


public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
    Cache cache = ms.getCache();
    if (cache != null) {
      flushCacheIfRequired(ms);
      if (ms.isUseCache() && resultHandler == null) {
        ensureNoOutParams(ms, key, parameterObject, boundSql);
        if (!dirty) {
          cache.getReadWriteLock().readLock().lock();
          try {
            @SuppressWarnings("unchecked")
            List<E> cachedList = (List<E>) cache.getObject(key);
            if (cachedList != null) return cachedList;
          } finally {
            cache.getReadWriteLock().readLock().unlock();
          }
        }
        List<E> list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
        tcm.putObject(cache, key, list); // issue #578. Query must be not synchronized to prevent deadlocks
        return list;
      }
    }
    return delegate.<E>query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }


2012年7月17日 13:05

2个答案 按时间排序 按投票排序

0 0

它没有直接放入缓存,而是放进列表,在下一次sqlsession的时候commit这个列表里的缓存项,可能你两个select是在一个sqlsession里面了

2013年3月19日 10:46
0 0

麻烦先把代码整理好

2012年7月18日 00:45

相关推荐

Global site tag (gtag.js) - Google Analytics