Hibernate 二级缓存-ehcache

1 添加依赖包

<dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.12</version>
   <scope>test</scope>
  </dependency>
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>3.1.0</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>javax.servlet.jsp</groupId>
   <artifactId>javax.servlet.jsp-api</artifactId>
   <version>2.3.1</version>
  </dependency>
  <!-- pinyin4j jar -->
  <dependency>
   <groupId>com.belerweb</groupId>
   <artifactId>pinyin4j</artifactId>
   <version>2.5.0</version>
  </dependency>
  <!-- mysql驱动包 -->
  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.44</version>
  </dependency>
  <!-- hibernate -->
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>5.3.6.Final</version>
  </dependency>
  <!-- struts2 jar包 -->
  <dependency>
   <groupId>org.apache.struts</groupId>
   <artifactId>struts2-core</artifactId>
   <version>2.5.14.1</version>
  </dependency>
  <!-- pinyin4j jar -->
  <dependency>
   <groupId>com.belerweb</groupId>
   <artifactId>pinyin4j</artifactId>
   <version>2.5.0</version>
  </dependency>
  <!-- jstl 依赖包 -->
  <dependency>
   <groupId>taglibs</groupId>
   <artifactId>standard</artifactId>
   <version>1.1.2</version>
  </dependency>
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
  </dependency>
   <!-- 添加ehcache 和 hibernate-ehcache的 依赖包 -->
  <dependency>
   <groupId>net.sf.ehcache</groupId>
   <artifactId>ehcache</artifactId>
   <version>2.10.0</version>
  </dependency>
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-ehcache</artifactId>
   <version>5.3.6.Final</version>
  </dependency>

添加 ehcache.xml

<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"          updateCheck="false">     <!--磁盘存储:将缓存中暂时不使用的对象,转移到硬盘,类似于Windows系统的虚拟内存-->     <!--path:指定在硬盘上存储对象的路径-->     <!--java.io.tmpdir 是默认的临时文件路径。 可以通过如下方式打印出具体的文件路径 System.out.println(System.getProperty("java.io.tmpdir"));-->     <diskStore path="java.io.tmpdir"/> 
    <!--defaultCache:默认的管理策略-->
    <!--eternal:设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断-->
    <!--maxElementsInMemory:在内存中缓存的element的最大数目-->
    <!--overflowToDisk:如果内存中数据超过内存限制,是否要缓存到磁盘上-->
    <!--diskPersistent:是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false-->
    <!--timeToIdleSeconds:对象空闲时间(单位:秒),指对象在多长时间没有被访问就会失效。只对eternal为false的有效。默认值0,表示一直可以访问-->
    <!--timeToLiveSeconds:对象存活时间(单位:秒),指对象从创建到失效所需要的时间。只对eternal为false的有效。默认值0,表示一直可以访问-->
    <!--memoryStoreEvictionPolicy:缓存的3 种清空策略-->
    <!--FIFO:first in first out (先进先出)-->
    <!--LFU:Less Frequently Used (最少使用).意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存-->
    <!--LRU:Least Recently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存-->
    <defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false"
                  timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/>
    <!--name: Cache的名称,必须是唯一的(ehcache会把这个cache放到HashMap里)-->
    <cache name="com.zking.hibernate.entity.Book" eternal="false" maxElementsInMemory="100"
           overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
           timeToLiveSeconds="300" memoryStoreEvictionPolicy="LRU"/>
</ehcache>

添加 log4j2.xml

<?xml version="1.0" encoding="UTF-8"?> <!-- status : 指定log4j本身的打印日志的级别.ALL< Trace < DEBUG < INFO < WARN < ERROR 
 < FATAL < OFF。 monitorInterval : 用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s. -->
