redis之spring应用

前言

  读本文之前,需要大家对redis有所了解,大家可以去看一下我之前分享的redis安装及简单使用这一随笔,而本文我将跟大家分享学习一下redis与spring的集成。当然,首先需要打开我们的redis服务,之后才可以继续进行我们的集成。

  项目主要是将从mysql数据库查询出来的数据缓存到redis数据库中,第二次查询就直接查询redis缓存,然后增删改操作将删除数据的缓存,下一次查询操作继续缓存,避免连接mysql进行查询,从而提高性能。redis的查询速度跟Mysql查询速度可以这么比较  内存读写速度 / 磁盘读写速度

一、项目结构

二、Maven构建项目

  用maven来构建项目环境,下载所依赖的JAR包

<?xml version="1.0" encoding="UTF-8"?>

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.stonegeek</groupId>
  <artifactId>RedisSpringDemo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>RedisSpringDemo Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.version>4.2.0.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</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-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.3</version>
    </dependency>
    <dependency>
      <groupId>org.codehaus.jackson</groupId>
      <artifactId>jackson-mapper-asl</artifactId>
      <version>1.9.13</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.6.1</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.6.1</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.6.1</version>
    </dependency>
    <!-- spring mvc related.....end -->

    <!-- mybatis orm related.....start -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.2.3</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.36</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.3.0</version>
    </dependency>
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.12</version>
    </dependency>
    <!-- mybatis orm related.....end -->

    <!-- project log related.....start -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
    <!-- project log related.....end -->

    <!-- redis cache related.....start -->
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-redis</artifactId>
      <version>1.6.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.7.3</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>RedisSpringDemo</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

三、配置信息properties文件

1、jdbc.properties

jdbc.host=127.0.0.1
jdbc.database=bjsxt
jdbc.port=3306
jdbc.username=root
jdbc.password=xiaokai960201

2、redis.properties

# Redis settings
redis.host=192.168.43.230
redis.port=6379  
#redis.pass=password
redis.dbIndex=0  
redis.expiration=3000  
redis.maxIdle=300  
redis.maxActive=600  
redis.maxWait=1000  
redis.testOnBorrow=true

3、log4j.properties

#设置日志的级别,定义日志信息的输出目的
log4j.rootLogger=DEBUG, A1 ,R
#定义A1的输出目的地为控制台
log4j.appender.A1=org.apache.log4j.ConsoleAppender
#布局为 PatternLayout 可以灵活地指定布局模式。
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
#设置输出格式
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss} [%c]-[%p] %m%n
#定义R的输出目的地为文件,并且文件大小到达指定尺寸的时候产生一个新的文件
log4j.appender.R=org.apache.log4j.RollingFileAppender
#设置输出的文件地址
log4j.appender.R.File=D:\\Test_Log4j.log
#设置文件大小伟100 kb 文件到达100时,产生一个新文件,
#MaxBackupIndex 最大记录的文件数为1 查过一个文件删除文件较早的。
log4j.appender.R.MaxFileSize=100KB log4j.appender.R.MaxBackupIndex=1
#以下和上面一样
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n 

四、配置文件

1、applicationContext.xml

