您的位置:首页 > 数据库 > Redis

SpringBoot 学习记录(七): Redis

2017-04-11 11:19 429 查看
之前写过一篇spring+spring_mvc+redis的博客,这篇我们学习在spring_boot中如何使用redis

对spring_boot有过了解后可以知道,spring_boot本身集成了很多模块,根据需要引入即可,

redis的使用也是,第一步是引入相关依赖包。

一,pom.xml中添加依赖:

<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
二,在application.properties中添加redis的配置,
请确保你的本地已安装有redis,我的是装在虚拟机,

有需要的可以回顾博文:常用框架(二) : spring+springMvc+mybatis+maven+redis

#redis
spring.redis.database=0  
spring.redis.host=192.168.230.130
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

三,定义RedisConfiguration配置类

package com.example.config;

import java.lang.reflect.Method;

import org.springframework.cache.CacheManager;
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.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
@EnableCaching//启用缓存
public class RedisConfiguration extends CachingConfigurerSupport {

/**
* 自定义缓存key值
* 此方法将会根据类名+方法名+所有参数的值生成唯一的一个key
*/
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}

/**
* 缓存管理器
* @param redisTemplate
* @return
*/
@Bean
public CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
//设置缓存过期时间
rcm.setDefaultExpiration(300);//秒
return rcm;
}

