在SpringBoot中使用Redis有两种方式,一种是使用Jredis,这是一个Client,得到实例后可以调用Redis的命令,使用上很简单明了,不过好像要自己处理下连接池

另一种是使用RedisTemplate,这个是被Spring封装了一次的,可以不关心连接池,在使用上又分为两种方式,一种是使用它封装的方法(类似于使用Jredis),另一种是使用注解方式


使用之前需要先添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-redis</artifactId>
    <version>1.4.7.RELEASE</version>
</dependency>


一、使用Jredis

使用Jredis需要先初始化连接池,然后从连接池中获取对象


JedisPool pool = new JedisPool("192.168.0.1",6379);


然后获取对象


Jedis jedis = jedisPool.getResource();

然后可以使用jedis调用Redis的命令

jedis.hset("hset","tem1","haha");
String str=jedis.get("string");


jedis封装了Redis的命令,命名和命令一致




二、使用RedisTeplate

使用RedisTeplate需要先创建一个他的配置类

在这里面主要求三个东西

第一个是CacheManager,在这里设置缓存的默认过期时间和某个缓存的过期时间(这个主要在使用注解方式时使用)

第二个是keyGenerator,这个是key生成规则,在这里写默认的(注解方式使用),也可以在写注解的时候定义

第三个是redisTemplate,这里谢了序列化方法,这里用的是json


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.payme.mbe.user.controller.UserController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    @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();
            }
        };
    }

    @SuppressWarnings("rawtypes")
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
        //设置默认缓存过期时间
        rcm.setDefaultExpiration(3600);//秒
        rcm.setExpires(this.initExpiresMap());//设置某个缓存的过期时间
        return rcm;
    }

    private Map<String, Long> initExpiresMap()
    {
        Map<String, Long> map= new HashMap<String, Long>();
        map.put("users",100L);
        return map;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate 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;
    }
}





1、使用方法

写好上面那些之后,我们可以使用方法来操作Redis

先注入两个Template

@Autowired
private StringRedisTemplate stringRedisTemplate;//操作String型数据

@Autowired
private RedisTemplate redisTemplate;//操作其它类型数据



stringRedisTemplate.opsForValue().set("aaa", "111");//添加一个key为aaa,值为111的缓存


下面是一个插入对象的

UserEntity user=new UserEntity();//UserEntity需要implements Serializable
user.setUserid(11);
user.setUserName("admin");



//这两个是将User插入缓存,第二个自定义了过期时间

ValueOperations<String, UserEntity> operations=redisTemplate.opsForValue();
operations.set("com.neox", user);
operations.set("com.neo.f", user,10, TimeUnit.SECONDS);

//判断是否存在key

boolean exists=redisTemplate.hasKey("com.neo.f");



//操作List,方法名和命令名有些类似

redisTemplate.opsForList().rightPush("gllist","1");
redisTemplate.opsForList().rightPush("gllist","2");
String str = (String)redisTemplate.opsForList().leftPop("gllist");
long siz = redisTemplate.opsForList().size("testList");



//一次性在list中插入多个(List方式)

redisTemplate.opsForList().rightPushAll("testList",list);



使用这种方法的形式可以操作Redis,如果实现缓存逻辑,插入、取出、删除需要自己写,这样的方式和Jedris类似


2、使用注解

也可以使用注解的方式使用缓存,如果在一个GetInfo的方法上使用注解,方法会自动先去缓存找数据,找不到再执行方法体(去数据库找),获取后再加入缓存(如果使用上面的方式,这些逻辑要自己写)

有三个注解项

@Cacheable//这个注解放到Get方法上,实现先去缓存找数据,找不到执行方法体(数据库找数据),获取后插入到缓存


@CachePut//这个注解一般是放到更新语句上,实现的功能是更新缓存对应的值(但是注意更新这个直接把更新方法的返回值更新到缓存里,例如GetUser和UpdateUser,我们缓存的是UserInfo,但是如果UpdateUser的返回值是int,只表示成功失败,那这个注解会把UserInfo替换为int值,所以如果使用需要把函数返回值改为对象)


@CacheEvict//这个是删除对应的缓存,一般放到delete方法上(如果我们在所有修改的方法上都放这个也行,修改就删除,靠get更新缓存)


例如下面的几个方法

注解的两个参数value表示这类数据的缓存列表名称,例如上面配置了users的过期时间。key就是每个数据的缓存key值(下面方法中key定义的缓存key值最后会是"userentity1","userentity2"这样)

这个方法会先去缓存找数据,找不到执行方法获取数据,然后再插入缓存

@Cacheable(value = "users", key="'userentity'+#userID")
    public UserEntity get(int userID) {

       UserEntity u = userMapper.getOne(userID);//userRepository.get(userID);
        if (u!=null)
        {
            logger.info("插入了- " + userID);
        }
        return u;
    }





这个方法会删除缓存中对应key值得数据

@CacheEvict(value = "users", key="'userentity'+#userID")
    public int delete(int userID) {
        int result = userMapper.delete(userID); //userRepository.delete(userID);
        return result;
    }



更新方法我同样也做了删除数据

@CacheEvict(value = "users", key="'userentity'+#userEntity.userid")
    public int update(UserEntity userEntity) {
        int result = userMapper.update(userEntity); 
    
        return result;
    }



到Redis里面数据会是这样

JRedisPool 设置 DB1_redis


@Cacheable(value = "users", key="'userentity'+#userID")
    public UserEntity get(int userID) {

       UserEntity u = userMapper.getOne(userID);//userRepository.get(userID);
        if (u!=null)
        {
            logger.info("CityServiceImpl.findCityById() : 插入了>> " + userID);
        }
        return u;
    }