缓存第二篇:maven项目中ssm整合ehcache_万米高空的博客-程序员宅基地

技术标签: redis缓存相关  ehcache  maven  ssm  

上一节做了ehcache的入门级别的学习,这节接近真实项目做了一次整合。发现上一节的有些东西是多余的,几乎没啥用。ehcache我们主要使用的是与mabatis的mapper结合使用。

环境:jdk1.7+maven3.3.9+win7
框架:ssm+maven
参考资料:
ehcache官方文档

1.工程目录

这里写图片描述

2.引入依赖 包括ssm+ehcache

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zhanglf</groupId>
    <artifactId>SpringEhcacheProject</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>EhCcheProject Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <!--spring版本号 -->
        <spring.version>4.0.2.RELEASE</spring.version>
        <!--mybatis版本号 -->
        <mybatis.version>3.2.6</mybatis.version>
        <!--log4j日志文件管理包版本 -->
        <slf4j.version>1.7.7</slf4j.version>
        <slf4j.version>1.2.17</slf4j.version>
    </properties>


    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>


        <!-- 添加 Spring依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--spring核心包 -->

        <!--spring单元测试依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>


        <!--mybatis核心包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
        <!--mybatis核心包 -->

        <!--mybatis-spring包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.2</version>
        </dependency>
        <!--mybatis-spring包 -->

        <!--导入数据库连接jar包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.30</version>
        </dependency>
        <!--导入数据库连接jar包 -->

        <!-- 导入jbcp的jar,用来在application.xml中配置数据库, 如jndi,是主流数据库连接池之一 -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.2.2</version>
        </dependency>
        <!-- 导入jbcp的jar,用来在application.xml中配置数据库, 如jndi,是主流数据库连接池之一 -->

        <!-- JSTL标签类 -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- JSTL标签类 -->

        <!-- ehcache 相关依赖 -->
        <dependency>
            <groupId>org.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>3.1.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-ehcache -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.0.0</version>
        </dependency>




        <!-- 序列化:将对象转换为JSON字符串 String strJson=JSON.toJSONString(实体对象); 反序列化: UserInfo 
            userInfo=JSON.parseObject(json,UserInfo.class); -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- 数据库连接池druid、 用于数据库字段加、解密 -->
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.26</version>
        </dependency>



        <!-- 映入JSON -->
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>

    </dependencies>
    <build>
        <finalName>SpringEhcacheProject</finalName>
        <!-- Compiler插件,指定jdk版本 -->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

3.引入各种配置文件

3.1 cache文件夹下的chcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <!-- java.io.tmpdir:Java临时目录。指定一个文件目录,当EhCache把数据写到硬盘上或者系统jvm内存时,将把数据写到这个文件目录下 -->
    <diskStore path="java.io.tmpdir"/>

<!-- maxElementsInMemory:设置基于内存的缓存可存放对象的最大数目。  -->
<!-- eternal:如果为true,表示对象永远不会过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false; -->
<!-- timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,如果处于空闲状态的时间超过了 -->
<!-- timeToIdleSeconds属性值,这个对象就会过期。当对象过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。 -->
<!-- 如果该属性值为0,则表示对象可以无限期地处于空闲状态。  -->
<!-- timeToLiveSeconds:设定对象允许存在于缓存中的最长时间,以秒为单位。当对象自从被存放到缓存中后,如果处于缓存中的时间超过了 timeToLiveSeconds属性值,这个对象就会过期。当对象过期,EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地存在于缓存中。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义。  -->
<!-- overflowToDisk:如果为true,表示当基于内存的缓存中的对象数目达到了maxElementsInMemory界限后,会把益出的对象写到基于硬盘的缓存中。 -->

    <!-- 设定缓存的默认数据过期策略 -->
    <defaultCache
            maxElementsInMemory="10000" 
            eternal="false" 
            overflowToDisk="true"
            timeToIdleSeconds="10"
            timeToLiveSeconds="20"
            diskPersistent="false"  
 diskExpiryThreadIntervalSeconds="120"/>