/**
* RedisTemplate缓存操作类,类似于jdbcTemplate的一个类;
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
//key序列化方式
Jackson2JsonRedisSerializer<Object> redisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
redisSerializer.setObjectMapper(om);
template.setValueSerializer(redisSerializer);
template.afterPropertiesSet();
return template;
}
}

四,测试

首先请确保开启你的redis服务:



新建测试类RedisController:

这里我们使用RedisTemplate的api进行存储数据,如下:



一般是自己定义一个RedisService工具类,方便使用,本例就不说明了,有兴趣的可以查看之前的博客。

package com.example.controller;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RedisController {

private Logger logger = LoggerFactory.getLogger(this.getClass());

@Resource
private RedisTemplate<String,String> redisTemplate;

@RequestMapping("/redis/set")
public String setKeyAndValue(){
String key = "name";
String value = "wendy";
logger.info("访问set:key={},value={}",key,value);
ValueOperations<String,String> valOpsStr = redisTemplate.opsForValue();
valOpsStr.set(key, value);
return "Set Ok";
}

@RequestMapping("redis/get")
public String getKey(){
String key = "name";
logger.info("访问get:key={}",key);
ValueOperations<String,String> valOpsStr = redisTemplate.opsForValue();
return valOpsStr.get(key);
}
}
启动服务测试:http://localhost:8088/spring-boot/redis/set ===== 返回结果:Set Ok

如果测试redis连接失败,clean project 之后重启再试,如果还有问题,请确保你的redis服务是否开启,配置是否正确等

启动服务测试:http://localhost:8088/spring-boot/redis/get
====== 返回结果:wendy
==================================================================================================

上面定义RedisConfiguration配置类时,我们定义了一个自动生成key的方法,

也就是说不用定义一个唯一key,也能根据自动生成的key存取value值,下面我们来学习如何使用注解的方式

前面学习jap的时候我们定义了UserInfoRepository,在controller层也是直接使用的dao层,

这里我们加上service,使代码规范化

package com.example.service;

import com.example.entity.UserInfo;

public interface UserService {

UserInfo findById(long id);

void deleteFromCache(long id);
}
package com.example.service.impl;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.example.entity.UserInfo;
import com.example.repository.UserInfoRepository;
import com.example.service.UserService;

@Service
public class UserServiceImpl implements UserService {

private Logger logger = LoggerFactory.getLogger(this.getClass());

@Resource
private UserInfoRepository userRepository;

@Override
public UserInfo findById(long id) {
logger.info("从数据库查询数据");
return userRepository.findById(id);
}

@Override
public void deleteFromCache(long id) {
logger.info("从缓存中删除数据");
}

}
五,在RedisController中添加测试方法:
package com.example.controller;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.base.ReturnResult;
import com.example.entity.UserInfo;
import com.example.service.UserService;

@RestController
public class RedisController {

@Resource
private UserService userService;

@RequestMapping("redis/get/user")
@Cacheable(value="userInfo")//注解直接缓存查询结果
public UserInfo getUserById(long id){
UserInfo user = userService.findById(id);
return user;
}

@RequestMapping("redis/del/user")
@CacheEvict(value="userInfo",allEntries=true)//注解从缓存删除结果
public String delUserById(long id){
userService.deleteFromCache(id);
return "del from cache";
}
}

这里说明一下spring cache的注解使用:

Cacheable 支持如下几个参数:

value:缓存位置名称,不能为空,如果使用EHCache,就是ehcache.xml中声明的cache的name

key:缓存的key,默认为空则表示使用方法的参数类型及参数值作为key,可以自定义key的生成规则

condition:触发条件,只有满足条件的情况才会加入缓存,默认为空示全部都加入缓存

@CacheEvict 支持如下几个参数:

value:缓存位置名称,不能为空,同上

key:缓存的key,默认为空,同上

condition:触发条件,只有满足条件的情况才会清除缓存,默认为空

allEntries:true表示清除value中的全部缓存,默认为false

================ 注解用在service层是一样的,看个人业务需求使用

启动测试:第一次查询用户信息是从数据库查询,控制台应该会打印日志
访问测试:http://localhost:8088/spring-boot/redis/get/user?id=1

返回结果:

{
"id": 1,
"name": "initname",
"gender": "F",
"status": null
}
查看控制台:
2017-04-11 14:58:40.609 DEBUG 6308 --- [nio-8088-exec-2] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/spring-boot/redis/get/user]
2017-04-11 14:58:40.610 DEBUG 6308 --- [nio-8088-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /redis/get/user
2017-04-11 14:58:40.610 DEBUG 6308 --- [nio-8088-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public com.example.entity.UserInfo com.example.controller.RedisController.getUserById(long)]
2017-04-11 14:58:40.610 DEBUG 6308 --- [nio-8088-exec-2] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/spring-boot/redis/get/user] is: -1
2017-04-11 14:58:40.619  INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop                   : LogAop.doBefore()
2017-04-11 14:58:40.619  INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop                   : URL : http://localhost:8088/spring-boot/redis/get/user 2017-04-11 14:58:40.619  INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop                   : HTTP_METHOD : GET
2017-04-11 14:58:40.619  INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop                   : IP : 0:0:0:0:0:0:0:1
2017-04-11 14:58:40.622  INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop                   : CLASS_METHOD : com.example.controller.RedisController.getUserById
2017-04-11 14:58:40.623  INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop                   : ARGS : [1]
id: 1
2017-04-11 14:58:40.724  INFO 6308 --- [nio-8088-exec-2] c.example.service.impl.UserServiceImpl   : 从数据库查询数据
Hibernate: select userinfo0_.id as id1_0_, userinfo0_.gender as gender2_0_, userinfo0_.name as name3_0_ from user_info userinfo0_ where userinfo0_.id=?
2017-04-11 14:58:40.900  INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop                   : LogAop.doAfter()
2017-04-11 14:58:40.900  INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop                   : LogAop.doAfterReturning()
2017-04-11 14:58:40.900  INFO 6308 --- [nio-8088-exec-2] com.example.aop.LogAop                   : 耗时(毫秒) : 281
2017-04-11 14:58:40.909 DEBUG 6308 --- [nio-8088-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Written [com.example.entity.UserInfo@4f696c3f] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@403a7b03]
2017-04-11 14:58:40.910 DEBUG 6308 --- [nio-8088-exec-2] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-04-11 14:58:40.911 DEBUG 6308 --- [nio-8088-exec-2] o.s.web.servlet.DispatcherServlet        : Successfully completed request

再次访问,此时应该是从缓存获取数据,控制台不会打印出“从数据库查询数据”这条日志

且注意查看耗时时间,会比查询数据库要短

清除控制台再次访问查看:

2017-04-11 15:19:11.792 DEBUG 6260 --- [nio-8088-exec-3] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/spring-boot/redis/get/user]
2017-04-11 15:19:11.793 DEBUG 6260 --- [nio-8088-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /redis/get/user
2017-04-11 15:19:11.794 DEBUG 6260 --- [nio-8088-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public com.example.entity.UserInfo com.example.controller.RedisController.getUserById(long)]
2017-04-11 15:19:11.794 DEBUG 6260 --- [nio-8088-exec-3] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/spring-boot/redis/get/user] is: -1
2017-04-11 15:19:11.795  INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop                   : LogAop.doBefore()
2017-04-11 15:19:11.795  INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop                   : URL : http://localhost:8088/spring-boot/redis/get/user 2017-04-11 15:19:11.795  INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop                   : HTTP_METHOD : GET
2017-04-11 15:19:11.796  INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop                   : IP : 0:0:0:0:0:0:0:1
2017-04-11 15:19:11.796  INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop                   : CLASS_METHOD : com.example.controller.RedisController.getUserById
2017-04-11 15:19:11.796  INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop                   : ARGS : [1]
id: 1
2017-04-11 15:19:11.797  INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop                   : LogAop.doAfter()
2017-04-11 15:19:11.797  INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop                   : LogAop.doAfterReturning()
2017-04-11 15:19:11.797  INFO 6260 --- [nio-8088-exec-3] com.example.aop.LogAop                   : 耗时(毫秒) : 2
2017-04-11 15:19:11.803 DEBUG 6260 --- [nio-8088-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Written [com.example.entity.UserInfo@9e8e466] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@345a0792]
2017-04-11 15:19:11.803 DEBUG 6260 --- [nio-8088-exec-3] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-04-11 15:19:11.803 DEBUG 6260 --- [nio-8088-exec-3] o.s.web.servlet.DispatcherServlet        : Successfully completed request
============= 说明测试缓存成功

下面我们测试删除缓存方法:http://localhost:8088/spring-boot/redis/del/user?id=1

返回结果:del from cache

再次测试查询方法:http://localhost:8088/spring-boot/redis/get/user?id=1

可以看到这里又打印了日志:“从数据库查询数据”,删除缓存成功

2017-04-11 21:20:07.644 DEBUG 8460 --- [nio-8088-exec-9] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/spring-boot/redis/del/user]
2017-04-11 21:20:07.645 DEBUG 8460 --- [nio-8088-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /redis/del/user
2017-04-11 21:20:07.645 DEBUG 8460 --- [nio-8088-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public java.lang.String com.example.controller.RedisController.delUserById(long)]
2017-04-11 21:20:07.646 DEBUG 8460 --- [nio-8088-exec-9] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/spring-boot/redis/del/user] is: -1
2017-04-11 21:20:07.647  INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop                   : LogAop.doBefore()
2017-04-11 21:20:07.647  INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop                   : URL : http://localhost:8088/spring-boot/redis/del/user 2017-04-11 21:20:07.647  INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop                   : HTTP_METHOD : GET
2017-04-11 21:20:07.648  INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop                   : IP : 0:0:0:0:0:0:0:1
2017-04-11 21:20:07.648  INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop                   : CLASS_METHOD : com.example.controller.RedisController.delUserById
2017-04-11 21:20:07.648  INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop                   : ARGS : [1]
id: 1
2017-04-11 21:20:07.648  INFO 8460 --- [nio-8088-exec-9] c.example.service.impl.UserServiceImpl   : 从缓存中删除数据
2017-04-11 21:20:07.651  INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop                   : LogAop.doAfter()
2017-04-11 21:20:07.651  INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop                   : LogAop.doAfterReturning()
2017-04-11 21:20:07.651  INFO 8460 --- [nio-8088-exec-9] com.example.aop.LogAop                   : 耗时(毫秒) : 4
2017-04-11 21:20:07.653 DEBUG 8460 --- [nio-8088-exec-9] m.m.a.RequestResponseBodyMethodProcessor : Written [del from cache] as "text/plain;charset=UTF-8" using [org.springframework.http.converter.StringHttpMessageConverter@3badefd6]
2017-04-11 21:20:07.653 DEBUG 8460 --- [nio-8088-exec-9] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-04-11 21:20:07.654 DEBUG 8460 --- [nio-8088-exec-9] o.s.web.servlet.DispatcherServlet        : Successfully completed request
2017-04-11 21:20:10.258 DEBUG 8460 --- [io-8088-exec-10] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/spring-boot/redis/get/user]
2017-04-11 21:20:10.259 DEBUG 8460 --- [io-8088-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /redis/get/user
2017-04-11 21:20:10.259 DEBUG 8460 --- [io-8088-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public com.example.entity.UserInfo com.example.controller.RedisController.getUserById(long)]
2017-04-11 21:20:10.259 DEBUG 8460 --- [io-8088-exec-10] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/spring-boot/redis/get/user] is: -1
2017-04-11 21:20:10.263  INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop                   : LogAop.doBefore()
2017-04-11 21:20:10.263  INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop                   : URL : http://localhost:8088/spring-boot/redis/get/user 2017-04-11 21:20:10.263  INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop                   : HTTP_METHOD : GET
2017-04-11 21:20:10.263  INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop                   : IP : 0:0:0:0:0:0:0:1
2017-04-11 21:20:10.263  INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop                   : CLASS_METHOD : com.example.controller.RedisController.getUserById
2017-04-11 21:20:10.263  INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop                   : ARGS : [1]
id: 1
2017-04-11 21:20:10.265  INFO 8460 --- [io-8088-exec-10] c.example.service.impl.UserServiceImpl   : 从数据库查询数据
Hibernate: select userinfo0_.id as id1_0_, userinfo0_.gender as gender2_0_, userinfo0_.name as name3_0_ from user_info userinfo0_ where userinfo0_.id=?
2017-04-11 21:20:10.269  INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop                   : LogAop.doAfter()
2017-04-11 21:20:10.270  INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop                   : LogAop.doAfterReturning()
2017-04-11 21:20:10.270  INFO 8460 --- [io-8088-exec-10] com.example.aop.LogAop                   : 耗时(毫秒) : 7
2017-04-11 21:20:10.274 DEBUG 8460 --- [io-8088-exec-10] m.m.a.RequestResponseBodyMethodProcessor : Written [com.example.entity.UserInfo@1e076014] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@51e330c]
2017-04-11 21:20:10.274 DEBUG 8460 --- [io-8088-exec-10] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-04-11 21:20:10.275 DEBUG 8460 --- [io-8088-exec-10] o.s.web.servlet.DispatcherServlet        : Successfully completed request

============================================================================

接下来我们学习如何在redis中存储session,在做负载均衡的时候多应用共享session

一,添加依赖:

<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>

二,定义配置类SessionConfiguration

package com.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60*60*2)
public class SessionConfiguration {

}

接下来就可以部署测试了,这里不做演示

到此redis的学习就暂时告一段落,下篇我们将学习,SpringBoot 学习记录(八): properties 属性自定义
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: