【redis】4.spring boot集成redis,实现数据缓存

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 参考地址:https://spring.io/guides/gs/messaging-redis/  ==============================================================================================================================1.

参考地址:https://spring.io/guides/gs/messaging-redis/

 

 ==============================================================================================================================

1.pom.xml关于redis的依赖

spring boot 1.4版本之前的关于redis的依赖

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

上面依赖如果在高版本使用,会出现下面的情况:

已经被弃用

 

 

而spring boot 1.4版本之后的关于redis的依赖 【如下,使用时去掉<version>即可】

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

 

2.application.properties配置

#redis
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=398023
# 连接池最大连接数(使用负值表示没有限制)
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

 

 

3.RedisConfig.java

【Redis的key生成策略、缓存管理、序列化】

【配置以后,就可以单独使用注解的方式使用redis了】

package com.sxd.redis;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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 {

    /**
     * 生成key的策略【默认第一种】
     * 如果不指定,则按照本方法的key生成策略去拼接key
     * 例如:com.sxd.service.UserServiceImpl.save:com.sxd.entity.User@7c9359ec
     * @return
     */
    @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();
            }
        };
    }

    /**
     * 生成key的策略【自定义第二种】
     * 使用时在注解@Cacheable(value = "12s",keyGenerator = "listkeyGenerator")中指定
     * @return
     */
    @Bean(name = "listkeyGenerator")
    public KeyGenerator listkeyGenerator(){
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(method.getName());
                return sb.toString();
            }
        };
    }

    /**
     * 缓存管理
     */
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager rcm =new RedisCacheManager(redisTemplate);

        //按需求设置自己需要的    缓存名字 和 对应的失效时间
        //可以不要
        Map<String,Long> map = new HashMap<>();
        map.put("12h",3600*12L);
        map.put("12m",60*12L);
        map.put("12s",12L);
        rcm.setExpires(map);


        return rcm;
    }


    /**
     * RedisTemplate配置
     * Redis序列化
     */
    @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;
    }
}
View Code

 

4.RedisService.java

【spring提供操作redis方法的封装】

【本来注解可以单独使用操作redis,如果配合封装的方法的话,可以实现更多更完善的功能】

