• Hibernate二级缓存以及ehcache的搭建配置


    转载自      https://blog.csdn.net/fengshizty/article/details/43603611

    前言

            这次主要复习Hibernate的二级缓存的相关知识,配置以及使用。二级缓存主要采用第三方的ehcache,也将介绍ehcache缓存的相关配置属性以及在项目中的搭建,具体的项目查看下一篇的 Maven搭建SpringMVC+Hibernate项目详解 的文章。(之前使用过Hibernate的二级缓存,但是没自己搭建和研究过,现在花了半天时间搭建了一下,写下来供大家参考)

    1、Hibernate二级缓存

         Hibernate包括两个级别的缓存:

            1、一级缓存:默认总是启用的session级别的。

             2、二级缓存:可选的SessionFactory级别的。

           Session级别的以及缓存总是有效的,当应用保持持久化实体、修改持久化实体时,Session并不会吧这种改变flush到数据库,而是缓存在当前Session的一级缓存中,除非程序显示调用session的flush方法,或者查询关闭session时,才会把这先改变一次性的flush到底层数据库,这样可以减少与数据库的交互,从而提高数据库的访问性能。

          SessionFactory级别的二级缓存是全局的,应用的所有的Seeion都共享这个二级缓存,当Session需要抓取数据时,Session就会优先从二级缓存中抓取。(主要包括实体缓存,查询缓存)。

    2、适用范围

          主要适合以下数据放入二级缓存:

               1. 很少被修改,大量查询的

                2. 不是很重要的数据,允许出现偶尔并发访问的

    3、Hibernate二级缓存的配置

                  Hibernate的二级缓存主要使用第三方缓存插件,这里主要使用Ehcache二级缓存。

             首先、我们需要映入ehcache包以及hibernate-ehcache包,maven的pom.xml映入如下:

             

     1  
     2 <!-- hibernate -->
     3  
     4 <dependency>
     5  
     6 <groupId>org.hibernate</groupId>
     7  
     8 <artifactId>hibernate-core</artifactId>
     9  
    10 <version>4.3.8.Final</version>
    11  
    12 </dependency>
    13  
    14  
    15  
    16 <dependency>
    17  
    18 <groupId>org.hibernate</groupId>
    19  
    20 <artifactId>hibernate-ehcache</artifactId>
    21  
    22 <version>4.3.8.Final</version>
    23  
    24 </dependency>
    25  
    26  
    27  
    28 <!-- 二级缓存ehcache -->
    29  
    30 <dependency>
    31  
    32 <groupId>net.sf.ehcache</groupId>
    33  
    34 <artifactId>ehcache</artifactId>
    35  
    36 <version>2.9.0</version>
    37  
    38 </dependency>


             其次、我们需要在Hibernate的配置文件中设置二级缓存的相关信息

                     

     1 <!-- 开启二级缓存 ehcache -->
     2  
     3 <prop key="hibernate.cache.use_second_level_cache">true</prop>
     4  
     5 <!-- 开启查询的二级缓存 如果不需要就不设置-->
     6  
     7 <prop key="hibernate.cache.use_query_cache">true</prop>
     8  
     9 <!-- Hibernate4.0以上设置factory -->
    10  
    11 <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
    12  
    13 <!-- 二级缓存 ehcache的配置文件位置 -->
    14  
    15 <prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</prop>

                一般Hibernate的二级缓存实体和属性的缓存映射,如果需要将查询数据也二级缓存,需要使用hibernate.cache.use_query_cache开启。

     

    4、Ehcache的配置

          ehcache.xml的配置文件如下:

         

     1  
     2 <?xml version="1.0" encoding="UTF-8"?>
     3  
     4 <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
     5  
     6  
     7  
     8 <diskStore path="java.io.tmpdir/ehcache" />
     9  
    10 <!-- DefaultCache setting. -->
    11  
    12 <defaultCache
    13  
    14 maxElementsInMemory="1000"
    15  
    16 eternal="false"
    17  
    18 timeToIdleSeconds="300"
    19  
    20 timeToLiveSeconds="300"
    21  
    22 maxElementsOnDisk="1000000"
    23  
    24 overflowToDisk="true"
    25  
    26 memoryStoreEvictionPolicy="LRU">
    27  
    28  
    29  
    30 </defaultCache>
    31  
    32  
    33  
    34 <!-- Special objects setting. -->
    35  
    36 <!--
    37  
    38 <cache
    39  
    40 name="org.andy.work.entity.AcctUser"
    41  
    42 maxElementsInMemory="2"
    43  
    44 memoryStoreEvictionPolicy="LRU"
    45  
    46 eternal="true"
    47  
    48 diskPersistent="false"
    49  
    50 overflowToDisk="false"
    51  
    52 maxElementsOnDisk="1000000" /> -->
    53  
    54  
    55  
    56  
    57  
    58  
    59  
    60 </ehcache>

    第一段是配置默认的ehcache二级缓存信息,第二段是特殊的配置(需要配置特殊时)。

    4.1、配置详解

        name:缓存名称。
        maxElementsInMemory:缓存最大个数。
        eternal:对象是否永久有效,一但设置了,timeout将不起作用。
        timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
        timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
       overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
       diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
       maxElementsOnDisk:硬盘最大缓存个数。
       diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
       diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
       memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
       clearOnFlush:内存数量最大时是否清除。 

       注:java.io.tmpdir目录为:C:Users登录用户AppDataLocalTemp(window环境中),所以上面在我的电脑下的目录如下(已经有缓存内容):

           

         当然存储位置我们可以随意的配置如:   <diskStore path="D:/ehcache" />  就是在D盘下的ehcache目录了。

    5、配置需二级缓存实体和属性

          这里只介绍注解形式的,xml形式的不说了,大多数公司都用注解。

        在实体类和实体的那些集合属性上启用二级缓存使用

                  @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

       注:如果一个实体需要二级缓存,若该实体含有<set...>,<list...>等属性时,也必须要指定缓存策略。

           如下:

         

      1  
      2 package org.andy.work.entity;
      3  
      4  
      5  
      6 // Generated 2015-2-3 10:43:00 by Hibernate Tools 4.0.0
      7  
      8  
      9  
     10 import java.util.Date;
     11  
     12 import java.util.HashSet;
     13  
     14 import java.util.Set;
     15  
     16  
     17  
     18 import javax.persistence.Column;
     19  
     20 import javax.persistence.Entity;
     21  
     22 import javax.persistence.FetchType;
     23  
     24 import javax.persistence.Id;
     25  
     26 import javax.persistence.JoinColumn;
     27  
     28 import javax.persistence.JoinTable;
     29  
     30 import javax.persistence.ManyToMany;
     31  
     32 import javax.persistence.Table;
     33  
     34 import javax.persistence.Temporal;
     35  
     36 import javax.persistence.TemporalType;
     37  
     38  
     39  
     40 import org.hibernate.annotations.Cache;
     41  
     42 import org.hibernate.annotations.CacheConcurrencyStrategy;
     43  
     44  
     45  
     46 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
     47  
     48  
     49  
     50 /**
     51  
     52 * AcctUser generated by hbm2java
     53  
     54 */
     55  
     56 @Entity
     57  
     58 @Table(name = "acct_user", catalog = "work")
     59  
     60 @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
     61  
     62 public class AcctUser implements java.io.Serializable {
     63  
     64  
     65  
     66 /**
     67  
     68 *
     69  
     70 */
     71  
     72 private static final long serialVersionUID = 6980093847795726310L;
     73  
     74 private String id;
     75  
     76 private String nickName;
     77  
     78 private String telephone;
     79  
     80 private Date registerTime;
     81  
     82 private Set<AcctRole> acctRoles = new HashSet<AcctRole>(0);
     83  
     84  
     85  
     86 public AcctUser() {
     87  
     88  
     89  
     90 }
     91  
     92  
     93  
     94 public AcctUser(String id, String nickName) {
     95  
     96 this.id = id;
     97  
     98 this.nickName = nickName;
     99  
    100 }
    101  
    102  
    103  
    104 public AcctUser(String id, String nickName, String telephone,
    105  
    106 Date registerTime, Set<AcctRole> acctRoles) {
    107  
    108 this.id = id;
    109  
    110 this.nickName = nickName;
    111  
    112 this.telephone = telephone;
    113  
    114 this.registerTime = registerTime;
    115  
    116 this.acctRoles = acctRoles;
    117  
    118 }
    119  
    120  
    121  
    122 @Id
    123  
    124 @Column(name = "id", unique = true, nullable = false, length = 36)
    125  
    126 public String getId() {
    127  
    128 return this.id;
    129  
    130 }
    131  
    132  
    133  
    134 public void setId(String id) {
    135  
    136 this.id = id;
    137  
    138 }
    139  
    140  
    141  
    142 @Column(name = "nick_name", nullable = false)
    143  
    144 public String getNickName() {
    145  
    146 return this.nickName;
    147  
    148 }
    149  
    150  
    151  
    152 public void setNickName(String nickName) {
    153  
    154 this.nickName = nickName;
    155  
    156 }
    157  
    158  
    159  
    160 @Column(name = "telephone")
    161  
    162 public String getTelephone() {
    163  
    164 return this.telephone;
    165  
    166 }
    167  
    168  
    169  
    170 public void setTelephone(String telephone) {
    171  
    172 this.telephone = telephone;
    173  
    174 }
    175  
    176  
    177  
    178 @Temporal(TemporalType.TIMESTAMP)
    179  
    180 @Column(name = "register_time", length = 19)
    181  
    182 public Date getRegisterTime() {
    183  
    184 return this.registerTime;
    185  
    186 }
    187  
    188  
    189  
    190 public void setRegisterTime(Date registerTime) {
    191  
    192 this.registerTime = registerTime;
    193  
    194 }
    195  
    196  
    197  
    198 @JsonIgnoreProperties(value={"acctUsers", "acctAuthorities"})
    199  
    200 @ManyToMany(fetch = FetchType.LAZY)
    201  
    202 @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    203  
    204 @JoinTable(name = "acct_user_role", catalog = "work", joinColumns = { @JoinColumn(name = "user_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "role_id", nullable = false, updatable = false) })
    205  
    206 public Set<AcctRole> getAcctRoles() {
    207  
    208 return this.acctRoles;
    209  
    210 }
    211  
    212  
    213  
    214 public void setAcctRoles(Set<AcctRole> acctRoles) {
    215  
    216 this.acctRoles = acctRoles;
    217  
    218 }
    219  
    220  
    221  
    222 }

    5.1、缓存usage事务隔离机制

            Usage提供缓存对象的事务隔离机制有如下几种:

            (NONE, READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL)

          ehcache不支持transaction事务机制,但其他三种可以使用:

           read-only::

                     无需修改, 那么就可以对其进行只读 缓存,注意,在此策略下,如果直接修改数据库,即使能够看到前台显示效果,

                 但是将对象修改至cache中会报error,cache不会发生作用。另:删除记录会报错,因为不能在read-only模式的对象从cache中删除。

          read-write: 

                       需要更新数据,那么使用读/写缓存 比较合适,前提:数据库不可以为serializable transaction isolation level(序列化事务隔离级别)

         nonstrice-read-write:

                      只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离,那么比较适合使用非严格读/写缓存策略。

    6、使用查询缓存

          查询缓存所缓存的key值就是查询所使用的HQL或SQL语句,需要注意的是:查询缓存不仅要求所使用的HQL语句、SQL语句相同,甚至是要求所传入的参数也相同,Hibernate才能从缓存中查去数据。

       查询缓存有如下两步:

          1、查询缓存不不仅开启 hibernate.cache.use_query_cache

          2、还需要在查询时使用  setCacheable(true)

        

    public List<AcctUser> findAll() {
     
    List<AcctUser> acctUsers = this.getCurrentSession().createQuery("from AcctUser").setCacheable(true).list();
     
     
     
    return acctUsers;
  • 相关阅读:
    虚拟机配置桥接网络以及使用mobaxterm连接虚拟机
    maven依赖包问题2
    47.火狐浏览器登录过全球服务器之后,切换回本地服务器登录失败解决方法
    博客园美化
    vue拼图验证(vue-puzzle-vcode)
    vue使用axios
    vue中使用swiper
    VUE安装并配置
    vue中router-view不显示
    vue打包后空白
  • 原文地址:https://www.cnblogs.com/kwaitfort/p/9491775.html
Copyright © 2020-2023  润新知