<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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.0.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    <!-- 使用注解的自扫描功能-->
    <context:component-scan base-package="com.stonegeek.serviceImpl" />
    <context:component-scan base-package="com.stonegeek.utils" />
  
   <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:jdbc.properties</value> <value>classpath:redis.properties</value> </list> </property> </bean> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource " destroy-method="close"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://${jdbc.host}:${jdbc.port}/${jdbc.database}?useUnicode=true&amp;characterEncoding=utf8" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- mybatis的配置映射文件--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:Mapper/*.xml" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.stonegeek.dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean> <!-- redis config start --> <!-- 配置JedisPoolConfig实例 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="maxTotal" value="${redis.maxActive}" /> <property name="maxWaitMillis" value="${redis.maxWait}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> </bean> <!-- 配置JedisConnectionFactory --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="${redis.host}" /> <property name="port" value="${redis.port}" /> <!-- <property name="password" value="${redis.pass}" /> --> <property name="database" value="${redis.dbIndex}" /> <property name="poolConfig" ref="poolConfig" /> </bean> <!-- 配置RedisTemplate --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory" /> </bean> <!-- 配置RedisCacheManager --> <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"> <constructor-arg name="redisOperations" ref="redisTemplate" /> <property name="defaultExpiration" value="${redis.expiration}" /> </bean> <!-- 配置RedisCacheConfig --> <bean id="redisCacheConfig" class="com.stonegeek.utils.RedisCacheConfig"> <constructor-arg ref="jedisConnectionFactory" /> <constructor-arg ref="redisTemplate" /> <constructor-arg ref="redisCacheManager" /> </bean> <!-- redis config end --> </beans>

2、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">

    <!-- 添加注解驱动  使用注解标注的类生效-->
    <mvc:annotation-driven />
    <!-- 设置能访问静态资源 -->
    <mvc:default-servlet-handler/>
    <!--扫描controller-->
    <context:component-scan base-package="com.stonegeek.controller" />

    <!-- jsp page related... start -->
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
                  value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <bean id="mappingJacksonHttpMessageConverter"
          class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>application/json;charset=UTF-8</value>
            </list>
        </property>
    </bean>

    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="mappingJacksonHttpMessageConverter" />
            </list>
        </property>
    </bean>

</beans>

3、web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Archetype Created Web Application</display-name>

<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>

<!-- 加载spring bean -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- 编码过滤器 -->
<filter>
<filter-name>springfilter</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>
</filter>

<filter-mapping>
<filter-name>springfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

</web-app>

五、项目主要代码

1、dao层

package com.stonegeek.dao;

import com.stonegeek.pojo.User;

import java.util.List;

public interface UserMapper {
    List<User> selectAll();
    User selectByPrimaryKey(String unumber);
    int insert(User record);

    int insertSelective(User record);
    int deleteOne(String unumber);
}
<?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.stonegeek.dao.UserMapper" >
  <resultMap id="BaseResultMap" type="com.stonegeek.pojo.User" >
    <result column="unumber" property="unumber" jdbcType="VARCHAR" />
    <result column="uname" property="uname" jdbcType="VARCHAR" />
    <result column="pwd" property="pwd" jdbcType="VARCHAR" />
    <result column="sex" property="sex" jdbcType="VARCHAR" />
    <result column="fav" property="fav" jdbcType="VARCHAR" />
  </resultMap>
  <select id="selectAll" resultMap="BaseResultMap">
    select
    *
    from user
  </select>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" >
    select
    *
    from user
    where unumber = #{unumber,jdbcType=VARCHAR}
  </select>
  <insert id="insert" parameterType="com.stonegeek.pojo.User" >
    insert into user (unumber, uname, pwd, 
      sex, fav)
    values (#{unumber,jdbcType=VARCHAR}, #{uname,jdbcType=VARCHAR}, #{pwd,jdbcType=VARCHAR}, 
      #{sex,jdbcType=VARCHAR}, #{fav,jdbcType=VARCHAR})
  </insert>
  <insert id="insertSelective" parameterType="com.stonegeek.pojo.User" >
    insert into user
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="unumber != null" >
        unumber,
      </if>
      <if test="uname != null" >
        uname,
      </if>
      <if test="pwd != null" >
        pwd,
      </if>
      <if test="sex != null" >
        sex,
      </if>
      <if test="fav != null" >
        fav,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="unumber != null" >
        #{unumber,jdbcType=VARCHAR},
      </if>
      <if test="uname != null" >
        #{uname,jdbcType=VARCHAR},
      </if>
      <if test="pwd != null" >
        #{pwd,jdbcType=VARCHAR},
      </if>
      <if test="sex != null" >
        #{sex,jdbcType=VARCHAR},
      </if>
      <if test="fav != null" >
        #{fav,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <delete id="deleteOne" parameterType="java.lang.String">
    delete from user where unumber = #{unumber}
  </delete>
</mapper>

2、model层

package com.stonegeek.pojo;

import java.io.Serializable;

public class User implements Serializable{
    private static final long serialVersionUID = 1L;
    private String unumber;

    private String uname;

    private String pwd;

    private String sex;

    private String fav;

    public String getUnumber() {
        return unumber;
    }

    public void setUnumber(String unumber) {
        this.unumber = unumber == null ? null : unumber.trim();
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname == null ? null : uname.trim();
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd == null ? null : pwd.trim();
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex == null ? null : sex.trim();
    }

    public String getFav() {
        return fav;
    }

    public void setFav(String fav) {
        this.fav = fav == null ? null : fav.trim();
    }
}

注意:

要想使用redis存对象,一定要让实体类实现Serializable接口,否则会报错。

3、controller层

package com.stonegeek.controller;

import com.stonegeek.pojo.User;
import com.stonegeek.service.IUserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by StoneGeek on 2018/5/2.
 */