<!--  自定义缓存策略-学生信息缓存容器对应策略-->
    <cache name="studentCache"          
        maxElementsInMemory="1000"  
        eternal="false"             
        overflowToDisk="true"       
        timeToIdleSeconds="10"      
        timeToLiveSeconds="20"/>
   <!--  自定义缓存策略-教师信息缓存容器对应策略-->  
<!--      <cache name="techerCache"          -->
<!--         maxElementsInMemory="1000"  -->
<!--         eternal="false"                 -->
<!--         overflowToDisk="true"       -->
<!--         timeToIdleSeconds="10"      -->
<!--         timeToLiveSeconds="20"/>        -->

</ehcache>

3.2 context文件夹下的applicationContext.xml中开启和引入缓存到spring框架

<?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:cache="http://www.springframework.org/schema/cache"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="  
           http://www.springframework.org/schema/beans  
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
           http://www.springframework.org/schema/aop  
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           http://www.springframework.org/schema/context  
           http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/cache 
           http://www.springframework.org/schema/cache/spring-cache-3.1.xsd">
    <!-- 自动扫描注解的bean -->
    <context:component-scan base-package="com.**.cache;com.**.service;com.**.dao">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    <!-- 开启spring缓存 -->
    <cache:annotation-driven cache-manager="cacheManager" />  

    <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">  
        <property name="configLocation" value="classpath:/META-INF/app_config/cache/ehcache.xml"></property>  
    </bean>  

    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">  
        <property name="cacheManager" ref="ehcache"></property>  
    </bean>  


</beans>

3.3 mybatis文件夹下mybatis配置 spring-mybatis.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:p="http://www.springframework.org/schema/p"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:mvc="http://www.springframework.org/schema/mvc"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">  
    <!-- 自动扫描 -->  
    <context:component-scan base-package="com.zhanglf" /> 

    <!-- 引入数据源的配置文件 -->  
    <bean id="propertyConfigurer"  
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
        <property name="location" value="classpath:/META-INF/app_config/property/jdbc.properties" />  
    </bean>  

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"  
        destroy-method="close">  
        <property name="driverClassName" value="${driver}" />  
        <property name="url" value="${url}" />  
        <property name="username" value="${username}" />  
        <property name="password" value="${password}" />  
        <!-- 初始化连接大小 -->  
        <property name="initialSize" value="${initialSize}"></property>  
        <!-- 连接池最大数量 -->  
        <property name="maxActive" value="${maxActive}"></property>  
        <!-- 连接池最大空闲 -->  
        <property name="maxIdle" value="${maxIdle}"></property>  
        <!-- 连接池最小空闲 -->  
        <property name="minIdle" value="${minIdle}"></property>  
        <!-- 获取连接最大等待时间 -->  
        <property name="maxWait" value="${maxWait}"></property>  
    </bean>  

    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->  
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <!-- 自动扫描mapping.xml文件 -->  
        <property name="mapperLocations" value="classpath:com/zhanglf/mapper/*.xml"></property>  
    </bean>  

    <!-- DAO接口所在包名,Spring会自动查找其下的类,这个很重要,缺少了就会注入Dao层失败报错 -->  
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
        <property name="basePackage" value="com.zhanglf.dao" />  
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>  
    </bean>  

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->  
    <bean id="transactionManager"  
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource" />  
    </bean>  

</beans>  

3.4 property文件夹下的资源配置文件 jdcb.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ehcachedatabase
username=root
password=
#定义初始化连接数
initialSize=0
#定义最大连接数
maxActive=20
#定义最大空闲
maxIdle=20
#定义最小空闲
minIdle=1
#定义最长等待时间
maxWait=60000

