zoukankan      html  css  js  c++  java
  • Hibernate的缓存机制如何应用?

    2.一级缓存应用: save()。当session对象调用save()方法保存一个对象后,该对象会被放入到session的缓存中。 get()和load()。当session对象调用get()或load()方法从数据库取出一个对象后,该对象也会被放入到session的缓存中。 使用HQL和QBC等从数据库中查询数据。

    复制代码

    public class Client
    {
        public static void main(String[] args)
        {
            Session session = HibernateUtil.getSessionFactory().openSession();
            Transaction tx = null;
            try
            {
                /*开启一个事务*/
                tx = session.beginTransaction();
                /*从数据库中获取id="402881e534fa5a440134fa5a45340002"的Customer对象*/
                Customer customer1 = (Customer)session.get(Customer.class, "402881e534fa5a440134fa5a45340002");
                System.out.println("customer.getUsername is"+customer1.getUsername());
                /*事务提交*/
                tx.commit();
                
                System.out.println("-------------------------------------");
                
                /*开启一个新事务*/
                tx = session.beginTransaction();
                /*从数据库中获取id="402881e534fa5a440134fa5a45340002"的Customer对象*/
                Customer customer2 = (Customer)session.get(Customer.class, "402881e534fa5a440134fa5a45340002");
                System.out.println("customer2.getUsername is"+customer2.getUsername());
                /*事务提交*/
                tx.commit();
                
                System.out.println("-------------------------------------");
                
                /*比较两个get()方法获取的对象是否是同一个对象*/
                System.out.println("customer1 == customer2 result is "+(customer1==customer2));
            }
            catch (Exception e)
            {
                if(tx!=null)
                {
                    tx.rollback();
                }
            }
            finally
            {
                session.close();
            }
        }
    }

    复制代码

    复制代码

    结果
    Hibernate: 
        select
            customer0_.id as id0_0_,
            customer0_.username as username0_0_,
            customer0_.balance as balance0_0_ 
        from
            customer customer0_ 
        where
            customer0_.id=?
    customer.getUsername islisi
    -------------------------------------
    customer2.getUsername islisi
    -------------------------------------
    customer1 == customer2 result is true

    复制代码

    输出结果中只包含了一条SELECT SQL语句,而且customer1 == customer2 result is true说明两个取出来的对象是同一个对象。其原理是:第一次调用get()方法, Hibernate先检索缓存中是否有该查找对象,发现没有,Hibernate发送SELECT语句到数据库中取出相应的对象,然后将该对象放入缓存中,以便下次使用,第二次调用get()方法,Hibernate先检索缓存中是否有该查找对象,发现正好有该查找对象,就从缓存中取出来,不再去数据库中检索。

     

    3.二级缓存的管理:

    evict(Class arg0, Serializable arg1)将某个类的指定ID的持久化对象从二级缓存中清除,释放对象所占用的资源。

    sessionFactory.evict(Customer.class, new Integer(1));  

    evict(Class arg0)  将指定类的所有持久化对象从二级缓存中清除,释放其占用的内存资源。

    sessionFactory.evict(Customer.class);  

    evictCollection(String arg0)  将指定类的所有持久化对象的指定集合从二级缓存中清除,释放其占用的内存资源。

    sessionFactory.evictCollection("Customer.orders");  

     

    4.二级缓存的配置

    常用的二级缓存插件

    EHCache  org.hibernate.cache.EhCacheProvider

    OSCache  org.hibernate.cache.OSCacheProvider

    SwarmCahe  org.hibernate.cache.SwarmCacheProvider

    JBossCache  org.hibernate.cache.TreeCacheProvider

    复制代码

    <!-- EHCache的配置,hibernate.cfg.xml --> 
    <hibernate-configuration>
        <session-factory>
           <!-- 设置二级缓存插件EHCache的Provider类-->
           <property name="hibernate.cache.provider_class">
              org.hibernate.cache.EhCacheProvider
           </property>
           <!-- 启动"查询缓存" -->
           <property name="hibernate.cache.use_query_cache">
              true
           </property>
        </session-factory>
      </hibernate-configuration>

    复制代码

    复制代码

    <!-- ehcache.xml -->
    <?xml version="1.0" encoding="UTF-8"?>
    <ehcache>
        <!--
            缓存到硬盘的路径
        -->
        <diskStore path="d:/ehcache"></diskStore>
        <!--
            默认设置
            maxElementsInMemory : 在內存中最大緩存的对象数量。
            eternal : 缓存的对象是否永远不变。
            timeToIdleSeconds :可以操作对象的时间。
            timeToLiveSeconds :缓存中对象的生命周期,时间到后查询数据会从数据库中读取。
            overflowToDisk :内存满了,是否要缓存到硬盘。
        -->
        <defaultCache maxElementsInMemory="200" eternal="false" 
            timeToIdleSeconds="50" timeToLiveSeconds="60" overflowToDisk="true"></defaultCache>
        <!--
            指定缓存的对象。
            下面出现的的属性覆盖上面出现的,没出现的继承上面的。
        -->
        <cache name="com.suxiaolei.hibernate.pojos.Order" maxElementsInMemory="200" eternal="false" 
            timeToIdleSeconds="50" timeToLiveSeconds="60" overflowToDisk="true"></cache>
    </ehcache>

    复制代码

    复制代码

    <!-- *.hbm.xml -->
    <?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" >
    <hibernate-mapping>
       <class>
           <!-- 设置该持久化类的二级缓存并发访问策略 read-only read-write nonstrict-read-write transactional-->
           <cache usage="read-write"/>    
       </class>
    </hibernate-mapping>

    复制代码

    若存在一对多的关系,想要在在获取一方的时候将关联的多方缓存起来,需要在集合属性下添加<cache>子标签,这里需要将关联的对象的hbm文件中必须在存在<class>标签下也添加<cache>标签,不然Hibernate只会缓存OID。

    复制代码

    <hibernate-mapping>
            <class name="com.suxiaolei.hibernate.pojos.Customer" table="customer">
                <!-- 主键设置 -->
                <id name="id" type="string">
                    <column name="id"></column>
                    <generator class="uuid"></generator>
                </id>
                
                <!-- 属性设置 -->
                <property name="username" column="username" type="string"></property>
                <property name="balance" column="balance" type="integer"></property>
                
                <set name="orders" inverse="true" cascade="all" lazy="false" fetch="join">
                    <cache usage="read-only"/>
                    <key column="customer_id" ></key>
                    <one-to-many class="com.suxiaolei.hibernate.pojos.Order"/>
                </set>
                
            </class>
        </hibernate-mapping>
  • 相关阅读:
    第十二讲 Web 服务的创建和使用
    第十七讲 ASP.NET安全性
    第九讲 水晶报表的使用
    第十五讲 数据集的使用方法和技巧
    第十六讲 调试和跟踪ASP.NET应用程序
    第十讲 ASP.NET程序的部署
    第十四讲 ADO.NET数据操作
    第十八讲 Web服务器控件使用
    【笔记】java多线程 2 五种状态
    【笔记】数据库模式
  • 原文地址:https://www.cnblogs.com/jalenFish/p/14099071.html
Copyright © 2011-2022 走看看