springboot实战(续 天气接口)之 mongodb数据库集成redis缓存使用并检验缓存是否起作用

本篇博客是基于上一篇博客的,上一篇完成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

猜你喜欢

转载自blog.csdn.net/zhang_li_ke/article/details/81323334