spring boot 使用redis做缓存学习记录

来源:互联网 发布:电力大数据 编辑:程序博客网 时间:2024/06/05 07:45

一 、配置文件中的内容

  • redis 系统配置,即在application.yml文件中的配置
  • RedisPoolConfig配置
  • RedisPool配置
  • RedisConnectionFactory配置
  • StringRedisTemplate
  • RedisTemplate
package com.seedyee.config;import java.lang.reflect.Method;import java.net.UnknownHostException;import org.springframework.beans.factory.annotation.Value;import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.CachingConfigurerSupport;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.connection.jedis.JedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;import org.springframework.data.redis.serializer.StringRedisSerializer;import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;/** * @author lcl * @createDate 2016年11月22日上午11:00:08 redis 缓存配置类 * 这里实现CachingConfigurerSupport主要是方便使用自定义keyGenerator */@Configuration@EnableCaching // 启用缓存public class RedisCacheConfig extends CachingConfigurerSupport {    @Value("${spring.redis.host}")    private String host;    @Value("${spring.redis.port}")    private int port;    @Value("${spring.redis.timeout}")    private int timeout;    @Value("${spring.redis.password}")    private String password;    @Value("${spring.redis.pool.max-active}")    private int maxActive;    @Value("${spring.redis.pool.max-wait}")    private int maxWait;    @Value("${spring.redis.pool.max-idle}")    private int maxIdle;    @Value("${spring.redis.pool.min-idle}")    private int mainIdle;    /**     * 配置JedisPoolConfig     * @return JedisPoolConfig实体     */    @Bean    public JedisPoolConfig jedisPoolConfig() {        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();        jedisPoolConfig.setMaxIdle(this.maxIdle);        jedisPoolConfig.setMaxWaitMillis(this.maxWait);        jedisPoolConfig.setMinIdle(this.mainIdle);        return jedisPoolConfig;    }    /**     * 配置JedisPool     * @return     */    @Bean    public JedisPool jedisPool() {        JedisPool jedisPool = null;        if (this.password != null) {            jedisPool = new JedisPool(this.jedisPoolConfig(), this.host, this.port, this.timeout, this.password);        } else {            jedisPool = new JedisPool(this.jedisPoolConfig(), this.host, this.port);        }        return jedisPool;    }    /**     * RedisConnectionFactory配置     * @return     */    @Bean    public RedisConnectionFactory redisConnectionFactory() {        return new JedisConnectionFactory(this.jedisPoolConfig());    }    /**     * 配置StringRedisTemplate实体     * @return     */    @Bean    public StringRedisTemplate stringRedisTemplate() {        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();        stringRedisTemplate.setConnectionFactory(this.redisConnectionFactory());        return stringRedisTemplate;    }    /**     * 配置RedisTemplate     * @return 返回redisTemplate实体     */    @Bean    public RedisTemplate<String, Object> redisTemplate() throws UnknownHostException {        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();        template.setConnectionFactory(this.redisConnectionFactory());        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(                Object.class);        ObjectMapper om = new ObjectMapper();        om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);        om.enableDefaultTyping(DefaultTyping.NON_FINAL);        jackson2JsonRedisSerializer.setObjectMapper(om);        //使用StringRedisSerializer作为序列化key,默认是使用JdkSerializationRedisSerializer,会出现脏字段在key中        template.setKeySerializer(new StringRedisSerializer());        template.setValueSerializer(jackson2JsonRedisSerializer);        template.afterPropertiesSet();        return template;    }    /**     * 自定义keyGenerator     *      * @return     */    @Bean    public KeyGenerator wiselyKeyGenerator() {        return new KeyGenerator() {            @Override            public Object generate(Object target, Method method, Object... params) {                StringBuffer sb = new StringBuffer();                sb.append("mykey" + ":");                sb.append(method.getName() + ":");                for (Object object : params) {                    sb.append(object.toString());                }                return sb.toString();            }        };    }    /**     * 配置redis缓存管理对象     *      * @param redisTemplate     * @return     */    @Bean(name = "cacheManager")    public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {        return new RedisCacheManager(redisTemplate);    }}

注意:在配置文件中配置RedisTemplate的之后需要注意,Redis默认使用JdkSerializationRedisSerializer作为序列化key和value的,所以需要重新设置key和value的序列化,本文在代码中采用的key的序列化为StringRedisSerializer,value的序列化采用jackson2JsonRedisSerializer,具体代码请查看以上配置文件的代码。如果不设置的话插入redis数据库中的数据的key的形式为:\xAC\xED\x00\x05t\x00\x1810001,其中10001是自己存的key的值,会多前面这一窜,value的话分为对象和字符串的两种情况,字符串的情况和id的情况是一样的,对象的话就是把属性分为每个字符串的情况。

二、使用

2.1 使用注解实现方法级缓存

可以自定义缓存切入点,可以在dao层做,也可以在service层做,具体可以根据需求,下面记录的是在service层做的:

package com.seedyee.service;import java.util.Collection;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;import com.seedyee.dao.EmailDao;import com.seedyee.dao.RedisDao;import com.seedyee.dao.UserDao;import com.seedyee.domain.User;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;/** * @author lcl * @createDate 2016年11月21日下午5:30:23 * */@Servicepublic class UserService {    @Autowired    private CacheManager cacheManager;    @Autowired    private RedisDao redis;    @Autowired    private UserDao userDao;    @Autowired    private EmailDao emailDao;    //@Cacheable(cacheNames = {"users"}, key= "#user.id")    public Object createUser(User user) {        User createUser = null;        createUser = userDao.save(user);        return createUser;    }    @Cacheable(cacheNames = {"users"}, key = "#id" )    public Object getUserInfo(String id) {        User user = null;        user = userDao.findById(id);        Collection<String> cacheNames = cacheManager.getCacheNames();        for (String string : cacheNames) {            System.out.println(string);            System.out.println(cacheManager.getCache(string));        }        System.out.println("--------------进来说明没有使用缓存-------------------");        return user;    }    @CacheEvict(cacheNames = {"users"}, key = "#user.id")    public Object updateUserInfo(User user) {        User formUser = userDao.findById(user.getId());        if (user.getName() != null && formUser != null) {            formUser.setName(user.getName());            //修改成功删除缓存中的数据            //redis.delete(formUser.getId());            return userDao.save(formUser);        }        return "修改出现异常";    }    @CacheEvict(cacheNames = {"users"})    public Object deleteUser(String id) {        userDao.delete(id);        //删除成功删除缓存中的数据        //redis.delete(id);        return "ok";    }}

2.2 选择在需要的地方存储或是删除缓存的

2.2.1 配置redis对数据库操作类

使用配置文件中配置好的StringRedisTemplate和RedisTemplate来完成对数据库数据的CRUD操作,以下代码主要是存储和删除操作:
文件名 RedisDao.java

package com.seedyee.dao;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.stereotype.Component;/** * @author lcl * @createDate 2016年11月24日下午11:03:57 * */@Componentpublic class RedisDao {    @Autowired    private StringRedisTemplate stringRedisTemplate;//  @Resource(name = "stringRedisTemplate")//  private ValueOperations<String, String> valOpsStr;    @Autowired    private RedisTemplate<String, Object> redisTemplate;//  @Resource//  private ValueOperations<String, Object> valOps;    /**     * 存储字符串     * @param key string类型的key     * @param value String类型的value     */    public void set(String key, String value) {        stringRedisTemplate.opsForValue().set(key, value);    }    /**     * 存储对象     * @param key String类型的key     * @param value Object类型的value     */    public void set(String key, Object value) {        redisTemplate.opsForValue().set(key, value);    }    /**     * 根据key获取字符串数据     * @param key     * @return     */    public String getValue(String key) {        return stringRedisTemplate.opsForValue().get(key);    }    /**     * 根据key获取对象     * @param key     * @return     */    public Object getValueOfObject(String key) {        return redisTemplate.opsForValue().get(key);    }    /**     * 根据key删除缓存信息     * @param key     */    public void delete(String key) {        redisTemplate.delete(key);    }}

2.2.2 对缓存进行操作

在需要对缓存进行操作的地方使用redisDao的示例对象进行操作,下面的代码主要是记录删除时候的操作:

package com.seedyee.service;import java.util.Collection;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;import com.seedyee.dao.EmailDao;import com.seedyee.dao.RedisDao;import com.seedyee.dao.UserDao;import com.seedyee.domain.User;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;/** * @author lcl * @createDate 2016年11月21日下午5:30:23 * */@Servicepublic class UserService {    @Autowired    private CacheManager cacheManager;    @Autowired    private RedisDao redis;    @Autowired    private UserDao userDao;    @Autowired    private EmailDao emailDao;    //@Cacheable(cacheNames = {"users"}, key= "#user.id")    public Object createUser(User user) {        User createUser = null;        createUser = userDao.save(user);        return createUser;    }    @Cacheable(cacheNames = {"users"}, key = "#id" )    public Object getUserInfo(String id) {        User user = null;        user = userDao.findById(id);        Collection<String> cacheNames = cacheManager.getCacheNames();        for (String string : cacheNames) {            System.out.println(string);            System.out.println(cacheManager.getCache(string));        }        System.out.println("--------------进来说明没有使用缓存-------------------");        return user;    }    //@CacheEvict(cacheNames = {"users"}, key = "#user.id")    public Object updateUserInfo(User user) {        User formUser = userDao.findById(user.getId());        if (user.getName() != null && formUser != null) {            formUser.setName(user.getName());            //修改成功删除缓存中的数据            redis.delete(formUser.getId());            return userDao.save(formUser);        }        return "修改出现异常";    }    //@CacheEvict(cacheNames = {"users"})    public Object deleteUser(String id) {        userDao.delete(id);        //删除成功删除缓存中的数据        *redis.delete(id);*        return "ok";    }}

注意:在使用第二种方法实现缓存的时候,上面代码中删除缓存对应的信息以后,cacheName下的key的值没有删掉,cacheName下存储同一类的不同key。这里记录一下,寻求解决方法中。。。

0 0