3.5 web文件夹下的springmvc配置 springmvc.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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
    <!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
    <context:component-scan base-package="com.zhanglf.controller" />
    <!-- mvc注解驱动 -->
    <mvc:annotation-driven />
    <!-- 在对所有的拦截改为不包括easyui的拦截,这样easyui才能引入成功。 -->
    <mvc:resources location="/static/js/easyui/" mapping="/static/js/easyui/**" />

    <!--避免IE执行AJAX时,返回JSON出现下载文件 -->
    <bean id="mappingJacksonHttpMessageConverter"
        class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>application/json;charset=UTF-8</value>
                <value>text/html;charset=UTF-8</value>
            </list>
        </property>
    </bean> 


    <!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->
    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON转换器 -->
            </list>
        </property>
    </bean>
    <!-- 定义跳转的文件的前后缀 ,视图模式配置 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->
        <property name="prefix" value="/view/" />
        <property name="suffix" value=".jsp" />
    </bean>

</beans>  

3 配置文件引入完毕,开始java代码部分。

我们用的是spring结合mybatis接口实现对数据库的操作。其中的bo,dao,mapper的文件用generator生成器生成。

1.数据库用的是mysql database ,先create table student,初始化几条数据:
这里写图片描述

2.用代码生成器生成bo,dao,mapper文件,copy到项目中。代码如下

–>com.zhanglf.bo包下的 StudentBo.java

package com.zhanglf.bo;

import java.io.Serializable;

public class StudentBo implements Serializable {
    

    private static final long serialVersionUID = 1L;

    private Integer id;

    private String name;

    private Integer age;

    private String address;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name == null ? null : name.trim();
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address == null ? null : address.trim();
    }
}

–>com.zhanglf.dao包下的 StudentDao.java 接口文件

package com.zhanglf.dao;

import java.util.List;

import com.zhanglf.bo.StudentBo;
/**
 * 注意:Dao层接口直接对应mapper.xml。
 * Dao层路径+接口名=mapper文件的namespace
 * @author Administrator
 *
 */
public interface StudentDao {
    

    int deleteByPrimaryKey(Integer id);

    int insert(StudentBo record);

    int insertSelective(StudentBo record);

    StudentBo selectByPrimaryKey(Integer id);

    //自己新增的方法。查询全部学生信息
    List<StudentBo> selectAllStudent();

    int updateByPrimaryKeySelective(StudentBo record);

    int updateByPrimaryKey(StudentBo record);
}

–> com.zhanglf.mapper 包下的StudentMapper.xml,导进来之后我有自己加了查询所有学生信息的sql语句,用红色标出了。对应的dao层也是增加了这样一个方法。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.zhanglf.dao.StudentDao">
    <resultMap id="BaseResultMap" type="com.zhanglf.bo.StudentBo">
        <id column="id" property="id" jdbcType="INTEGER" />
        <result column="name" property="name" jdbcType="VARCHAR" />
        <result column="age" property="age" jdbcType="INTEGER" />
        <result column="address" property="address" jdbcType="VARCHAR" />
    </resultMap>
    <sql id="Base_Column_List">
        id, name, age, address
    </sql>

    <!--在mapper文件中的头部引入缓存策略-->
    <cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>

    <!--自己新增的方法-->
    <select id="selectAllStudent" resultMap="BaseResultMap" >
        select
        *
        from student
    </select>


    <select id="selectByPrimaryKey" resultMap="BaseResultMap"
        parameterType="java.lang.Integer">
        select
        <include refid="Base_Column_List" />
        from student
        where id = #{id,jdbcType=INTEGER}
    </select>


    <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
        delete from student
        where id = #{id,jdbcType=INTEGER}
    </delete>


    <insert id="insert" parameterType="com.zhanglf.bo.StudentBo">
        insert into student (id, name, age,
        address)
        values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
        #{age,jdbcType=INTEGER},
        #{address,jdbcType=VARCHAR})
    </insert>


    <insert id="insertSelective" parameterType="com.zhanglf.bo.StudentBo">
        insert into student
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">
                id,
            </if>
            <if test="name != null">
                name,
            </if>
            <if test="age != null">
                age,
            </if>
            <if test="address != null">
                address,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="id != null">
                #{id,jdbcType=INTEGER},
            </if>
            <if test="name != null">
                #{name,jdbcType=VARCHAR},
            </if>
            <if test="age != null">
                #{age,jdbcType=INTEGER},
            </if>
            <if test="address != null">
                #{address,jdbcType=VARCHAR},
            </if>
        </trim>
    </insert>


    <update id="updateByPrimaryKeySelective" parameterType="com.zhanglf.bo.StudentBo">
        update student
        <set>
            <if test="name != null">
                name = #{name,jdbcType=VARCHAR},
            </if>
            <if test="age != null">
                age = #{age,jdbcType=INTEGER},
            </if>
            <if test="address != null">
                address = #{address,jdbcType=VARCHAR},
            </if>
        </set>
        where id = #{id,jdbcType=INTEGER}
    </update>


    <update id="updateByPrimaryKey" parameterType="com.zhanglf.bo.StudentBo">
        update student
        set name = #{name,jdbcType=VARCHAR},
        age = #{age,jdbcType=INTEGER},
        address = #{address,jdbcType=VARCHAR}
        where id = #{id,jdbcType=INTEGER}
    </update>
