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

参考地址: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配置

 

spring boot2.0之前的配置

#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

 

 

spring boot2.0 以后的配置

#redis配置
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=398023
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedi.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedi.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedi.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.jedi.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,如果配合封装的方法的话,可以实现更多更完善的功能】

【建议:把

ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();

提取出来】

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中存入的数据!!

 

 

 

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

大概就是这些了。

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

 

posted @ 2017-12-12 17:46  Angel挤一挤  阅读(1564)  评论(0编辑  收藏  举报