一:环境搭建
controller层采用springmvc,前后台交互使用json,数据库操作使用spring data jpa,采用ehcache缓存降低操作数据库的负载。
1.1 web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>ehcache</display-name> <!-- spring配置文件加载 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:applicationContext.xml, classpath*:springContext.xml, classpath*:web-servlet.xml </param-value> </context-param> <!-- spring配置 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- spring配置文件结束 --> <!-- springMVC的监听器 --> <servlet> <servlet-name>web-practice</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>web-practice</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> <!--ehcache 页面缓存过滤器 --> <filter> <filter-name>PageCachingFilter</filter-name> <filter-class>net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter</filter-class> <init-param> <param-name>cacheName</param-name> <param-value>SimplePageCachingFilter</param-value> </init-param> </filter> <filter-mapping> <filter-name>PageCachingFilter</filter-name> <url-pattern>/userController/testPageCache.action</url-pattern> </filter-mapping> <!-- 配置log4j --> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath:log4j.properties</param-value> </context-param> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>3000</param-value> </context-param> <!-- 配置过滤器,同时把所有的请求都转为utf-8编码 --> <filter> <filter-name>Spring character encoding filter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>Spring character encoding filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
1.2 applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <!-- 开启注解 --> <context:annotation-config model="aspectj" /> <!-- 扫描包 --> <context:component-scan base-package="com.travelsky.pss" /> <!-- 自动扫描并注入Spring Data JPA --> <jpa:repositories base-package="com.travelsky.pss.dao" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" /> <!-- 加载JDBC连接信息 --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- 开启事物 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="false" /> <cache:annotation-driven cache-manager="ehcacheManager"/> <!-- cacheManager工厂类,指定ehcache.xml的位置 --> <bean id="ehcacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:shared="true"> <property name="configLocation" value="classpath:ehcache.xml" /> </bean> <!-- 声明cacheManager --> <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="ehcacheManagerFactory" /> </bean> <!-- 配置数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.driverUrl}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- 配置连接池的初始值 --> <property name="initialSize" value="${jdbc.initialSize}" /> <!-- 连接池的最大值 --> <!-- <property name="maxActive" value="500"/> --> <!-- 最大空闲时,当经过一个高峰之后,连接池可以将一些用不到的连接释放,一直减少到maxIdle为止 --> <!-- <property name="maxIdle" value="2"/> --> <!-- 当最小空闲时,当连接少于minIdle时会自动去申请一些连接 --> <property name="minIdle" value="${jdbc.minIdle}" /> <property name="maxActive" value="${jdbc.maxActive}" /> <property name="maxWait" value="${jdbc.maxWait}" /> </bean> <!-- 配置entityManagerFactory --> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="persistenceUnitName" value="react" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="database" value="MYSQL"></property> <property name="showSql" value="true"></property> <property name="generateDdl" value="true" /> </bean> </property> <property name="packagesToScan"> <list> <value>com.travelsky.pss.vo</value> </list> </property> <property name="jpaPropertyMap" ref="jpaPropertyMap" /> </bean> <util:map id="jpaPropertyMap"> <entry key="dialect" value="org.hibernate.dialect.MySQLDialect" /> <entry key="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" /> <entry key="hibernate.hbm2ddl.auto" value="none" /> <entry key="hibernate.cache.use_second_level_cache" value="false" /> <entry key="hibernate.cache.use_query_cache" value="false" /> <entry key="hibernate.generate_statistics" value="false" /> <entry key="show_sql" value="true" /> <entry key="format_sql" value="false" /> <entry key="javax.persistence.validation.mode" value="none" /> </util:map> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <!-- 开启AOP监听 --> <aop:aspectj-autoproxy expose-proxy="true" /> <!-- 配置哪些方法要加入事务控制 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 让所有的方法都加入事务管理,为了提高效率,可以把一些查询之类的方法设置为只读的事务 --> <tx:method name="*" propagation="REQUIRED" read-only="true" /> <!-- 以下方法都是可能设计修改的方法,就无法设置为只读 --> <tx:method name="insert*" propagation="REQUIRED" read-only="false" /> <tx:method name="add*" propagation="REQUIRED" read-only="false" /> <tx:method name="del*" propagation="REQUIRED" read-only="false" /> <tx:method name="update*" propagation="REQUIRED" read-only="false" /> <tx:method name="save*" propagation="REQUIRED" read-only="false" /> <tx:method name="clear*" propagation="REQUIRED" read-only="false" /> </tx:attributes> </tx:advice> <!-- 配置AOP,Spring是通过AOP来进行事务管理的 --> <aop:config> <!-- 设置pointCut表示哪些方法要加入事务处理 --> <aop:pointcut id="allMethods" expression="execution(* com.travelsky.pss.*.service..*.*(..))" /> <!-- 通过advisor来确定具体要加入事务控制的方法 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="allMethods" /> </aop:config> </beans>
1.3 springmvc配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> <!-- 注解扫描包 --> <context:component-scan base-package="com.travelsky.pss"/> <!-- 打开注解 --> <mvc:annotation-driven /> <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="jsonHttpMessageConverter"/> </list> </property> </bean> <!-- JSON的转换 --> <bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /> <!-- 配置视图解析器,将ModelAndView解析为具体的页面 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="contentType" value="text/html; charset=utf-8"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
1.4 ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" monitoring="autodetect" dynamicConfig="true" > <!-- monitoring: 使用"autodetect"值,Terracotta集群的出现将被检测和监视,并通过Developer控制台激活 dynamicConfig: 能够使与这个CacheManager相关联的动态配置失活。这个设置的默认值是true-例如,动态配置是激活的 --> <diskStore path="java.io.tmpdir" /> <defaultCache maxEntriesLocalHeap="10000" eternal="false" overflowToDisk="false" timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30" maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> <persistence strategy="localTempSwap" /> </defaultCache> <!-- maxBytesLocalHeap:主要是用来限制缓存所能使用的堆内存的最大字节数 maxEntriesLocalHeap:用来限制当前缓存在堆内存上所能保存的最大元素数量的 maxEntriesLocalDisk:用来限制在磁盘上所能保存的元素的最大数量的 eternal :缓存中对象是否永久有效,即是否永驻内存,如果为true,将忽略timeToIdleSeconds="300" timeToLiveSeconds="600" timeToIdleSeconds : 缓存数据在失效前的允许闲置时间(单位:秒),仅当eternal=false时使用,默认值是0表示可闲置时间无穷大,此为可选属性 即访问这个cache中元素的最大间隔时间,若超过这个时间没有访问此Cache中的某个元素,那么此元素将被从Cache中清除 timeToLiveSeconds : 缓存数据在失效前的允许存活时间(单位:秒),仅当eternal=false时使用,默认值是0表示可存活时间无穷大 即Cache中的某元素从创建到清楚的生存时间,也就是说从创建开始计时,当超过这个时间时,此元素将从Cache中清除 overflowToDisk : 内存不足时,是否启用磁盘缓存(即内存中对象数量达到maxElementsInMemory时,Ehcache会将对象写到磁盘中) memoryStoreEvictionPolicy : 内存存储与释放策略,即达到maxElementsInMemory限制时,Ehcache会根据指定策略清理内存 共有三种策略,分别为LRU(最近最少使用)、LFU(最常用的)、FIFO(先进先出) transactionalMode: 使ehcache作为JTA事务的参与者 --> <cache name="myCache" maxEntriesLocalHeap="10000" maxEntriesLocalDisk="1000" eternal="false" diskSpoolBufferSizeMB="30" timeToIdleSeconds="300" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU" transactionalMode="off"> <cacheEventListenerFactory class="com.travelsky.pss.listener.MyCacheEventListenerFactory"/> <persistence strategy="localTempSwap" /> </cache> <!-- 页面全部缓存 --> <cache name="SimplePageCachingFilter" maxElementsInMemory="10" maxElementsOnDisk="10" eternal="false" overflowToDisk="false" timeToIdleSeconds="120" timeToLiveSeconds="60" memoryStoreEvictionPolicy="LFU"> </cache> </ehcache>
1.5:jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.driverUrl = jdbc:mysql://localhost:3306/ehcache?useUnicode=true&characterEncoding=UTF-8 jdbc.username = root jdbc.password = 123 jdbc.initialSize=1 jdbc.minIdle=1 jdbc.maxActive=50 jdbc.maxWait=100
二:代码示例
2.1 controller层
package com.travelsky.pss.controller; import java.util.Date; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import com.travelsky.pss.service.UserService; import com.travelsky.pss.vo.User; @Controller @RequestMapping("/userController") public class UserController { @Autowired private transient UserService userService; @ResponseBody @RequestMapping("/saveUser") public String saveUser(HttpServletRequest request, HttpServletResponse response) { String userId = request.getParameter("userId"); String username = request.getParameter("userName"); User user = new User(); user.setId(userId); user.setUserName(username); user.setSex("0"); user.setAge("25"); userService.save(user); return "SUCCESS"; } @RequestMapping("/findUser") public ModelAndView findUser() { ModelMap modelMap = new ModelMap(); User user = userService.find("0"); modelMap.addAttribute("data", user); return new ModelAndView("show", modelMap); } @RequestMapping("/coutUserNum") public ModelAndView coutUserNum(){ ModelMap modelMap = new ModelMap(); int number = userService.coutNum(); modelMap.addAttribute("number", number); return new ModelAndView("count", modelMap); } @RequestMapping("/testPageCache") public ModelAndView testPageCache(){ ModelMap modelMap = new ModelMap(); System.out.println("===========页面缓存进来了"); modelMap.addAttribute("data", new Date()); return new ModelAndView("pageCache", modelMap); } }
2.2 service层
package com.travelsky.pss.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import com.travelsky.pss.dao.UserDao; import com.travelsky.pss.vo.User; @Service("userService") public class UserService { @Autowired private transient UserDao userDao; @CacheEvict(value="myCache",key="0",beforeInvocation=true) public void save(User user){ userDao.save(user); } @Cacheable(value="myCache",key="#id") public User find(String id){ return userDao.findOne(id); } public void delete(String id){ userDao.delete(id); } public void update(User user) { userDao.saveAndFlush(user); } @Cacheable(value="myCache", key="0") public int coutNum(){ int numer = userDao.findAll().size(); return numer; } }
2.3 dao层
package com.travelsky.pss.dao; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import com.travelsky.pss.vo.User; @Repository public interface UserDao extends JpaRepository<User,String> { }
2.4 浏览器访问
http://localhost:8080/ehcache/userController/coutUserNum.action
效果如下:
Tue May 31 16:24:29 CST 2016 缓存测试 User的数量: 6
查看eclipse控制台
[20160531 16:24:29][http-bio-8080-exec-6][DispatcherServlet.doService]DispatcherServlet with name 'web-practice' processing GET request for [/ehcache/userController/coutUserNum.action] [20160531 16:24:29][http-bio-8080-exec-6][AbstractHandlerMethodMapping.getHandlerInternal]Looking up handler method for path /userController/coutUserNum.action [20160531 16:24:29][http-bio-8080-exec-6][AbstractHandlerMethodMapping.getHandlerInternal]Returning handler method [public org.springframework.web.servlet.ModelAndView com.travelsky.pss.controller.UserController.coutUserNum()] [20160531 16:24:29][http-bio-8080-exec-6][AbstractBeanFactory.doGetBean]Returning cached instance of singleton bean 'userController' [20160531 16:24:29][http-bio-8080-exec-6][DispatcherServlet.doDispatch]Last-Modified value for [/ehcache/userController/coutUserNum.action] is: -1 expired [20160531 16:24:29][http-bio-8080-exec-6][AbstractPlatformTransactionManager.getTransaction]Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; '' [20160531 16:24:29][http-bio-8080-exec-6][JpaTransactionManager.doBegin]Opened new EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@18c53c] for JPA transaction [20160531 16:24:29][http-bio-8080-exec-6][AbstractTransactionImpl.begin]begin [20160531 16:24:29][http-bio-8080-exec-6][LogicalConnectionImpl.obtainConnection]Obtaining JDBC connection [20160531 16:24:29][http-bio-8080-exec-6][LogicalConnectionImpl.obtainConnection]Obtained JDBC connection [20160531 16:24:29][http-bio-8080-exec-6][JdbcTransaction.doBegin]initial autocommit status: true [20160531 16:24:29][http-bio-8080-exec-6][JdbcTransaction.doBegin]disabling autocommit [20160531 16:24:29][http-bio-8080-exec-6][JpaTransactionManager.doBegin]Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@3cf593] [20160531 16:24:29][http-bio-8080-exec-6][CriteriaQueryImpl.interpret]Rendered criteria query -> select generatedAlias0 from User as generatedAlias0 [20160531 16:24:29][http-bio-8080-exec-6][SqlStatementLogger.logStatement]select user0_.id as id1_0_, user0_.age as age2_0_, user0_.sex as sex3_0_, user0_.name as name4_0_ from user user0_ Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.sex as sex3_0_, user0_.name as name4_0_ from user user0_ [20160531 16:24:29][http-bio-8080-exec-6][Loader.processResultSet]Result set row: 0 [20160531 16:24:29][http-bio-8080-exec-6][Loader.getRow]Result row: EntityKey[com.travelsky.pss.vo.User#0] [20160531 16:24:29][http-bio-8080-exec-6][Loader.processResultSet]Result set row: 1 [20160531 16:24:29][http-bio-8080-exec-6][Loader.getRow]Result row: EntityKey[com.travelsky.pss.vo.User#1] [20160531 16:24:29][http-bio-8080-exec-6][Loader.processResultSet]Result set row: 2 [20160531 16:24:29][http-bio-8080-exec-6][Loader.getRow]Result row: EntityKey[com.travelsky.pss.vo.User#2] [20160531 16:24:29][http-bio-8080-exec-6][Loader.processResultSet]Result set row: 3 [20160531 16:24:29][http-bio-8080-exec-6][Loader.getRow]Result row: EntityKey[com.travelsky.pss.vo.User#11] [20160531 16:24:29][http-bio-8080-exec-6][Loader.processResultSet]Result set row: 4 [20160531 16:24:29][http-bio-8080-exec-6][Loader.getRow]Result row: EntityKey[com.travelsky.pss.vo.User#66] [20160531 16:24:29][http-bio-8080-exec-6][Loader.processResultSet]Result set row: 5 [20160531 16:24:29][http-bio-8080-exec-6][Loader.getRow]Result row: EntityKey[com.travelsky.pss.vo.User#5555] [20160531 16:24:29][http-bio-8080-exec-6][TwoPhaseLoad.doInitializeEntity]Resolving associations for [com.travelsky.pss.vo.User#0] [20160531 16:24:29][http-bio-8080-exec-6][TwoPhaseLoad.doInitializeEntity]Done materializing entity [com.travelsky.pss.vo.User#0] [20160531 16:24:29][http-bio-8080-exec-6][TwoPhaseLoad.doInitializeEntity]Resolving associations for [com.travelsky.pss.vo.User#1] [20160531 16:24:29][http-bio-8080-exec-6][TwoPhaseLoad.doInitializeEntity]Done materializing entity [com.travelsky.pss.vo.User#1] [20160531 16:24:29][http-bio-8080-exec-6][TwoPhaseLoad.doInitializeEntity]Resolving associations for [com.travelsky.pss.vo.User#2] [20160531 16:24:29][http-bio-8080-exec-6][TwoPhaseLoad.doInitializeEntity]Done materializing entity [com.travelsky.pss.vo.User#2] [20160531 16:24:29][http-bio-8080-exec-6][TwoPhaseLoad.doInitializeEntity]Resolving associations for [com.travelsky.pss.vo.User#11] [20160531 16:24:29][http-bio-8080-exec-6][TwoPhaseLoad.doInitializeEntity]Done materializing entity [com.travelsky.pss.vo.User#11] [20160531 16:24:29][http-bio-8080-exec-6][TwoPhaseLoad.doInitializeEntity]Resolving associations for [com.travelsky.pss.vo.User#66] [20160531 16:24:29][http-bio-8080-exec-6][TwoPhaseLoad.doInitializeEntity]Done materializing entity [com.travelsky.pss.vo.User#66] [20160531 16:24:29][http-bio-8080-exec-6][TwoPhaseLoad.doInitializeEntity]Resolving associations for [com.travelsky.pss.vo.User#5555] [20160531 16:24:29][http-bio-8080-exec-6][TwoPhaseLoad.doInitializeEntity]Done materializing entity [com.travelsky.pss.vo.User#5555] [20160531 16:24:29][http-bio-8080-exec-6][AbstractPlatformTransactionManager.processCommit]Initiating transaction commit [20160531 16:24:29][http-bio-8080-exec-6][JpaTransactionManager.doCommit]Committing JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@18c53c] [20160531 16:24:29][http-bio-8080-exec-6][AbstractTransactionImpl.commit]committing [20160531 16:24:29][http-bio-8080-exec-6][JdbcTransaction.doCommit]committed JDBC Connection [20160531 16:24:29][http-bio-8080-exec-6][JdbcTransaction.releaseManagedConnection]re-enabling autocommit [20160531 16:24:29][http-bio-8080-exec-6][JpaTransactionManager.doCleanupAfterCompletion]Closing JPA EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@18c53c] after transaction [20160531 16:24:29][http-bio-8080-exec-6][EntityManagerFactoryUtils.closeEntityManager]Closing JPA EntityManager [20160531 16:24:29][http-bio-8080-exec-6][LogicalConnectionImpl.releaseConnection]Releasing JDBC connection [20160531 16:24:29][http-bio-8080-exec-6][LogicalConnectionImpl.releaseConnection]Released JDBC connection [20160531 16:24:29][http-bio-8080-exec-6][Segment.put]put added 0 on heap put [20160531 16:24:29][http-bio-8080-exec-6][DispatcherServlet.render]Rendering view [org.springframework.web.servlet.view.JstlView: name 'count'; URL [/WEB-INF/jsp/count.jsp]] in DispatcherServlet with name 'web-practice' [20160531 16:24:29][my%0043ache.data][Segment.fault]fault removed 0 from heap [20160531 16:24:29][my%0043ache.data][Segment.fault]fault added 0 on disk [20160531 16:24:29][http-bio-8080-exec-6][AbstractView.exposeModelAsRequestAttributes]Added model object 'number' of type [java.lang.Integer] to request in view with name 'count' [20160531 16:24:29][http-bio-8080-exec-6][InternalResourceView.renderMergedOutputModel]Forwarding to resource [/WEB-INF/jsp/count.jsp] in InternalResourceView 'count' [20160531 16:24:29][http-bio-8080-exec-6][FrameworkServlet.processRequest]Successfully completed request
可以看到,在缓存失效后,重新查询了数据库,当你再次刷新页面
Tue May 31 16:26:40 CST 2016 缓存测试 User的数量: 6
eclipse控制台
[20160531 16:26:40][http-bio-8080-exec-8][DispatcherServlet.doService]DispatcherServlet with name 'web-practice' processing GET request for [/ehcache/userController/coutUserNum.action] [20160531 16:26:40][http-bio-8080-exec-8][AbstractHandlerMethodMapping.getHandlerInternal]Looking up handler method for path /userController/coutUserNum.action [20160531 16:26:40][http-bio-8080-exec-8][AbstractHandlerMethodMapping.getHandlerInternal]Returning handler method [public org.springframework.web.servlet.ModelAndView com.travelsky.pss.controller.UserController.coutUserNum()] [20160531 16:26:40][http-bio-8080-exec-8][AbstractBeanFactory.doGetBean]Returning cached instance of singleton bean 'userController' [20160531 16:26:40][http-bio-8080-exec-8][DispatcherServlet.doDispatch]Last-Modified value for [/ehcache/userController/coutUserNum.action] is: -1 [20160531 16:26:40][http-bio-8080-exec-8][DispatcherServlet.render]Rendering view [org.springframework.web.servlet.view.JstlView: name 'count'; URL [/WEB-INF/jsp/count.jsp]] in DispatcherServlet with name 'web-practice' [20160531 16:26:40][http-bio-8080-exec-8][AbstractView.exposeModelAsRequestAttributes]Added model object 'number' of type [java.lang.Integer] to request in view with name 'count' [20160531 16:26:40][http-bio-8080-exec-8][InternalResourceView.renderMergedOutputModel]Forwarding to resource [/WEB-INF/jsp/count.jsp] in InternalResourceView 'count' [20160531 16:26:40][http-bio-8080-exec-8][FrameworkServlet.processRequest]Successfully completed request
发现并没有操作数据库的日志打印出来,因为这个时候直接从缓存获取了。
项目源码下载:亲测可用