</mapper>

然后是com.zhanglf.cache包下的接口及其impl包下的实现类

package com.zhanglf.cache;

import java.util.List;

import com.zhanglf.bo.StudentBo;

public interface ICacheService {
    
    final String SERVICEID="ICacheService";
    public List<StudentBo> getAllStudent();

    public StudentBo getStudentById(int id);

}
package com.zhanglf.cache.impl;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.zhanglf.bo.StudentBo;
import com.zhanglf.cache.ICacheService;
import com.zhanglf.dao.StudentDao;

@Service(ICacheService.SERVICEID)
public class CacheServiceImpl implements ICacheService {
    
    @Resource
    private StudentDao studentDao;

    @Override
    //@Cacheable(name = "studentCache")
    public List<StudentBo> getAllStudent() {
         List<StudentBo> list = studentDao.selectAllStudent();
         if(list!=null&& list.size()>0){
             for (StudentBo student : list) {
                System.out.println("查询得到的学生的姓名:"+student.getName()+",学生的年龄:"+student.getAge()+"学生地址:"+student.getAddress());
            }
         }
        return list;
    }

    @Override
    public StudentBo getStudentById(int id) {
        StudentBo student = studentDao.selectByPrimaryKey(id);
        System.out.println("查询id为"+id+"的学生姓名是:"+student.getName()+",住址:"+student.getAddress());

        return student;
    }

}

然后是com.zhanglf.controller包下的StudentController.java

package com.zhanglf.controller;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.zhanglf.bo.StudentBo;
import com.zhanglf.cache.ICacheService;

@Controller
@RequestMapping("/student")
public class StudentController {

    @Resource(name = ICacheService.SERVICEID)
    private ICacheService cacheService;

    @RequestMapping("/info")
    @ResponseBody
    public List getAllStudentInfo() {
        List<StudentBo> list = new ArrayList<>();
        list = cacheService.getAllStudent();
        return list;
    }

    @RequestMapping("/byId")
    @ResponseBody
    public Integer getAllStudentInfoById(HttpServletRequest request) {
        List<StudentBo> list = new ArrayList<>();
        StudentBo bo = cacheService.getStudentById(Integer.valueOf(request
                .getParameter("id")));

        return bo.getAge();
    }

}

这样一个完整的项目就搭建完成了。下面部署到tomcat7,启动项目。在页面访问http://localhost:8080/SpringEhcacheProject/student/info,可以看到页面显示出全部学生信息。
这里写图片描述