@Controller
@RequestMapping("/redisTest")
public class UserController {
    @Resource
    private IUserService userService;
    @RequestMapping(value = "/selectall", method = RequestMethod.GET)
    @ResponseBody
    public Object showUsers() {
        List<User> userList = new ArrayList<User>();
        userList = userService.selectAll();
        System.out.println("--------------------------");
        System.out.println(userList);
        System.out.println("--------------------------");
        return userList;
    }
    @RequestMapping(value = "/delUser/{unumber}", method = RequestMethod.GET)
    @ResponseBody
    public Object delUser(@PathVariable String unumber) {
        System.out.println(unumber);
        userService.deleteOne(unumber);
        return "ok";
    }
}

4、service层

package com.stonegeek.service;

import com.stonegeek.dao.UserMapper;
import com.stonegeek.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by StoneGeek on 2018/5/2.
 */

public interface IUserService {
    public User getUserById(String  unumber);
    public List<User> selectAll();
    public int deleteOne(String unumber);

}
package com.stonegeek.serviceImpl;

import com.stonegeek.dao.UserMapper;
import com.stonegeek.pojo.User;
import com.stonegeek.service.IUserService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by Xiaokai on 2018/5/2.
 */
@Service("userService")
@Transactional(propagation= Propagation.REQUIRED, rollbackFor=Exception.class)
public class UserServiceImpl implements IUserService{
    @Resource
    private UserMapper iUserDao;
   @Cacheable(
"getUserById") @Override public User getUserById(String unumber) { return this.iUserDao.selectByPrimaryKey(unumber); } @Cacheable("selectAll") @Override public List<User> selectAll() { return iUserDao.selectAll(); } @CacheEvict(value= {"selectAll","getUserById"},allEntries=true) @Override public int deleteOne(String unumber) { return iUserDao.deleteOne(unumber); } }
 @Cacheable("a")注解的意义就是把该方法的查询结果放到redis中去,下一次再发起查询就去redis中去取,存在redis中的数据的key就是a;
 @CacheEvict(value={"a","b"},allEntries=true) 的意思就是执行该方法后要清除redis中key名称为a,b的数据;

5、utils工具类

package com.stonegeek.utils;

/**
 * Created by StoneGeek on 2018/5/2.
 * 通过spring管理redis缓存配置
 */
import java.lang.reflect.Method;

import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
    private volatile JedisConnectionFactory jedisConnectionFactory;
    private volatile RedisTemplate<String, String> redisTemplate;
    private volatile RedisCacheManager redisCacheManager;

    public RedisCacheConfig() {
        super();
    }

    /**
     * 带参数的构造方法 初始化所有的成员变量
     *
     * @param jedisConnectionFactory
     * @param redisTemplate
     * @param redisCacheManager
     */
    public RedisCacheConfig(JedisConnectionFactory jedisConnectionFactory, RedisTemplate<String, String> redisTemplate,
                            RedisCacheManager redisCacheManager) {
        this.jedisConnectionFactory = jedisConnectionFactory;
        this.redisTemplate = redisTemplate;
        this.redisCacheManager = redisCacheManager;
    }

    public JedisConnectionFactory getJedisConnecionFactory() {
        return jedisConnectionFactory;
    }

    public RedisTemplate<String, String> getRedisTemplate() {
        return redisTemplate;
    }

    public RedisCacheManager getRedisCacheManager() {
        return redisCacheManager;
    }

    @Bean
    public KeyGenerator customKeyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... objects) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : objects) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }
}

六、项目结果展示及说明

访问http://localhost:8080/redisTest/selectall

控制台输出(部分):

