`

get 会使用二级缓存

阅读更多

经常看到session.get()和session.load()方法的区别,书上说load方法可以充分利用二级缓存中的现有数据,而get方法仅在内部缓存进行数据查找,如果没有查找到数据,将越过二级缓存,直接调用SQL完成数据读取。可我试了试,执行结果确实两个方法都充分利用了二级缓存。
代码如下:
  TuserDAO

Java代码 复制代码
  1.   package org.xiyou;   
  2.   
  3. import java.util.Iterator;   
  4. import java.util.List;   
  5.   
  6. import org.hibernate.Criteria;   
  7. import org.hibernate.Query;   
  8. import org.hibernate.Session;   
  9. import org.hibernate.SessionFactory;   
  10. import org.hibernate.Transaction;   
  11. import org.hibernate.cfg.Configuration;   
  12. import org.hibernate.criterion.Expression;   
  13.   
  14. public class TuserDAO {   
  15.      public void get()   
  16.   {   
  17.       SessionFactory sessionFactory=new Configuration().configure("org/xiyou/hibernate.cfg.xml").buildSessionFactory();   
  18.       Session session=sessionFactory.openSession();   
  19.       Tuser user=(Tuser)session.get(Tuser.classnew Integer(3));   
  20.       System.out.println(user.getName());   
  21.       session.close();   
  22.       Session session1=sessionFactory.openSession();   
  23.       Tuser user1=(Tuser)session1.get(Tuser.classnew Integer(3));   
  24.       System.out.println(user1.getName());   
  25.       System.out.println((session.equals(session1)));   
  26.       session1.close();   
  27.   }   
  28.   /*  
  29.    * 测试Session.load()  
  30.    *   
  31.    *   
  32.    * */  
  33.   public void load()   
  34.   {   
  35.       SessionFactory sessionFactory=new Configuration().configure("org/xiyou/hibernate.cfg.xml").buildSessionFactory();   
  36.       Session session=sessionFactory.openSession();   
  37.       Tuser user=(Tuser)session.load(Tuser.classnew Integer(3));   
  38.       System.out.println(user.getName());   
  39.       session.close();   
  40.       Session session1=sessionFactory.openSession();   
  41.       Tuser user1=(Tuser)session1.load(Tuser.classnew Integer(3));   
  42.          
  43.       System.out.println(user1.getName());   
  44.          
  45.       session1.close();   
  46.       System.out.println((session.equals(session1)));   
  47.   }   
  48. }  


测试类:

Java代码 复制代码
  1. package org.xiyou;   
  2.   
  3. public class Test01 {   
  4.    public static void main(String [] args)   
  5.    {   
  6.        TuserDAO userdao=new TuserDAO();   
  7.        userdao.get2();   
  8.        userdao.load();   
  9.     }   
  10. }  
Java代码 
  1. Hibernate: select tuser0_.id as id0_, tuser0_.version as version0_0_, tuser0_.name as name0_0_ from test.tuser tuser0_ where tuser0_.id=?   
  2. aaaa   
  3. aaaa   
  4. false  
  5. aaaa   
  6. aaaa   
  7. false  

hibernate.cfg.xml 
Java代码 复制代码
  1. <?xml version='1.0' encoding='UTF-8'?>   
  2. <!DOCTYPE hibernate-configuration PUBLIC   
  3.           "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
  4.           "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">   
  5.   
  6. <!-- Generated by MyEclipse Hibernate Tools.                   -->   
  7. <hibernate-configuration>   
  8.   
  9. <session-factory>   
  10.     <property name="dialect">   
  11.         org.hibernate.dialect.MySQLDialect   
  12.     </property>   
  13.     <property name="connection.url">   
  14.         jdbc:mysql://localhost/test   
  15.     </property>   
  16.     <property name="connection.username">root</property>   
  17.     <property name="connection.password">123</property>   
  18.     <property name="connection.driver_class">   
  19.         com.mysql.jdbc.Driver   
  20.     </property>   
  21.     <property name="myeclipse.connection.profile">mysql</property>   
  22.     <property name="show_sql">true</property>   
  23. <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>   
  24.     <mapping resource="org/xiyou/Tuser.hbm.xml" />   
  25.   
  26. </session-factory>   
  27.   
  28. </hibernate-configuration>  
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

<session-factory>
	<property name="dialect">
		org.hibernate.dialect.MySQLDialect
	</property>
	<property name="connection.url">
		jdbc:mysql://localhost/test
	</property>
	<property name="connection.username">root</property>
	<property name="connection.password">123</property>
	<property name="connection.driver_class">
		com.mysql.jdbc.Driver
	</property>
	<property name="myeclipse.connection.profile">mysql</property>
	<property name="show_sql">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
	<mapping resource="org/xiyou/Tuser.hbm.xml" />

</session-factory>

</hibernate-configuration>


Tuser.hbm.xml

Java代码 复制代码
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">   
  4. <!--    
  5.     Mapping file autogenerated by MyEclipse - Hibernate Tools   
  6. -->   
  7. <hibernate-mapping>   
  8.     <class name="org.xiyou.Tuser" table="tuser" catalog="test" >   
  9.     <cache usage="read-only"/>   
  10.         <id name="id" type="java.lang.Integer">   
  11.             <column name="id" />   
  12.             <generator class="native" />   
  13.         </id>   
  14.         <property name="version"  
  15.                  column="version"  
  16.                  type="integer"></property>   
  17.         <property name="name" type="java.lang.String">   
  18.             <column name="name" length="20" />   
  19.         </property>   
  20.   
  21.     </class>   
  22. </hibernate-mapping>  
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
    <class name="org.xiyou.Tuser" table="tuser" catalog="test" >
    <cache usage="read-only"/>
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="native" />
        </id>
        <property name="version"
                 column="version"
                 type="integer"></property>
        <property name="name" type="java.lang.String">
            <column name="name" length="20" />
        </property>

    </class>
</hibernate-mapping>


ehcache.xml

Java代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd">   
  3.     <diskStore path="java.io.tmpdir" />   
  4.     <defaultCache    
  5.         maxElementsInMemory="10000"    
  6.         eternal="false"    
  7.         timeToIdleSeconds="120"    
  8.         timeToLiveSeconds="120"    
  9.         overflowToDisk="true"    
  10.         diskPersistent="false"    
  11.         diskExpiryThreadIntervalSeconds="120"    
  12.         memoryStoreEvictionPolicy="LRU" />   
  13. </ehcache>  

 

 

 

 

源码(3.2.6.ga),确实如此

先看一下Session的默认实现SessionImpl
get方法会转到fireLoad,loadType的值是LoadEventListener.GET
load方法也是转到fireLoad,不同的是loadType的值是LoadEventListener.LOAD

Java代码 复制代码
  1. private void fireLoad(LoadEvent event, LoadType loadType) {   
  2.     errorIfClosed();   
  3.     checkTransactionSynchStatus();   
  4.     LoadEventListener[] loadEventListener = listeners.getLoadEventListeners();   
  5.     for ( int i = 0; i < loadEventListener.length; i++ ) {   
  6.         loadEventListener[i].onLoad(event, loadType);   
  7.     }   
  8. }  
private void fireLoad(LoadEvent event, LoadType loadType) {
	errorIfClosed();
	checkTransactionSynchStatus();
	LoadEventListener[] loadEventListener = listeners.getLoadEventListeners();
	for ( int i = 0; i < loadEventListener.length; i++ ) {
		loadEventListener[i].onLoad(event, loadType);
	}
}

 调用loadEventListener的onLoad方法
LoadEventListener的默认实现DefaultLoadEventListener中
最终会转到doLoad方法,options就是前面的loadType

Java代码 复制代码
  1. protected Object doLoad(   
  2.             final LoadEvent event,   
  3.             final EntityPersister persister,   
  4.             final EntityKey keyToLoad,   
  5.             final LoadEventListener.LoadType options) throws HibernateException {   
  6.     。。。。。。   
  7.     Object entity = loadFromSessionCache( event, keyToLoad, options );//从一级缓存加载   
  8.     //如果不为空,直接返回   
  9.     。。。。。。   
  10.     entity = loadFromSecondLevelCache(event, persister, options);//从二级缓存加载   
  11.     。。。。。。   
  12. }  
protected Object doLoad(
			final LoadEvent event,
			final EntityPersister persister,
			final EntityKey keyToLoad,
			final LoadEventListener.LoadType options) throws HibernateException {
	。。。。。。
	Object entity = loadFromSessionCache( event, keyToLoad, options );//从一级缓存加载
	//如果不为空,直接返回
	。。。。。。
	entity = loadFromSecondLevelCache(event, persister, options);//从二级缓存加载
	。。。。。。
}

 loadFromSecondLevelCache即是从二级缓存中查找对象
get和load的区别在于LoadEventListener.LoadType options参数,一个是LoadEventListener.GET,一个是LoadEventListener.LOAD
而在这个方法中,并没有用到options参数
也就是说get和load使用二级缓存的状况是一样的,get也会使用二级缓存

分享到:
评论

相关推荐

    Redis用作二级缓存

    3. 编写Mybatis的配置:在mybatis-config.xml文件中,启用全局的二级缓存并指定使用Redis作为缓存实现。 ```xml &lt;!-- Redis相关配置 --&gt; ``` 4. 定义Mapper缓存:在每个Mapper接口或XML配置文件...

    hibernate二级缓存实例

    5. 应用到查询:对于查询结果,可以使用`SessionFactory.getCache()`方法获取二级缓存对象,然后进行相关的读写操作。 在源码实例中,你可以看到如何在代码层面与二级缓存进行交互,例如通过SessionFactory的get...

    Hibernate二级缓存

    1. **导入依赖**:首先,你需要添加ehcache库的jar包到项目的类路径中,因为Hibernate通常使用ehcache作为默认的二级缓存提供者。 2. **配置二级缓存**:在`hibernate.cfg.xml`配置文件中,需要指定二级缓存的提供...

    二级缓存配置

    1. **加载实体**:当通过`session.get()`或`session.load()`方法加载实体时,Hibernate首先检查二级缓存,然后是一级缓存,最后才是数据库。 2. **更新实体**:当对实体进行修改时,如果启用了`read-write`缓存策略...

    mybatis二级缓存扩展-与redis集成

    要将MyBatis的二级缓存与Redis集成,首先需要在MyBatis的配置文件中定义自定义的Cache实现类,这个类通常会基于Java的Jedis库来操作Redis。在实现类中,你需要覆盖`put`、`get`、`remove`等关键方法,以实现数据的...

    JPA-5 使用二级缓存

    但需要注意的是,二级缓存可能会增加数据的一致性风险,因为不同事务可能同时修改缓存中的同一数据。 使用JPA的二级缓存,我们需要进行以下几个步骤: 1. **选择缓存提供商**:JPA本身并不提供二级缓存实现,而是...

    Hibernate二级缓存技术

    通过使用二级缓存,可以显著提高应用性能,尤其是在频繁查询相同数据的情况下。 #### 三、配置与实现 **1. 配置 EhCache** 为了使用Hibernate的二级缓存功能,首先需要配置EhCache。EhCache 是一个开源的、高性能...

    mybatis plus使用redis作为二级缓存的方法

    MyBatis Plus 使用 Redis 作为二级缓存的方法 MyBatis Plus 是一个基于 MyBatis 的增强工具,提供了许多实用的功能,其中之一就是支持使用 Redis 作为二级缓存。本文将详细介绍如何使用 MyBatis Plus 将 Redis 作为...

    LruCache和DiskLruCache实现二级缓存的自定义ImageLoader

    本文将深入探讨如何使用`LruCache`和`DiskLruCache`实现一个二级缓存的自定义`ImageLoader`。 `LruCache`是Android SDK提供的内存缓存解决方案,全称为"Least Recently Used Cache"(最近最少使用缓存)。它的原理...

    J2EE企业级项目开发-1期 05 hibernate二级缓存实战经验.doc

    当我们通过`Session.get()`检索一个对象时,Hibernate首先检查一级缓存(即Session内部的缓存),如果不在一级缓存中,那么会尝试从二级缓存中查找。如果二级缓存也没有,Hibernate才会去数据库中查询。在这个测试中...

    springboot2.x整合redis做mybatis的二级缓存

    Spring Boot和Redis的结合使用,可以构建出高效、可扩展的二级缓存系统,以减轻数据库的压力。本篇文章将深入探讨如何在Spring Boot 2.x项目中整合Redis作为MyBatis的二级缓存,并实现自定义键、自定义过期时间和...

    SSH框架网上商城项目第16战之Hibernate二级缓存处理首页热门显示

    对于HQL的`list()`查询,它会直接从数据库获取多条记录,并将其存储到二级缓存,以便后续的`get()`和`load()`调用。而`executeUpdate()`这类更新操作同样不支持二级缓存,它会直接作用于数据库。 通过以上配置和...

    Hibernate一级缓存和二级缓存详解

    二级缓存是SessionFactory级别的缓存,顾名思义,就是查询的时候会把查询结果缓存到二级缓存中,如果同一个sessionFactory创建的某个session执行了相同的操作,hibernate就会从二级缓存中拿结果,而不会再去连接...

    Mybatis如何通过注解开启使用二级缓存

    "Mybatis 中通过注解开启使用二级缓存" Mybatis 是一个基于 Java 的持久层框架,它提供了一个简单易用的方式来访问数据库。二级缓存是 Mybatis 中的一种缓存机制,它可以将查询结果缓存起来,减少数据库的访问次数...

    memcached作为hibernate二级缓存必备的jar包

    在这个场景下,我们将探讨如何使用Memcached作为Hibernate的二级缓存,并了解相关的jar包及其作用。 标题提到的"memcached作为hibernate二级缓存必备的jar包",指的是将分布式内存缓存系统Memcached集成到Hibernate...

    ASimpleCache二级缓存修改

    在原代码基础上,添加内存缓存机制,提升常用缓存数据读取速度。 获取顺序:内存缓存-&gt;文件缓存----&gt;网络(ACache不含网络读取) 以下有个小的demo,希望您能喜欢: ACache mCache = ACache.get(this); mCache.put...

    详解Hibernate注解方式的二级缓存

    通常情况下,只有在对效率有较高要求且需要跨多个Session共享数据时,才会考虑使用二级缓存。 接下来,介绍如何通过注解来配置和使用Hibernate的二级缓存: 1. 开启二级缓存功能:要在Hibernate配置文件中添加开启...

Global site tag (gtag.js) - Google Analytics