使用Ehcache和Hibernate时,我的速度没有提高
以下是我在下面进行测试时得到的结果。测试是使用缓存再次读取80个Stop对象,然后再读取相同的80个Stop对象。
在第二次阅读时,它正在达到缓存,但速度没有提高。关于我做错了什么的想法?
Speed Test:
First Read: Reading stops 1-80 : 288ms
Second Read: Reading stops 1-80 : 275ms
Cache Info:
elementsInMemory: 79
elementsInMemoryStore: 79
elementsInDiskStore: 0
JunitCacheTest
public class JunitCacheTest extends TestCase {
static Cache stopCache;
public void testCache()
{
ApplicationContext context = new ClassPathXmlApplicationContext("beans-hibernate.xml");
StopDao stopDao = (StopDao) context.getBean("stopDao");
CacheManager manager = new CacheManager();
stopCache = (Cache) manager.getCache("ie.dataStructure.Stop.Stop");
//First Read
for (int i=1; i<80;i++)
{
Stop toStop = stopDao.findById(i);
}
//Second Read
for (int i=1; i<80;i++)
{
Stop toStop = stopDao.findById(i);
}
System.out.println("elementsInMemory " + stopCache.getSize());
System.out.println("elementsInMemoryStore " + stopCache.getMemoryStoreSize());
System.out.println("elementsInDiskStore " + stopCache.getDiskStoreSize());
}
public static Cache getStopCache() {
return stopCache;
}
}
HibernateStopDao
@Repository("stopDao")
public class HibernateStopDao implements StopDao {
private SessionFactory sessionFactory;
@Transactional(readOnly = true)
public Stop findById(int stopId) {
Cache stopCache = JunitCacheTest.getStopCache();
Element cacheResult = stopCache.get(stopId);
if (cacheResult != null){
return (Stop) cacheResult.getValue();
}
else{
Stop result =(Stop) sessionFactory.getCurrentSession().get(Stop.class, stopId);
Element element = new Element(result.getStopID(),result);
stopCache.put(element);
return result;
}
}
}
ehcache.xml中
<cache name="ie.dataStructure.Stop.Stop"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="5200"
timeToLiveSeconds="5200"
overflowToDisk="true">
</cache>
stop.hbm.xml
<class name="ie.dataStructure.Stop.Stop" table="stops" catalog="hibernate3" mutable="false" >
<cache usage="read-only"/>
<comment></comment>
<id name="stopID" type="int">
<column name="STOPID" />
<generator class="assigned" />
</id>
<property name="coordinateID" type="int">
<column name="COORDINATEID" not-null="true">
<comment></comment>
</column>
</property>
<property name="routeID" type="int">
<column name="ROUTEID" not-null="true">
<comment></comment>
</column>
</property>
</class>
停止
public class Stop implements Comparable<Stop>, Serializable {
private static final long serialVersionUID = 7823769092342311103L;
private Integer stopID;
private int routeID;
private int coordinateID;
}
答案 0 :(得分:2)
我看到的第一个错误是你在Hibernate的二级缓存之上处理一个缓存,它将缓存Stop
个实体。这只是无用的,二级缓存是透明的,你不需要在这里添加额外的类(如Element
)或额外的代码。所以DAO方法应该是:
@Transactional(readOnly = true)
public Stop findById(int stopId) {
return (Stop) sessionFactory.getCurrentSession().get(Stop.class, stopId);
}
这就是全部,仅此而已。我再说一遍:激活第二级是声明性的,你不需要修改你的代码。
第二个错误:您当前的测试实际上不会达到二级缓存,第二个循环使用相同的Session并将从... Session(第一级缓存)获取对象,而不是来自二级缓存。如果要测试二级缓存,请使用另一个会话(即关闭第一个会话并从会话工厂中获取另一个会话)。
我建议激活类别org.hibernate.cache
上的日志记录以记录所有二级缓存活动,并确保事情按预期工作。
确定后,删除记录并在较大的样本(x10或x100)上重新运行(固定)测试。
答案 1 :(得分:0)
当您将<cache>
元素添加到映射文件时,Hibernate将自动使用二级缓存。在从Session中获取对象之前/之后,您无需显式管理缓存。
你尝试过大量的物品吗?一秒钟之内的基准测试并不十分可靠。