那么我们该怎样测试缓存成功了没有呢?这里我们回头看一下chcache.xml中我们配置的缓存失效策略,如果我们访问后二十秒空置,不调用查询全部语句,则这个数据在缓存里就被清掉了。所以我们可以通过修改数据库中的数据,然后如果我们保持访问,则第一次查询操作加载到缓存中的数据会一直存在,即使20秒过了也会是一只是第一次加载进缓存的数据,而此时数据库中的数据我们已经改变了。可以证明缓存的存在的。然后我们停止查询操作20秒,这里不妨多等一会,在次执行这个链接访问数据库,可以看到查询到页面的数据已经和数据库中的一样了。这就说明之前的缓存已经被清除,证明缓存策略生效是出来效果的,也就是我们的搭建缓存框架是成功的。

总结:可以看到,整个配置的流程和redis配置类似-在spring中开启缓存,然后再对应的mapper文件中引入缓存,则可以把整个mapper文件中的查询语句的结果缓存到内存中(redis还需要引入工具类和自定义了实现一个接口)。而这里在mapper文件中引入<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>很重要,相反的是在CacheServiceImpl类中方法上的注解@Cacheable(name = "studentCache") 是多余的,不建议使用(配置不好启动会报错)。这里的缓存是框架级别的,是基于mapper文件的缓存,或者说是基于查询方法的缓存。我们在mapper中配置了就可以使用ehcache了。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhanglf02/article/details/74745726

智能推荐

gulp文件实例,自动化环境搭建实例,自动化,gulp自动化,gulp教程_全栈工程师继续努力的博客-程序员宅基地

第一步:安装Node首先,最基本也最重要的是,我们需要搭建node环境。访问 http://nodejs.org ,然后点击大大的绿色的 install 按钮,下载完成后直接运行程序,就一切准备就绪。 npm 会随着安装包一起安装,稍后会用到它。第二步:使用命令行也许现在你还不是很了解什么是命令行——OSX中的终端(Terminal),windows中的命令提示符(Command Prompt),但很快你就会知道。它看起来没那么简单,但一旦掌握了它的窍门,就可以很方便的执行很多命令行程序,比如S

无限级分销,无限级分销,五级三阶制,五级三晋制,传销,分销_php 会员分佣_kentrl的博客-程序员宅基地

需求:A推荐B,B推荐C、C推荐D、永远不断,不限制推荐层级;每个人只允许有一个上线;根据下线的人数设定规则规则, 也可实现五级三晋制;数据结构为: 典型的树结构;需解决的问题:1: 快速查询某人的所有上线;2: 快速查询某人的所有下线;3: 快速为某人增加一个下线;解决方案: 有四种一、邻接表:依赖父节点二、路径枚举三、嵌套集四、闭包表现在,仅使用 闭包表,实现解决方案-- 会员信息表-- level 字段说明:相对于第一个用户的等级。-- 譬如:用户A.

c语言中concat函数,数据结构C语言顺序串求高手修改,特别是concat函数,高手帮忙? 爱问知识人..._weixin_39772849的博客-程序员宅基地

//给你改到可以运行了,你要实现什么功能你也没说,就这样了,你自己看看自己的算法,你在用的时候注意下大小写,在C 中是严格区分大小写的,还有就是函数在进行参数传递的时候,传的是什么。怎样传好,如果对修改有不解的地方,我们可以共同解决。#include#include#include#define MAX 100#define FALSE 0#define TRUE 1#define ERROR 0...

Lustre参数调整_Lucien168的博客-程序员宅基地

1. 设置和查看lustre参数创建文件系统时,使用mkfs.lustre。当服务器停止运行时,使用use trnefs.lustre。当文件系统正在运行时,使用lctl设置或者查看参数。1.1 mkfs.lustre设置参数当文件系统第一次格式化时,参数可以通过在mkfs.lustre命令中添加--param选项进行设置。# 设置超时...

关于php下kafka消费者和生产者_php-kafka 504_乖乖康少的博客-程序员宅基地

kafka-php 相关的消费者和生产者的代码在git上有好多,我这就不写了!如果需要可以私信我!或发邮件[email protected]下面主要写的是一些注意:1、我弄好代码后,然后一直在浏览器上运行php程序,然后就是一直报错:504,说什么超时。最后找了一个大神问了一下,结果这些php程序需要在服务器下用命令来执行!