2018-05-03 11:08:23 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] DispatcherServlet with name 'SpringMVC' processing GET request for [/redisTest/selectall]
2018-05-03 11:08:23 [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Looking up handler method for path /redisTest/selectall

2018-05-03 11:08:23 [org.springframework.cache.annotation.AnnotationCacheOperationSource]-[DEBUG] Adding cacheable method 'selectAll' with attribute: [CacheableOperation[public java.util.List com.stonegeek.serviceImpl.UserServiceImpl.selectAll()] caches=[selectAll] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='']

2018-05-03 11:08:23 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Opening RedisConnection
2018-05-03 11:08:23 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Closing Redis Connection
2018-05-03 11:08:23 [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Creating a new SqlSession

2018-05-03 11:08:25 [com.stonegeek.dao.UserMapper.selectAll]-[DEBUG] ==> Preparing: select * from user 
2018-05-03 11:08:26 [com.stonegeek.dao.UserMapper.selectAll]-[DEBUG] ==> Parameters: 
2018-05-03 11:08:26 [com.stonegeek.dao.UserMapper.selectAll]-[DEBUG] <== Total: 2
2018-05-03 11:08:26 [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2ca4c9ac]
2018-05-03 11:08:26 [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Returning JDBC Connection to DataSource
2018-05-03 11:08:26 [com.mchange.v2.resourcepool.BasicResourcePool]-[DEBUG] trace com.mchange.v2.resourcepool.BasicResourcePool@5259cb3b [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@7f53b569)
2018-05-03 11:08:26 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Opening RedisConnection
2018-05-03 11:08:26 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Closing Redis Connection
--------------------------
[com.stonegeek.pojo.User@104d8d17, com.stonegeek.pojo.User@52389362]
--------------------------

2018-05-03 11:08:26 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Successfully completed request

此结果是第一次进行查询时log4j打印在console上的日志信息(挑选的部分重要信息),从这日志信息大概可以看出先连接到myql跟redis、然后将mysql查出的selectAll数据缓存到redis上并打印到控制台上

再次访问http://localhost:8080/redisTest/selectall

2018-05-03 11:16:11 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] DispatcherServlet with name 'SpringMVC' processing GET request for [/redisTest/selectall]
2018-05-03 11:16:11 [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Looking up handler method for path /redisTest/selectall
2018-05-03 11:16:11 [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Returning handler method [public java.lang.Object com.stonegeek.controller.UserController.showUsers()]
2018-05-03 11:16:11 [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'userController'
2018-05-03 11:16:11 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Last-Modified value for [/redisTest/selectall] is: -1
2018-05-03 11:16:11 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Opening RedisConnection
2018-05-03 11:16:11 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Closing Redis Connection
--------------------------
[com.stonegeek.pojo.User@5aee0851, com.stonegeek.pojo.User@68bdcc8a]
--------------------------
2018-05-03 11:16:11 [org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor]-[DEBUG] Written [[com.stonegeek.pojo.User@5aee0851, com.stonegeek.pojo.User@68bdcc8a]] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@27f9bd05]
2018-05-03 11:16:11 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Null ModelAndView returned to DispatcherServlet with name 'SpringMVC': assuming HandlerAdapter completed request handling
2018-05-03 11:16:11 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Successfully completed request

可以看出,此次操作并没有与mysql交互,直接从打开redis连接查询缓存所得

之后在进行一次删除操作

访问http://localhost:8080/redisTest/delUser/20180103

2018-05-03 11:18:14 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] DispatcherServlet with name 'SpringMVC' processing GET request for [/redisTest/delUser/20180103]
2018-05-03 11:18:14 [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Looking up handler method for path /redisTest/delUser/20180103
2018-05-03 11:18:14 [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Returning handler method [public java.lang.Object com.stonegeek.controller.UserController.delUser(java.lang.String)]
2018-05-03 11:18:14 [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'userController'
2018-05-03 11:18:14 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Last-Modified value for [/redisTest/delUser/20180103] is: -1
20180103
2018-05-03 11:18:14 [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Creating a new SqlSession
2018-05-03 11:18:14 [org.mybatis.spring.SqlSessionUtils]-[DEBUG] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2566bd74] was not registered for synchronization because synchronization is not active
2018-05-03 11:18:14 [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Fetching JDBC Connection from DataSource
2018-05-03 11:18:14 [com.mchange.v2.resourcepool.BasicResourcePool]-[DEBUG] trace com.mchange.v2.resourcepool.BasicResourcePool@5259cb3b [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@7f53b569)
2018-05-03 11:18:14 [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@3d69c864] will not be managed by Spring
2018-05-03 11:18:14 [com.stonegeek.dao.UserMapper.deleteOne]-[DEBUG] ==>  Preparing: delete from user where unumber = ? 
2018-05-03 11:18:14 [com.stonegeek.dao.UserMapper.deleteOne]-[DEBUG] ==> Parameters: 20180103(String)
2018-05-03 11:18:15 [com.stonegeek.dao.UserMapper.deleteOne]-[DEBUG] <==    Updates: 1
2018-05-03 11:18:15 [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2566bd74]
2018-05-03 11:18:15 [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Returning JDBC Connection to DataSource
2018-05-03 11:18:15 [com.mchange.v2.resourcepool.BasicResourcePool]-[DEBUG] trace com.mchange.v2.resourcepool.BasicResourcePool@5259cb3b [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@7f53b569)
2018-05-03 11:18:15 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Opening RedisConnection
2018-05-03 11:18:15 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Closing Redis Connection
2018-05-03 11:18:15 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Opening RedisConnection
2018-05-03 11:18:15 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Closing Redis Connection
2018-05-03 11:18:15 [org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor]-[DEBUG] Written [ok] as "text/html" using [org.springframework.http.converter.StringHttpMessageConverter@7065def5]
2018-05-03 11:18:15 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Null ModelAndView returned to DispatcherServlet with name 'SpringMVC': assuming HandlerAdapter completed request handling
2018-05-03 11:18:15 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Successfully completed request

然后再次查询所有用户信息

访问http://localhost:8080/redisTest/selectall

可以发现删除操作确实删除了缓存,本次查询查询数据库并重新缓存数据到redis内存

2018-05-03 11:19:58 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] DispatcherServlet with name 'SpringMVC' processing GET request for [/redisTest/selectall]
2018-05-03 11:19:58 [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Looking up handler method for path /redisTest/selectall
2018-05-03 11:19:58 [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Returning handler method [public java.lang.Object com.stonegeek.controller.UserController.showUsers()]
2018-05-03 11:19:58 [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'userController'
2018-05-03 11:19:58 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Last-Modified value for [/redisTest/selectall] is: -1
2018-05-03 11:19:58 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Opening RedisConnection
2018-05-03 11:19:58 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Closing Redis Connection
2018-05-03 11:19:58 [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Creating a new SqlSession
2018-05-03 11:19:58 [org.mybatis.spring.SqlSessionUtils]-[DEBUG] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@22fb1e63] was not registered for synchronization because synchronization is not active
2018-05-03 11:19:58 [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Fetching JDBC Connection from DataSource
2018-05-03 11:19:58 [com.mchange.v2.resourcepool.BasicResourcePool]-[DEBUG] trace com.mchange.v2.resourcepool.BasicResourcePool@5259cb3b [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@7f53b569)
2018-05-03 11:19:58 [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@2a67a803] will not be managed by Spring
2018-05-03 11:19:58 [com.stonegeek.dao.UserMapper.selectAll]-[DEBUG] ==>  Preparing: select * from user 
2018-05-03 11:19:58 [com.stonegeek.dao.UserMapper.selectAll]-[DEBUG] ==> Parameters: 
2018-05-03 11:19:58 [com.stonegeek.dao.UserMapper.selectAll]-[DEBUG] <==      Total: 1
2018-05-03 11:19:58 [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@22fb1e63]
2018-05-03 11:19:58 [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Returning JDBC Connection to DataSource
2018-05-03 11:19:58 [com.mchange.v2.resourcepool.BasicResourcePool]-[DEBUG] trace com.mchange.v2.resourcepool.BasicResourcePool@5259cb3b [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@7f53b569)
2018-05-03 11:19:58 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Opening RedisConnection
2018-05-03 11:19:58 [org.springframework.data.redis.core.RedisConnectionUtils]-[DEBUG] Closing Redis Connection
--------------------------
[com.stonegeek.pojo.User@5eecc6cd]
--------------------------
2018-05-03 11:19:58 [org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor]-[DEBUG] Written [[com.stonegeek.pojo.User@5eecc6cd]] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@27f9bd05]
2018-05-03 11:19:58 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Null ModelAndView returned to DispatcherServlet with name 'SpringMVC': assuming HandlerAdapter completed request handling
2018-05-03 11:19:58 [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Successfully completed request

七、总结

  首先我们先进行了第一次查询,然后将从mysql查询出来的结果缓存到redis内存中,第二次查询直接从redis内存中取出数据,之后我们又做了一次删除操作,此时会把redis上的缓存清空,之后又进行了一次查询操作,可以看到,确实是删除操作将redis缓存清空,然后又重新将mysql数据缓存到了redis内存上。

  这样redis的好处显露无疑:每次加载所有用户信息时,如果都要请求数据库,数据库编译并执行你的查询语句,这样效率就会低下很多,针对这种信息不经常变动并且数据量较大的情况,通常做法,就是把他加入redis缓存,每次取数据先去判断,如果缓存不为空,那么就从缓存取值,如果为空,再去请求数据库,并将数据加入缓存,这样大大提高系统访问效率。

猜你喜欢

转载自www.cnblogs.com/sxkgeek/p/8984576.html