本文模拟两种场景,一是使用Dao从数据库读取数据并缓存,一是使用RedisTemplate操作缓存。
1、Redis配置
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
application.properties
# REDIS (RedisProperties)
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=123456
# 连接超时时间(毫秒),不能使用0,否则报错:超时
spring.redis.timeout=100
RedisConfig.java
package com.test.demo.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.*;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport{
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Bean
public RedisTemplate<String, String> redisTemplate(
RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
setSerializer(template);// 设置序列化工具
template.afterPropertiesSet();
return template;
}
private void setSerializer(StringRedisTemplate template) {
@SuppressWarnings({ "rawtypes", "unchecked" })
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(
Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
}
}
DemoApplication.java
增加dao包扫描,开启缓存
@SpringBootApplication
// 在启动类中添加对mapper包扫描@MapperScan
@MapperScan({"com.test.demo.mybatis.dao","com.test.demo.redis"})
//开启缓存功能[redis]
@EnableCaching
public class DemoApplication
2、业务模拟一
Redis实体
package com.test.demo.redis;
import java.io.Serializable;
public class UserBean implements Serializable {
private static final long serialVersionUID = 56613L;
private Long id;
private String username;
private String name;
private String password;
private String salt;
private String state;
get,set....
}
RedisUserDao.java
package com.test.demo.redis;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
@Component
@CacheConfig(cacheNames = "users")
public interface RedisUserDao {
@Select("select * from USER_INFO where id =#{id}")
@Cacheable(key = "'userid:'+#p0")
// SpEL表达式:在SpEL表达式中,默认情况下,表达式前缀为 ' # ' ,而后缀为 ' } '
// 如果表达式中没有前缀和后缀,那么表达式字符串就被当作纯文本
UserBean findByCacheKey(@Param("id") String id);
}
Controller类
在HelloController类中,新增如下内容:
@Resource
RedisUserDao redisService;
@RequestMapping("/getRedisUser")
public UserBean getRedisUser(String key) {
System.out.println("-- key - Username --"+key);
return this.redisService.findByCacheKey(key);
}
运行
浏览器中访问http://cos6743:8081/getRedisUser?key=802
返回结果:{“id”:802,“username”:“yangtom”,“name”:“tom”,“password”:“25f9e79388b62b”,“salt”:null,“state”:null}
3、业务模拟二
UserRedisMapper.java
package com.test.demo.redis;
import javax.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@Component
public class UserRedisMapper {
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
Controller类
在HelloController类中,新增如下内容:
@Resource
UserRedisMapper redisMapper;
@RequestMapping("/getRedisUserinfo")
public UserBean getRedisUserInfo(String key) {
//为了key的区分,增加 user 开头
return (UserBean)this.redisMapper.get("user:"+key);
}
@RequestMapping("/addRedisUserinfo")
public boolean setRedisUserInfo(String key) {
UserBean user = new UserBean();
user.setId(100L);
user.setName(key);
user.setUsername("Tom");
user.setPassword("miwen");
return this.redisMapper.set("user:"+key, user);
}
运行
1、增加用户:浏览器中访问http://cos6743:8081/addRedisUserinfo?key=yang
返回结果:true
2、查看用户:浏览器中访问http://cos6743:8081/getRedisUserinfo?key=yang
返回结果:{“id”:100,“username”:“Tom”,“name”:“yang”,“password”:“miwen”,“salt”:null,“state”:null}
4、Redis客户端查看keys
5、SpringBootTest
注意区分 RedisTemplate 和 StringRedisTemplate
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestRedis {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RedisTemplate redisTemplate;
@Test
public void test() throws Exception {
redisTemplate.opsForValue().set("aaa", "111");
Assert.assertEquals("111", redisTemplate.opsForValue().get("aaa"));
}
@Test
public void testObj() throws Exception {
boolean exists=redisTemplate.hasKey("testkey");
if(exists){
System.out.println("the value: "+redisTemplate.opsForValue().get("aaa"));
System.out.println("the spring value: "+stringRedisTemplate.opsForValue().get("testkey"));
}else{
System.out.println("exists is false");
}
}
}