SpringBoot系列(2):SpringBoot集成单机版Redis

本节内容

目录

前言

SpringBoot项目集成单机版Redis

1、pom.xml依赖配置

2、配置中心(application.yml)加入redis参数配置

3、RedisTemplate配置

4、RedisUtils工具类

5、Congtroller测试


前言

最近项目上用到redis,主要就是在SpringBoot项目中集成Redis,在做拓展开发。关于SpringBoot集成Redis开发,实际上比较简单,网上也有很多的教程,这里还是自己总结一下实践过程,巩固学习。

工欲善其事必先利其器,不管是练习还是项目开发,我们要在SpringBoot中集成Redis,肯定得先安装Redis(废话了)。关于Redis的安装,这里不再赘述,详细安装步骤参见《(2)Linux环境下安装和使用Redis》,接下来步入正题。

SpringBoot项目集成单机版Redis

1、pom.xml依赖配置

在pom.xml文件里,需要什么jar包就引入什么依赖配置,即为方便,当然离线/断网/单机就算了。。。

<!--redis启动依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-redis</artifactId>
</dependency>

更直观地来看一下依赖配置。 

2、配置中心(application.yml)加入redis参数配置

在yml文件里配置redis参数,如目标主机地址host、redis服务端口port、超时时间timeout、redis访问连接的密码password、以及连接池参数配置,如下:

#连接池最大连接数(负值表示没有限制)
spring.redis.pool.max-active=8
#连接池最大阻塞等待时间(负值表示没有限制)
spring.redis.pool.max-wait= -1ms
#连接池中的最大空闲连接
spring.redis.pool.max-idle=8
#连接池中的最小空闲连接
spring.redis.pool.min-idle=0

具体配置:

#redis配置
 redis:
    host: 192.168.0.143
    port: 6379
    timeout: 10s
    lettuce:
      pool:
        min-idle: 0
        max-idle: 8
        max-active: 8
        max-wait: -1ms
    password:

3、RedisTemplate配置

关于redis配置,其实可以直接注入RedisTemplate对象,但是为什么,我们还要去自定义一个redisTemplate模板类?这里,我们看一下RedisAutoConfiguration自动化配置类的源码。

@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate")
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

	@Bean
	@ConditionalOnMissingBean
	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		StringRedisTemplate template = new StringRedisTemplate();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

}

注解@Import内容告诉我们,关于Redis连接池配置,提供了两种配置方式:Lettuce和Jedis。知道这两种方式即可,暂且跳过,以后再详细分析。

继续往下看,RedisAutoConfiguration类给出了两个生成模板类的方法,即SpringBoot集成Redis时,会自动帮我们在容器中生成一个RedisTemplate和一个StringRedisTemplate。但是,RedisTemplate是个泛型类,对于泛型<Object,Object>需要写好多类型转换的代码。相比较而言,我们需要一个泛型为<String,Object>形式的RedisTemplate。并且,这个RedisTemplate没有设置数据存在Redis时,key及value的序列化方式。

        注解@ConditionalOnMissingBean,表示如果容器中已经存在有RedisTemplate对象了,这个自动配置的RedisTemplate将不会被实例化。因此,可以直接自定义一个配置类,配置RedisTemplate。

RedisConfig类:

@Configuration
public class RedisConfig {

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(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);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

注意:设置key和value的序列化方式,不然存到Redis的中数据看起来乱七八糟的。 

4、RedisUtils工具类

直接用RedisTemplate操作Redis,代码量太大,体力怕是跟不上。因此直接封装一个RedisUtils,交给Spring容器实例化,使用时直接注解注入即可。

/**
 * RedisUtils类
 */
@Component
public class RedisUtils {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 写入缓存
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 写入缓存设置时效时间
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value, Long expireTime, TimeUnit timeUnit) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, timeUnit);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 批量删除对应的value
     *
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }

    /**
     * 批量删除key
     *
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0) {
            redisTemplate.delete(keys);
        }
    }

    /**
     * 删除对应的value
     *
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }

    /**
     * 判断缓存中是否有对应的value
     *
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 读取缓存
     *
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }

    /**
     * 哈希 添加
     *
     * @param key
     * @param hashKey
     * @param value
     */
    public void hmSet(String key, Object hashKey, Object value) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key, hashKey, value);
    }

    /**
     * 哈希获取数据
     *
     * @param key
     * @param hashKey
     * @return
     */
    public Object hmGet(String key, Object hashKey) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        return hash.get(key, hashKey);
    }

    /**
     * 列表添加
     *
     * @param k
     * @param v
     */
    public void lPush(String k, Object v) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(k, v);
    }

    /**
     * 列表获取
     *
     * @param k
     * @param l
     * @param l1
     * @return
     */
    public List<Object> lRange(String k, long l, long l1) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        return list.range(k, l, l1);
    }

    /**
     * 集合添加
     *
     * @param key
     * @param value
     */
    public void add(String key, Object value) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key, value);
    }

    /**
     * 集合获取
     *
     * @param key
     * @return
     */
    public Set<Object> setMembers(String key) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(key);
    }

    /**
     * 有序集合添加
     *
     * @param key
     * @param value
     * @param scoure
     */
    public void zAdd(String key, Object value, double scoure) {
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add(key, value, scoure);
    }

    /**
     * 有序集合获取
     *
     * @param key
     * @param scoure
     * @param scoure1
     * @return
     */
    public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }
}

5、Controller中测试

@RestController
@RequestMapping("/sysUser")
public class SysUserController  extends BaseController<ISysUserService> {
    private final static Logger logger = LoggerFactory.getLogger(SysUserController.class);
    @Autowired
    private RedisUtils redisUtils;

    /**
     * 根据ID查询系统用户
     */
    @RequestMapping(value = "/getUserById", method = RequestMethod.GET)
    public ResponseMessage getUserById(@RequestParam(value = "id") String id) {
        String str = "";
        boolean hasKey  = redisUtils.exists(id);
        if (hasKey ) {
            //获取缓存
            Object object  = redisUtils.get(id);
            logger.info("从缓存获取到的数据" + object);
            str = object.toString();
        } else {
            //从数据库中获取数据
            logger.info("从数据库中获取数据");
            SysUser infoById = baseService.selectById(id);
            System.out.println(infoById);
            str = infoById.getUserName();
            //数据插入缓存(set中的参数含义:key值,user对象,缓存存在时间10(long类型),时间单位)
            redisUtils.set(id, str,10L, TimeUnit.MINUTES);
            logger.info("数据插入缓存" + str);
        }
        return new ResponseMessage(ResponseStatus.SUCCESS.getStatus(), ResponseStatus.SUCCESS.getMessage(), str);
    }
}

愿你就像早晨八九点钟的太阳,活力十足,永远年轻。

发布了93 篇原创文章 · 获赞 136 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_27706119/article/details/103722794