<Configuration status="WARN" monitorInterval="30">
 <Properties>
  <!-- 配置日志文件输出目录 ${sys:user.home} -->
  <Property name="LOG_HOME">/root/workspace/lucenedemo/logs</Property>
  <property name="ERROR_LOG_FILE_NAME">/root/workspace/lucenedemo/logs/error</property>
  <property name="WARN_LOG_FILE_NAME">/root/workspace/lucenedemo/logs/warn</property>
  <property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} - %msg%n</property>
 </Properties> <Appenders>
  <!--这个输出控制台的配置 -->
  <Console name="Console" target="SYSTEM_OUT">
   <!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
   <ThresholdFilter level="trace" onMatch="ACCEPT"
    onMismatch="DENY" />
   <!-- 输出日志的格式 -->
   <!-- %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生产时间 %p : 日志输出格式 %c : logger的名称 
    %m : 日志内容,即 logger.info("message") %n : 换行符 %C : Java类名 %L : 日志输出所在行数 %M 
    : 日志输出所在方法名 hostName : 本地机器名 hostAddress : 本地ip地址 -->
   <PatternLayout pattern="${PATTERN}" />
  </Console>  <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用 -->
  <!--append为TRUE表示消息增加到指定文件中,false表示消息覆盖指定的文件内容,默认值是true -->
  <File name="log" fileName="logs/test.log" append="false">
   <PatternLayout
    pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
  </File>
  <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size, 则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
  <RollingFile name="RollingFileInfo" fileName="${LOG_HOME}/info.log"
   filePattern="${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
   <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
   <ThresholdFilter level="info" onMatch="ACCEPT"
    onMismatch="DENY" />
   <PatternLayout
    pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
   <Policies>
    <!-- 基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。 modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am. -->
    <!-- 关键点在于 filePattern后的日期格式,以及TimeBasedTriggeringPolicy的interval, 日期格式精确到哪一位,interval也精确到哪一个单位 -->
    <!-- log4j2的按天分日志文件 : info-%d{yyyy-MM-dd}-%i.log -->
    <TimeBasedTriggeringPolicy interval="1"
     modulate="true" />
    <!-- SizeBasedTriggeringPolicy:Policies子节点, 基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小. -->
    <!-- <SizeBasedTriggeringPolicy size="2 kB" /> -->
   </Policies>
  </RollingFile>  <RollingFile name="RollingFileWarn" fileName="${WARN_LOG_FILE_NAME}/warn.log"
   filePattern="${WARN_LOG_FILE_NAME}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
   <ThresholdFilter level="warn" onMatch="ACCEPT"
    onMismatch="DENY" />
   <PatternLayout
    pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
   <Policies>
    <TimeBasedTriggeringPolicy />
    <SizeBasedTriggeringPolicy size="2 kB" />
   </Policies>
   <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
   <DefaultRolloverStrategy max="20" />
  </RollingFile>  <RollingFile name="RollingFileError" fileName="${ERROR_LOG_FILE_NAME}/error.log"
   filePattern="${ERROR_LOG_FILE_NAME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd-HH-mm}-%i.log">
   <ThresholdFilter level="error" onMatch="ACCEPT"
    onMismatch="DENY" />
   <PatternLayout
    pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
   <Policies>
    <!-- log4j2的按分钟 分日志文件 : warn-%d{yyyy-MM-dd-HH-mm}-%i.log -->
    <TimeBasedTriggeringPolicy interval="1"
     modulate="true" />
    <!-- <SizeBasedTriggeringPolicy size="10 MB" /> -->
   </Policies>
  </RollingFile> </Appenders> <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效 -->
 <Loggers>
  <!--过滤掉spring和mybatis的一些无用的DEBUG信息 -->
  <logger name="org.springframework" level="INFO"></logger>
  <logger name="org.mybatis" level="INFO"></logger>  <!-- 第三方日志系统 -->
  <logger name="org.springframework" level="ERROR" />
  <logger name="org.hibernate" level="ERROR" />
  <logger name="org.apache.struts2" level="ERROR" />
  <logger name="com.opensymphony.xwork2" level="ERROR" />
  <logger name="org.jboss" level="ERROR" />
  <!-- 配置日志的根节点 -->
  <root level="all">
   <appender-ref ref="Console" />
   <appender-ref ref="RollingFileInfo" />
   <appender-ref ref="RollingFileWarn" />
   <appender-ref ref="RollingFileError" />
  </root> </Loggers></Configuration>

2:hibernate.cfg.xml中添加二级缓存相关配置

<!-- 开启二级缓存 -->
  <property name="hibernate.cache.use_second_level_cache">true</property>
  <!-- 开启查询缓存 -->
  <property name="hibernate.cache.use_query_cache">true</property>
  <!-- EhCache驱动 -->
  <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.internal.EhcacheRegionFactory</property>

3:指定实体类开启二级缓存

    <!-- 注解式开发 -->    
   <class-cache usage="read-write" class="entity.Dict"/>   
       <!-- xml配置方式 -->
      <class name="com.zking.hibernate.entity.Book" table="t_hibernate_book">
       <cache usage="read-write" region="com.zking.hibernate.entity.Book"/>               
   .......
      </class>

4:在方法中开启二级缓存

public void testList11() {
  Query query = session.createQuery(" from Book");
      query.setCacheable(true);//手动开启二级缓存
  List<?> list = query.list();
  System.out.println(list.size());
  List<?> list1 = query.list();
  System.out.println(list1.size());
  List<?> list2 = query.list();
  System.out.println(list2.size());
 }

5:如果你没有指定实体类开启二级缓存 可以手动绑定

query.setCacheRegion("entity.Dict");//指定缓存策略,名字必须实体类的完整类名

演示结果:
演示结果

猜你喜欢

转载自blog.csdn.net/t1136237940/article/details/83589012