package com.sxd.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class RedisService {

    @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) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            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);
    }
    /**
     * 根据key删除对应的value
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }
    /**
     * 根据key判断缓存中是否有对应的value
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }
    /**
     * 根据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);
    }
}
View Code

 

 

5.创建实体,对应数据库中的数据表,实体对应的Repository,和实体对应的ServiceImpl,以及Controller

实体类就不上了

repository如下:

【只写了几个方法】

package com.sxd.repository;

import com.sxd.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.lang.annotation.Target;


public interface UserRepository extends JpaRepository<User,String>{

    User findByUsername(String username);

    User findByUsernameAndPassword(String username,String password);

    User findById(String id);

    @Query("select u from User u where u.username = :name")
    User findUser(@Param("name")String username);


    User findTop3ByAge(Integer age);


}
View Code

 

UserServiceImpl.java

package com.sxd.service;

import com.sxd.entity.User;
import com.sxd.redis.RedisService;
import com.sxd.repository.UserRepository;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import static javafx.scene.input.KeyCode.T;

@Service
public class UserServiceImpl {

    @Resource
    private UserRepository userRepository;

    @Resource
    private RedisService redisService;

    @Cacheable(value = "us",key = "'EDS'")
// @Cacheable(value = "12h",keyGenerator = "listkeyGenerator")
// RedisConfig.java中配置的 定时失效的缓存,可以在这里指定value就是那边设定的缓存名
// keyGenerator 可以指定RedisConfig.java中配置的key生成策略

// key的值可以设定为字符串【字符串必须要用''引起来,否则会将其认定为字段而报错】    例如:key = "'EDS'"
// key的值也可以设定为spEL表达式书写     例如:key = "#userId"
// key的值也可以设定为      例如:key = "T(java.util.UUID).randomUUID().toString()"

// 关于注解中每个属性的详细使用,可以详细去查看API
    public List<User> findAllUser(){
        List<User> list = userRepository.findAll();
        return  Objects.nonNull(list) ? list : null;
    }

    @Cacheable(value = "allUser",key = "#userId")
    public User getById(String userId){
        User user = userRepository.findById(userId);
        return  Objects.nonNull(user) ? user : null;
    }

    @CachePut(value = "allUser",key="#user.id")
    public User save(User user){
        user = userRepository.save(user);
        redisService.remove("findAllUser");
        return user;
    }

    @CacheEvict(value = "allUser",allEntries = true)
    public void flushRedis(){

    }



}
View Code

关于这三个注解的详细使用说明:http://www.cnblogs.com/sxdcgaq8080/p/7228163.html

 

最后Controller去访问就好了 。

 

6.最后的说明

第一:@Cacheable(value = "12h",keyGenerator = "listkeyGenerator")
第二:RedisConfig.java中配置的 定时失效的缓存,可以在这里指定value就是那边设定的缓存名
第三:keyGenerator 可以指定RedisConfig.java中配置的key生成策略

第四:key的值可以设定为字符串【字符串必须要用''引起来,否则会将其认定为字段而报错】    例如:key = "'EDS'"
第五:key的值也可以设定为spEL表达式书写     例如:key = "#userId"
第六:key的值也可以设定为      例如:key = "T(java.util.UUID).randomUUID().toString()"

第七:spring管理redis的情况下,实测,就算
@Cacheable(value = "",key="")中的value值不同,key如果一致,也就是如果键值对的key已经存在与redis中,就算value值不同,也不会去创建新的缓存

第八:单独使用注解去使用了管理redis的话,很大程度上不是很灵活和方便,所以推荐使用注解和RedisService.java中的封装方法一起使用,效果更佳!
第九:RedisService.java中封装的方法仅作为部分参考,各位可以自己去完善更丰富的操作方法!!

 
第十:关于注解中每个属性的详细使用,可以详细去查看API

 

下面展示一下redis中存入的数据!!

 

 

 

=========================================================================

大概就是这些了。

赶紧完善正式项目中的这部分功能了!!!!

 

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2天前
|
NoSQL Java MongoDB
【MongoDB 专栏】MongoDB 与 Spring Boot 的集成实践
【5月更文挑战第11天】本文介绍了如何将非关系型数据库MongoDB与Spring Boot框架集成,以实现高效灵活的数据管理。Spring Boot简化了Spring应用的构建和部署,MongoDB则以其对灵活数据结构的处理能力受到青睐。集成步骤包括:添加MongoDB依赖、配置连接信息、创建数据访问对象(DAO)以及进行数据操作。通过这种方式,开发者可以充分利用两者优势,应对各种数据需求。在实际应用中,结合微服务架构等技术,可以构建高性能、可扩展的系统。掌握MongoDB与Spring Boot集成对于提升开发效率和项目质量至关重要,未来有望在更多领域得到广泛应用。
【MongoDB 专栏】MongoDB 与 Spring Boot 的集成实践
|
3天前
|
消息中间件 JSON Java
RabbitMQ的springboot项目集成使用-01
RabbitMQ的springboot项目集成使用-01
|
3天前
|
搜索推荐 Java 数据库
springboot集成ElasticSearch的具体操作(系统全文检索)
springboot集成ElasticSearch的具体操作(系统全文检索)
|
3天前
|
网络协议 Java Spring
Springboot 集成websocket
Springboot 集成websocket
7 0
|
4天前
|
JSON NoSQL Java
深入浅出Redis(十三):SpringBoot整合Redis客户端
深入浅出Redis(十三):SpringBoot整合Redis客户端
|
5天前
|
安全 Java 数据库连接
在IntelliJ IDEA中通过Spring Boot集成达梦数据库:从入门到精通
在IntelliJ IDEA中通过Spring Boot集成达梦数据库:从入门到精通
|
13天前
|
XML 存储 缓存
Spring缓存是如何实现的?如何扩展使其支持过期删除功能?
总之,Spring的缓存抽象提供了一种方便的方式来实现缓存功能,并且可以与各种缓存提供商集成以支持不同的过期策略。您可以根据项目的具体需求选择适合的方式来配置和扩展Spring缓存功能。
16 0
|
13天前
|
缓存 NoSQL Java
springboot业务开发--springboot集成redis解决缓存雪崩穿透问题
该文介绍了缓存使用中可能出现的三个问题及解决方案:缓存穿透、缓存击穿和缓存雪崩。为防止缓存穿透,可校验请求数据并缓存空值;缓存击穿可采用限流、热点数据预加载或加锁策略;缓存雪崩则需避免同一时间大量缓存失效,可设置随机过期时间。文章还提及了Spring Boot中Redis缓存的配置,包括缓存null值、使用前缀和自定义过期时间,并提供了改造代码以实现缓存到期时间的个性化设置。
|
16天前
|
前端开发 Java 应用服务中间件
从零手写实现 tomcat-08-tomcat 如何与 springboot 集成?
该文是一系列关于从零开始手写实现 Apache Tomcat 的教程概述。作者希望通过亲自动手实践理解 Tomcat 的核心机制。文章讨论了 Spring Boot 如何实现直接通过 `main` 方法启动,Spring 与 Tomcat 容器的集成方式,以及两者生命周期的同步原理。文中还提出了实现 Tomcat 的启发,强调在设计启动流程时确保资源的正确加载和初始化。最后提到了一个名为 mini-cat(嗅虎)的简易 Tomcat 实现项目,开源于 [GitHub](https://github.com/houbb/minicat)。
|
1月前
|
消息中间件 Java Kafka
Springboot集成高低版本kafka
Springboot集成高低版本kafka