黑马程序员技术交流社区

标题: 【上海校区】Hibernate中一级缓存、二级缓存及查询缓存的... [打印本页]

作者: 小影姐姐    时间: 2018-5-11 12:02
标题: 【上海校区】Hibernate中一级缓存、二级缓存及查询缓存的...
1.一级缓存

1.1什么是一级缓存
一级缓存指的是Session级别的缓存,通过session查询id为1的对象,session不关闭,再次查询id为1的对象,不会发送sql语句。

1.2验证一级缓存的存在
    @Test
    public void test1() {
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
            // 先查询id为1的客户,把查询出来的对象存放到session缓存里
            Customer customer1 = session.get(Customer.class, 1L);
            // 再次查询id为1的客户,session缓存里有,就不再发送sql语句查询数据库
            Customer customer2 = session.get(Customer.class, 1L);
            //两个对象是一致的
            System.out.println(customer1==customer2);
            tx.commit();
            // session一旦关闭,一级缓存就失效了
            session.close();
    }

测试结果如下:
@Test
    public void test2() {
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
            // 先查询id为1的客户,把查询出来的对象存放到session缓存里
            Customer customer1 = session.get(Customer.class, 1L);
            // session一旦关闭,一级缓存就失效了
            session.close();
            // 再次获取新的session
            session = HibernateUtils.openSession();
            tx = session.beginTransaction();
            // 再次查询id为1的客户,一级缓存中没有,就发送sql语句查询数据库
            Customer customer2 = session.get(Customer.class, 1L);
            //两个对象不一致
            System.out.println(customer1==customer2);
            tx.commit();
            session.close();
    }

测试结果如下:

2.二级缓存
2.1什么是二级缓存
二级缓存是SessionFactory级别的缓存,可以跨Session存在。

2.2开启二级缓存
导入二级缓存所需要的jar包


在hibernate.cfg.xml中配置二级缓存的提供商

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
            <session-factory>
                    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
                    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_itheima26</property>
                    <property name="hibernate.connection.username">root</property>
                    <property name="hibernate.connection.password">123456</property>
                    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
                    <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
                    <property name="hibernate.c3p0.max_size">20</property>
                    <property name="hibernate.c3p0.min_size">5</property>
                    <property name="hibernate.c3p0.timeout">5000</property>
                    <property name="hibernate.c3p0.idle_test_period">3000</property>
                    <property name="hibernate.show_sql">true</property>
                    <property name="hibernate.format_sql">false</property>
                    <property name="hibernate.hbm2ddl.auto">update</property>
                    <property name="hibernate.current_session_context_class">thread</property>
                    <!-- 配置二级缓存提供商 -->
                    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
                    <mapping resource="cn/itcast/domain/Customer.hbm.xml"/>
            </session-factory>
    </hibernate-configuration>

在映射文件中配置缓存策略

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
   
        <class name="cn.itcast.domain.Customer" table="cst_customer">
                <!-- 只读缓存 -->
                <cache usage="read-only"/>
                <id name="custId" column="cust_id">
                        <generator class="native"></generator>
                </id>
                <property name="custName" column="cust_name"></property>
                <property name="custSource" column="cust_source"></property>
                <property name="custIndustry" column="cust_industry"></property>
                <property name="custLevel" column="cust_level"></property>
                <property name="custAddress" column="cust_address"></property>
                <property name="custPhone" column="cust_phone"></property>
        </class>
   
    </hibernate-mapping>
   

2.3验证二级缓存的存在

    @Test
    public void test3() {
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
            // 先查询id为1的客户,把查询出来的对象存放到session缓存里
            Customer customer1 = session.get(Customer.class, 1L);
            // session一旦关闭,一级缓存就失效了
            session.close();
            // 再次获取新的session
            session = HibernateUtils.openSession();
            tx = session.beginTransaction();
            // 再次查询id为1的客户,一级缓存中没有,就找二级缓存,二级缓存中存在,不用发送sql语句
            Customer customer2 = session.get(Customer.class, 1L);
            tx.commit();
            session.close();
    }

测试结果如下:


3.查询缓存
3.1什么是查询缓存
所谓查询缓存,是指把hql语句查询得到的结果集缓存起来。

3.2配置查询缓存

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
    <session-factory>
            <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
            <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_itheima26</property>
            <property name="hibernate.connection.username">root</property>
            <property name="hibernate.connection.password">123456</property>
            <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
            <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
            <property name="hibernate.c3p0.max_size">20</property>
            <property name="hibernate.c3p0.min_size">5</property>
            <property name="hibernate.c3p0.timeout">5000</property>
            <property name="hibernate.c3p0.idle_test_period">3000</property>
            <property name="hibernate.show_sql">true</property>
            <property name="hibernate.format_sql">false</property>
            <property name="hibernate.hbm2ddl.auto">update</property>
            <property name="hibernate.current_session_context_class">thread</property>
            <!-- 配置二级缓存提供商 -->
            <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
            <!-- 开启查询缓存 -->
            <property name="hibernate.cache.use_query_cache">true</property>
            <mapping resource="cn/itcast/domain/Customer.hbm.xml"/>
            </session-factory>
    </hibernate-configuration>

3.3验证查询缓存的存在

    @Test
    public void test4() {
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
   
            Query query1 = session.createQuery("select custId,custName from Customer");
            //把查询的结果放到查询缓存中
            query1.setCacheable(true);
            //iterator方法不会使用缓存
            query1.list();
            tx.commit();
            session.close();
   
            session = HibernateUtils.openSession();
            tx = session.beginTransaction();
            // 只发出一条查询语句,第二次查询不发出语句
            Query query2 = session.createQuery("select custId,custName from Customer");
            // 从查询缓存中取数据
            query2.setCacheable(true);
            query2.list();
            tx.commit();
            session.close();
    }

测试结果如下:




1.png (17.62 KB, 下载次数: 11)

1.png

2.png (20.83 KB, 下载次数: 15)

2.png





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2