• 10. 搭配redis做文章缓存


    redis是一个使用较多的内存键值数据库,这儿的键是字符串类型的标识符,而值可以是字符串、散列、列表、集合和有序集合,也正是因为redis提供了较丰富的值的类型,能够满足不同的使用要求,而且redis的读写是很高效的,所以现在很多系统都将redis作为缓存系统,在使用的时候先从数据库中把数据读取出来,然后写入redis,再次使用该数据时就可以直接从redis中获取,当然如果修改数据的话就要把redis中的对应数据清除。本文主要是介绍springboot+mybatis搭配redis来作为文章的缓存,做法如下:

    1. 添加依赖:

    1 <dependency>
    2     <groupId>org.springframework.boot</groupId>
    3     <artifactId>spring-boot-starter-data-redis</artifactId>
    4 </dependency>
    pom.xml

    因为要观察读取数据时是从哪读取到的数据,所以也要配置log4j,并使mybatis能够把sql输出到控制台上,所以也要添加log4j的依赖:

    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-web</artifactId>  
        <exclusions>  
            <exclusion>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-starter-logging</artifactId>  
            </exclusion>  
        </exclusions> 
    </dependency> 
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j</artifactId>
        <version>1.3.8.RELEASE</version>
    </dependency>
    pom.xml

    2. 在src/main/resources目录下增加log4j.properties文件,并添加以下配置

     1 #logger level  
     2 log4j.rootCategory=DEBUG,stdout,DebugAppender,InfoAppender,ErrorAppender  
     3 log4j.debug=true  
     4 log4j.appender.stdout=org.apache.log4j.ConsoleAppender    
     5 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout       
     6 log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
     7 #logger input file  
     8 log4j.logger.DebugAppender.access=DEBUG  
     9 log4j.appender.DebugAppender=org.apache.log4j.DailyRollingFileAppender       
    10 log4j.appender.DebugAppender.File=../logs/debug  
    11 log4j.appender.DebugAppender.File.datePattern='.'yyyy-MM-dd
    12 log4j.appender.DebugAppender.layout=org.apache.log4j.PatternLayout       
    13 log4j.appender.DebugAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
    14   
    15 #logger input file  
    16 log4j.logger.InfoAppender.access=INFO  
    17 log4j.appender.InfoAppender=org.apache.log4j.DailyRollingFileAppender       
    18 log4j.appender.InfoAppender.File=../logs/info  
    19 log4j.appender.InfoAppender.File.datePattern='.'yyyy-MM-dd
    20 log4j.appender.InfoAppender.layout=org.apache.log4j.PatternLayout       
    21 log4j.appender.InfoAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n   
    22   
    23 #error log input file  
    24 log4j.logger.ErrorAppender.access=ERROR  
    25 log4j.appender.ErrorAppender=org.apache.log4j.DailyRollingFileAppender  
    26 log4j.appender.ErrorAppender.File=../logs/error 
    27 log4j.appender.ErrorAppender.File.datePattern='.'yyyy-MM-dd
    28 log4j.appender.ErrorAppender.Append = true  
    29 log4j.appender.ErrorAppender.threshold = ERROR  
    30 log4j.appender.ErrorAppender.layout=org.apache.log4j.PatternLayout   
    31 log4j.appender.ErrorAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
    log4j.properties

    同时在application.properties文件中增加:logging.level.*=DEBUG
    3. 在application.properties中添加redis配置

    spring.redis.database=0
    spring.redis.host=192.168.1.103
    spring.redis.port=6379
    spring.redis.password=
    spring.redis.pool.max-active=8
    spring.redis.pool.max-wait=-1
    spring.redis.pool.max-idle=8
    spring.redis.pool.min-idle=0
    spring.redis.timeout=0
    application.properties

    4. 添加RedisConfig,以开启redis配置:

     1 package com.lvniao.blog.config;
     2 
     3 import org.springframework.cache.interceptor.KeyGenerator;
     4 import org.springframework.beans.factory.annotation.Value;
     5 import org.springframework.cache.CacheManager;
     6 import org.springframework.cache.annotation.CachingConfigurerSupport;
     7 import org.springframework.cache.annotation.EnableCaching;
     8 import org.springframework.context.annotation.Bean;
     9 import org.springframework.context.annotation.Configuration;
    10 import org.springframework.data.redis.cache.RedisCacheManager;
    11 import org.springframework.data.redis.connection.RedisConnectionFactory;
    12 import org.springframework.data.redis.core.RedisTemplate;
    13 import org.springframework.data.redis.core.StringRedisTemplate;
    14 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    15 import org.springframework.data.redis.serializer.StringRedisSerializer;
    16 
    17 import java.lang.reflect.Method;
    18 import com.fasterxml.jackson.annotation.JsonAutoDetect;
    19 import com.fasterxml.jackson.annotation.PropertyAccessor;
    20 import com.fasterxml.jackson.databind.ObjectMapper;
    21 
    22 @Configuration
    23 @EnableCaching
    24 public class RedisConfig  extends CachingConfigurerSupport {
    25 
    26     @Value("${spring.redis.host}")
    27     private String host;
    28     @Value("${spring.redis.port}")
    29     private int port;
    30     @Value("${spring.redis.timeout}")
    31     private int timeout;
    32     
    33     @Bean
    34     public KeyGenerator keyGenerator() {
    35         return new KeyGenerator() {
    36             @Override
    37             public Object generate(Object target, Method method, Object... params) {
    38                 StringBuilder sb = new StringBuilder();
    39                 sb.append(target.getClass().getName());
    40                 sb.append(":" + method.getName());
    41                 for (Object obj : params) {
    42                     sb.append(":" + obj.toString());
    43                 }
    44                 return sb.toString();
    45             }
    46         };
    47     }
    48     
    49     @Bean 
    50     public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
    51         RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
    52         cacheManager.setDefaultExpiration(10000);
    53         return cacheManager;
    54     }
    55     
    56     @Bean
    57     public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
    58         RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
    59         redisTemplate.setConnectionFactory(factory);
    60         redisTemplate.afterPropertiesSet();
    61         setSerializer(redisTemplate);
    62         return redisTemplate;
    63     }
    64 
    65     private void setSerializer(RedisTemplate<String, String> template) {
    66         Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    67         ObjectMapper om = new ObjectMapper();
    68         om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    69         om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    70         jackson2JsonRedisSerializer.setObjectMapper(om);
    71         template.setKeySerializer(new StringRedisSerializer());
    72         template.setValueSerializer(jackson2JsonRedisSerializer);
    73     }
    74 }
    RedisConfig

    5. 这儿只是使用redis来缓存文章数据,所以在ArticleMapper的getArticleById方法上添加缓存配置,代码如下:

     1 @Cacheable(key ="#p0") 
     2 @Select("select id, name, content, summary, createtime createTime, modifytime modifyTime, publiz, first, author, category from articles where id=#{id}")
     3 @Results({
     4     @Result(id=true, column="id", property="id"),
     5     @Result(column="name", property="name"),
     6     @Result(column="content", property="content"),
     7     @Result(column="summary", property="summary"),
     8     @Result(column="createTime", property="createTime"),
     9     @Result(column="modifyTime", property="modifyTime"),
    10     @Result(column="publiz", property="publiz"),
    11     @Result(column="first", property="first"),
    12     @Result(column="author", property="author", 
    13         one=@One(select="com.lvniao.blog.mapper.UserMapper.getUserById", fetchType=FetchType.EAGER)),
    14     @Result(column="category", property="category", 
    15         one=@One(select="com.lvniao.blog.mapper.CategoryMapper.getCategoryById", fetchType=FetchType.EAGER)),
    16 })
    ArticleMapper

    public Article getArticleById(@Param("id") String id);
    @Cacheable(key ="#p0") 表示先redis中查找键,如果没找到就从数据库中获取数据,然后把数据写入redis中,这样当第二次调用该方法时,就会从redis中获取数据并返回给调用。其中key ="#p0"表示将第一个参数作为键值。
    6. 分别执行两次去掉@Cacheable(key ="#p0") 和含有@Cacheable(key ="#p0") 的操作,然后在控制台中比较两次的日志,截图如下:

    从图中可以看到执行同样的调用,左边是从redis中国获取数据,而右边是从数据库中获取数据,所以经过如上步骤,就可以在项目中使用redis了。

  • 相关阅读:
    C错误调试:当前不会命中断点。没有与此行关联的可执行代码
    将不同的数据写入不同的文件中
    UMFPACK调用的接口
    求解压力备份()
    用C++实现向量二范数
    编写参考文献的方法
    改写UMFPACK算例中的压缩方式(二)
    div文字多行展示,多出的文字用省略号代替
    Internet Explorer Developer Toolbar 中文
    (转帖)天下第七C#学习笔记(3)
  • 原文地址:https://www.cnblogs.com/lvniao/p/9051443.html
Copyright © 2020-2023  润新知