Hibernate缓存机制

Hibernate缓存机制

缓存:是计算机领域的概念,它介于应用程序和永久性数据存储源之间.Hibernate一般理解为是在内存中的一块空间,也可以将二级缓存配置到硬盘,就是一个存储数据的容器
作用:降低应用程序直接读写数据库的频率,从而提高程序的运行性能.缓存中的数据是数据存储源中数据的拷贝.缓存的物理介质通常是内存.
Hibernate缓存分为一级缓存,二级缓存查询缓存三种,每一种都有具体的使用方式和相关配置.

一级缓存

一级缓存又称为session缓存,生命周期和事务相同,周期较短.又被成为事务级别的缓存.这种缓存策略是Hibernate内置的,不可被拆卸的,默认开启.Session级别的,以及缓存总是有效的,应当保持持久化实体,修改持久化实体时,Session并不会把这种改变flush到数据库中,而是缓存到当前Session的一级缓存中,除非程序显示调用session的flush方法,或者查询关闭session时,才会把这些改变一次性的flush到数据库中,这样可以减少与数据库的交互,从而提高数据库的性能.

应用缓存

get load
get使用了一级缓存,用get查数据时,首先检查缓存是否有该数据,如果有直接从缓存中取数据,如果没有再查询数据库,并且将数据放入缓存中。
load也支持一级缓存,load还支持lazy,当load从数据库中查询数据后,也会将数据放入缓存。

Book book = session.get(Book.class, 1);
System.out.println(book.getName());
// 检查缓存是否有该数据,如果有直接从缓存中取数据
Book book2 = session.get(Book.class, 1);
System.out.println(book2.getName());
Book book = session.load(Book.class, 1);
System.out.println(book.getName());
// 检查缓存是否有该数据,如果有直接从缓存中取数据
Book book2 = session.load(Book.class, 1);
System.out.println(book2.getName());

unique
unique查询不会去查看缓存,但是unique查询的数据会放入缓存中。

String hql = "from Book where id = :id";
Book book = (Book) session.createQuery(hql)
				.setParameter("id", 1)
				.uniqueResult();
System.out.println(book);
System.out.println("====================分割线==================");
// 再次查询相同对象依旧查询了数据库,unique查询忽视缓存
Book book2 = (Book) session.createQuery(hql)
				.setParameter("id", 1)
				.uniqueResult();
System.out.println(book2);
System.out.println("====================分割线==================");
// 但是unique查询的数据会放入缓存中
Book book3 = session.get(Book.class, 1);
System.out.println(book3);

list
list查询不会去查看缓存,但是list查询的数据会放入缓存中。

String hql = "from Book";
List<Book> list = session.createQuery(hql).list();
for (Book b: list) {
	System.out.println(b);
} 
System.out.println("====================分割线==================");
// 再次查询相同对象依旧查询了数据库,list查询忽视缓存
List<Book> list2 = session.createQuery(hql).list();
for (Book b: list2) {
	System.out.println(b);
} 
System.out.println("====================分割线==================");
// 但是list查询的数据会放入缓存中
Book book = session.get(Book.class, 1);
System.out.println(book.getName());

iterator
iterator查询会执行查询id的操作,当查询具体对象时,会检查缓存中是否存在,如果存在则在缓存中取出数据.iterator查询的数据也会放入缓存.

// N+1查询
Iterator<Book> iter = session.createQuery("from Book").iterate();
for (; iter.hasNext();) {
	Book book = iter.next();
	System.out.println(book.getName());
}

管理缓存

  • flush():清除所有缓存
  • clear():清除所有缓存
  • evict():清除某个对象的缓存

二级缓存

二级缓存就是SessionFactory,进程级别的缓存,支持集群。但是二级缓存默认是没有开启的,需要我们通过配置文件及第三方缓存框架开启。SessionFactory级别的二级缓存是全局的,应用范围是所有的Seeion都共享这个二级缓存,当Session需要抓取数据时,Session就会优先从二级缓存中抓取。(主要包括实体缓存,查询缓存)。

添加依赖

添加Hibernate5.3.7版本对应的ehcache依赖

<!-- 添加ehcache依赖 -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
    <version>5.3.7.Final</version>
</dependency

添加配置

在hibernate.cfg.xml中开启二级缓存

<!-- 开启二级缓存 -->
<property name="cache.use_second_level_cache">true</property>
<property name="cache.region.factory_class">ehcache</property>

将ehcache.xml放入resources下(hibernate-release-5.3.7.Final\project\etc)

<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
  ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  -->
<ehcache>

    <!-- Sets the path to the directory where cache .data files are created.

         If the path is a Java System Property it is replaced by
         its value in the running VM.

         The following properties are translated:
         user.home - User's home directory
         user.dir - User's current working directory
         java.io.tmpdir - Default temp file path -->
    <diskStore path="java.io.tmpdir"/>


    <!--Default Cache configuration. These will applied to caches programmatically created through
        the CacheManager.

        The following attributes are required for defaultCache:

        maxInMemory       - Sets the maximum number of objects that will be created in memory
        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                            is never expired.
        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
                            if the element is not eternal. Idle time is now - last accessed time
        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
                            if the element is not eternal. TTL is now - creation time
        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                            has reached the maxInMemory limit.

        -->
    <!--
        maxElementsInMemory:设置最大存放对象的数量
        eternal:是否永久存储
        timeToIdleSeconds:设置对象的空闲时间
        timeToLiveSeconds:设置对象的存活时间
        overflowToDisk:内容溢出是否写入磁盘
    -->
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />

    <!--Predefined caches.  Add your cache configuration settings here.
        If you do not have a configuration for your cache a WARNING will be issued when the
        CacheManager starts

        The following attributes are required for defaultCache:

        name              - Sets the name of the cache. This is used to identify the cache. It must be unique.
        maxInMemory       - Sets the maximum number of objects that will be created in memory
        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                            is never expired.
        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
                            if the element is not eternal. Idle time is now - last accessed time
        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
                            if the element is not eternal. TTL is now - creation time
        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                            has reached the maxInMemory limit.

        -->

    <!-- Sample cache named sampleCache1
        This cache contains a maximum in memory of 10000 elements, and will expire
        an element if it is idle for more than 5 minutes and lives for more than
        10 minutes.

        If there are more than 10000 elements it will overflow to the
        disk cache, which in this configuration will go to wherever java.io.tmp is
        defined on your system. On a standard Linux system this will be /tmp"
        -->
    <cache name="sampleCache1"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />

    <!-- Sample cache named sampleCache2
        This cache contains 1000 elements. Elements will always be held in memory.
        They are not expired. -->
    <cache name="sampleCache2"
        maxElementsInMemory="1000"
        eternal="true"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
        overflowToDisk="false"
        /> -->
    <!-- Place configuration for your caches following -->
</ehcache>

在hibernate.cfg.xml配置文件中开启实体类缓存(推荐)

<!-- 推荐的二级缓存配置 -->
<class-cache class="cn.hibernate.pojo.Book" usage="read-write"></class-cache>

查询缓存

将查询结果集进行缓存,经常使用相同参数进行查询时,可以使用。(依赖于二级缓存)

List<Book> list = session.createQuery("from Book")
				.setCacheable(true) // 使用查询缓存
				.list();
System.out.println(list.size());
System.out.println("==================分割线==================");
HibernateUtil.closeSession();
session = HibernateUtil.getSession();
tx = session.beginTransaction();
list = session.createQuery("from Book")
			.setCacheable(true) // 使用查询缓存
			.list();
System.out.println(list.size());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值