随便推点

程序流程控制,位运算符,逻辑运算符_万万没想到2022的博客-程序员宅基地

凡是可以使用三元运算符的都可以改写成if-else,反之不成立。如果两个都以使用,优先使用三元运算符练习:随意给出一个三位数的整数,打印显示它的个位数,十位数,百位数的值。格式如下:数字xxx的情况如下:个位数:十位数:百位数:例如:数字153的情况如下:个位数:3十位数:5百位数:1*/class AriExer{public static void main(Str...

概率论与数理统计——第七周周三-边缘分布律及边缘密度_边缘分布律怎么算_#zhangyu的博客-程序员宅基地

文章目录边缘分布律及边缘密度引例1.边缘分布律例1:2 . 边缘密度函数例 2 :边缘分布律及边缘密度引例1.边缘分布律以二维表的形式给出:例1:设甲、乙两人各进行两次射击,他们每次的命中率分别为0.8和0.6。甲先射击,且甲全部命中时乙的命中率下降10%,甲全部未命中时乙的命中率上升20%,甲命中1次时 乙不受影响。令X,Y分别表示甲、乙的命中次数, 分别求(X,Y )...

海量空间数据库实施策略---矢量数据2_海量矢量数据发布方案___风__的博客-程序员宅基地

空间数据库设计,这部分主要介绍以下三方面的内容: 1. 设计流程 2. 数据建模 3. 数据组织 一般项目的设计流程为下图所示的流程 第一个步骤为gather也就是收集信息,也就是手机各种技术方面的信息,包括系统需求,客户期望等等,收集完信息后进入Design阶段,即设计阶段,在该阶段需要按照在第一阶段中所收集的信息进行设计,包括物理模型和逻辑模型的设计,在对两个模型设计完后进入第三个阶段build阶段,即建立模型,并在建立好的模型基础上进行相关的测试,针对测试好的结果进行评估,根据评估结果

第二章 离散时间信号和系统的时域描述分析 2.1 离散时间信号的序列描述_离散信号x(n)=8(n)是什么意思_程序员小勇的博客-程序员宅基地

◆离散时间信号可视为连续时间信号的采样◆ 若模拟信号为,对它进行以周期为T的等间隔采样,则得到的离散时间信号为 其中x(n)称为离散时间信号(数值序列), 取整数 ◆需要强调的是: n只能取整数值◆离散时间信号x(n)有三种表示方法: 用集合符合表示 用公式表示 用图形表示◆下面是一个用集合符合表示离散时间信号的例子 ...

谷歌浏览器如何截长图_fakerth的博客-程序员宅基地

前言:作为一名大学生,肯定每天有各种各样的作业要交,有一些在浏览器上做的测验要交截图,页面太长的话,截图分好几段又不美观,所以分享一个谷歌浏览器长截图的方法。1.打开开发者工具打开开发者工具后界面如下:2.按组合键Ctrl+Shift+P,打开Chrome浏览器的console功能菜单的指令搜索栏3.输入Capture full size screenshot命令,按回车。打开...

static(静态)变量有什么作用?_静态static有啥用_丫就是熊个猫猫的博客-程序员宅基地

在C语言中,关键字static的意思是静态,它有3个明显的作用:1)在函数体内,静态变量具有“记忆”功能,即一个被声明为静态的变量在这一函数被调用的过程中其值维持不变。2)在模块内(但在函数体外),它的作用域范围是有限制的,即如果一个变量被声明为静态的,那么该变量可以被模块内所有的函数访问,但不能被模块外其他函数访问。它是一个本地的全局变量,如果一个函数被声明为静态的,那么该函数与普通函数作用域不同,其作用域仅在本文件中,它只可能被这一模块内的其他函数调用,不能被模块外的其他函数调用,也就是说这个函数被