本篇博客是基于上一篇博客的,上一篇完成mongodb数据库的操作,在本篇博客中,加上集成的redis缓存,并且测试redis缓存是否起作用。
1、引入依赖以及设置properties文件:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
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
2、两个配置文件:
2.1 MyRedisCacheConfig
@Configuration
@EnableCaching
public class MyRedisCacheConfig extends CachingConfigurerSupport {
//作用:用于抑制编译器产生警告信息。
@SuppressWarnings({"rawtypes","unckecked"})
@Bean
public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory factory)
{
RedisTemplate<String,String> template = new StringRedisTemplate(factory);
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);
template.afterPropertiesSet();
return template;
}
@Bean
public KeyGenerator wiselyKeyGenerator()
{
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();
}
};
}
@Bean
public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate)
{
/*
* // 设置缓存过期时间 (秒)
cacheManager.setDefaultExpiration(2 * 60);
* */
return new RedisCacheManager(redisTemplate);
}
}
2.2 RedisUtil
@Service
public class RedisUtil {
@Autowired(required=true)
private RedisTemplate<String,String> redisTemplate;
/**
* 添加对象
*/
public boolean add(final String key, final String value) {
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection)
throws DataAccessException {
connection.set(
redisTemplate.getStringSerializer().serialize(key),
redisTemplate.getStringSerializer().serialize(value));
return true;
}
});
return false;
}
/**
* 添加对象
*/
public boolean add(final String key, final Long expires, final String value) {
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection)
throws DataAccessException {
connection.setEx(
redisTemplate.getStringSerializer().serialize(key),
expires,
redisTemplate.getStringSerializer().serialize(value)
);
return true;
}
});
return false;
}
/**
* 添加Map
*/
public boolean add(final Map<String,String>map) {
Assert.notEmpty(map);
boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
public Boolean doInRedis(RedisConnection connection)
throws DataAccessException {
RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
for (Map.Entry<String, String> entry : map.entrySet()) {
byte[] key = serializer.serialize(entry.getKey());
byte[] name = serializer.serialize(entry.getValue());
connection.setNX(key, name);
}
return true;
}
}, false, true);
return result;
}
/**
* 删除对象 ,依赖key
*/
public void delete(String key) {
redisTemplate.delete(key);
}
/**
* 修改对象
*/
public boolean update(final String key,final String value) {
if (get(key) == null) {
throw new NullPointerException("数据行不存在, key = " + key);
}
boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
public Boolean doInRedis(RedisConnection connection)
throws DataAccessException {
RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
connection.set(serializer.serialize(key), serializer.serialize(value));
return true;
}
});
return result;
}
/**
* 根据key获取对象
*/
public Object get(final String keyId) {
Object result = redisTemplate.execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection)
throws DataAccessException {
RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
byte[] key = serializer.serialize(keyId);
byte[] value = connection.get(key);
if (value == null) {
return null;
}
return serializer.deserialize(value);
}
});
return result;
}
}
3、在需要缓存的地方加上 @Cacheable
@Repository//用于标注数据访问组件,即 DAO组件
public interface TodayWeatherRepository extends MongoRepository<TodayWeather,String> {
//@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@Cacheable(value = "todayWeather")
TodayWeather findByCityDate(String cityDate);
void deleteByCityDate(String cityDate);
}
4、运行程序,多次访问其中一个或者两个 地方的天气。
在RedisDesktopManager中可以看见以下内容:(缓存的内容)
5、查看缓存是否起作用:
判断缓存是否 有起作用,就看有没有 对数据库查询在缓存中已有的数据。
开启检查mongodb的访问数据库的记录的语句可以是以下语句:
db.setProfilingLevel(2) ==》应该是在查询之前开启的
这样子,在mongodb的数据库目录下会生成 system.profile文件,记录了查询数据库的所有操作。
由于我在redis只是缓存了 TodayWeather的部分,Weather的没有缓存,连续访问两个地方的天气,可以看出,weather部分还是有访问记录,但是,todayWather的就仅有各自一条,可见,其他的访问todayWeather都是在redis缓存中访问的。
6、至此,缓存的集成并且测试就完成了。
6.1、如使用MySQL数据库的话,就直接使用 :spring.jpa.properties.hibernate.show_sql = true
就好了,每当访问数据库,都有相应的 sql语句打印在控制台中。
6.2、使用mongodb作为数据库,是可以采用redis作为缓存的!!!!
7、项目代码下载:https://download.csdn.net/download/zhang_li_ke/10577187