springBoot中redis的使用

1、pom文件中加入redis所需依赖

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

2、配置文件中对redis的属性进行设置
 

#redis配置
#Redis服务器IP地址
spring.redis.host=127.0.0.1
#Redis服务器端口号
spring.redis.port=6379
#Redis数据库索引(默认为0)
spring.redis.database=0  
#Jedis连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=50
#Jedis连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=3000
#Jedis连接池中的最大空闲连接数
spring.redis.jedis.pool.max-idle=20
#Jedis连接池中的最小空闲连接数
spring.redis.jedis.pool.min-idle=2
#连接超时时间(毫秒)
spring.redis.timeout=5000

3、

三,编写配置类,加载配置,返回RedisTemplate:

创建RedisConfig文件:

import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import ...
 
@EnableCaching
@Configuration
public class RedisConfig 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.pool.max-idle}")
    private int maxIdle;
 
    @Value("${spring.redis.pool.max-wait}")
    private long maxWaitMillis;
 
    /**
    * 返回一个Jedis连接池
    */
    @Bean
    public JedisPool redisPoolFactory() {
        Logger.getLogger(getClass()).info("JedisPool注入成功!!");
        Logger.getLogger(getClass()).info("redis地址:" + host + ":" + port);
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
 
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout);
 
        return jedisPool;
    }
 
    /**
    * 返回一个RedisTemplate对象
    */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        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.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }
 
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        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);
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600)) //缓存过期10分钟 ---- 业务需求。
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))//设置key的序列化方式
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) //设置value的序列化
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}

四,方便使用,封装一个RedisTemplate工具类:

        将RedisTemplate实例包装成一个工具类,便于对redis进行数据操作

package com.xcbeyond.springboot.redis;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
 
@Component
public class RedisUtils {
 
	@Autowired
	private RedisTemplate<String, String> redisTemplate;
 
	/**
	 * 读取缓存
	 * 
	 * @param key
	 * @return
	 */
	public String get(final String key) {
		return redisTemplate.opsForValue().get(key);
	}
 
	/**
	 * 写入缓存
	 */
	public boolean set(final String key, String value) {
		boolean result = false;
		try {
			redisTemplate.opsForValue().set(key, value);
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
 
	/**
	 * 更新缓存
	 */
	public boolean getAndSet(final String key, String value) {
		boolean result = false;
		try {
			redisTemplate.opsForValue().getAndSet(key, value);
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
 
	/**
	 * 删除缓存
	 */
	public boolean delete(final String key) {
		boolean result = false;
		try {
			redisTemplate.delete(key);
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
}

五,使用:

1,使用自己封装的工具类:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class RedisTest {
	@Resource
	private RedisUtils redisUtils;
 
	/**
	 * 插入缓存数据
	 */
	@Test
	public void set() {
		redisUtils.set("redis_key", "redis_vale");
	}
	
	/**
	 * 读取缓存数据
	 */
	@Test
	public void get() {
		String value = redisUtils.get("redis_key");
		System.out.println(value);
	}
 
}

2,使用RedisTemplate:

@SpringBootTest
public class SpringbootRedisApplicationTests {
 
	@Autowired
	private redisTemplate redisTemplate;
 
	@Test
	void contextLoads() {
 
		//操作redis中字符串 opsForValue实际操作就是redis中的String类型
		redisTemplate.opsForValue().set("name", "张三");
		redisTemplate.opsForValue().set("k3","v3");
        System.out.println(redisTemplate.opsForValue().get("name"));
 
		//设置该key的过期时间
		redisTemplate.expire("k3", 60, TimeUnit.SECONDS);
		System.out.println(redisTemplate.getExpire("k3"));
 
		//获取所有的key
		Set<String> keys = redisTemplate.keys("*");
		System.out.println(keys);
	}
 
 
    //操作redis中的key
    @Test
    public void testKey(){
		//删除一个key
        redisTemplate.delete("name");
		
		//判断一个key是否存在
        Boolean name = redisTemplate.hasKey("name");
        System.out.println(name);
		
        redisTemplate.type("name");//判断key所对应的类型
		
        redisTemplate.keys("*");//获取所有的key
		
        Long name1 = redisTemplate.getExpire("name");//获取key的超时时间 -1 永不超时 -2 key不存在
        System.out.println(name1);
		
        redisTemplate.rename("age", "age1");//修改key的名字  要求key必须存在 不存在会报错
        redisTemplate.renameIfAbsent("age", "age1");//如果key存在才修改名字,否则不修改
		
        redisTemplate.move("name", 1);//移动key到指定库
    }
 
 
    //操作redis中字符串 opsForValue实际操作就是redis中的String类型
    @Test
    public void testString(){
        redisTemplate.opsForValue().set("name", "小陈");//set用来设置一个key value
        String name = redisTemplate.opsForValue().get("name");//用来获取一个key对应的value
        System.out.println(name);
 
		//设置一个key的超时时间(我们短信验证码的超时时间就是用这个做的)
        redisTemplate.opsForValue().set("code", "2357", 120, TimeUnit.SECONDS);
 
        redisTemplate.opsForValue().append("name", "他是一个好人");//给key的value追加内容
    }
 
 
    //操作list   redisTemplate.opsForList()
    @Test
    public void testList(){
        redisTemplate.opsForList().leftPush("names", "xiaochen");//创建列表,放入一个元素
        redisTemplate.opsForList().leftPushAll("names", "xiaowang", "xiaoming", "xiaohei");//放入多个元素
 
        List<String> names = new ArrayList<>();
        names.add("aaa");
        names.add("bbb");
        redisTemplate.opsForList().leftPushAll("names", names);//创建一个列表,放入多个元素
 
        List<String> names = redisTemplate.opsForList().range("names", 0, -1);//循环遍历
        for (String name : names) {
            System.out.println(name);
        }
 
        redisTemplate.opsForList().trim("names", 1, 3); //获取列表中的部分元素
    }
 
 
    //操作set    redisTemplate.opsForSet()
    @Test
    public void testSet(){
        redisTemplate.opsForSet().add("sets", "zhangsan", "lisi", "wangwu");//创建set,并放入多个元素
        Set<String> sets = redisTemplate.opsForSet().members("sets"); //获取Redis中的key为"sets"的set集合:
        for (String name : sets) {
            System.out.println(name);
        }
 
        Long sets1 = redisTemplate.opsForSet().size("sets");
        System.out.println(sets1);
    }
 
    //操作hash   redisTemplate.opsForHash()
    @Test
    public void tetstHash(){
        redisTemplate.opsForHash().put("maps", "name", "zhangsan");//创建一个hash类型
 
        Map<String, String> map = new HashMap<>();
        map.put("age", "12");
        map.put("bir", "2012-12-12");
        redisTemplate.opsForHash().putAll("maps", map);  //将一个key为"maps"的hash集合存入Redis;
 
        redisTemplate.opsForHash().get("maps", "name");//获取key为"maps"的hash集合中的某个key的value值
 
        redisTemplate.opsForHash().values("maps");//获取key为"maps"的hash集合中的所有key的值
 
        redisTemplate.opsForHash().keys("maps");//获取key为"maps"的hash集合中的所有key
 
        redisTemplate.opsForHash().multiGet("maps", Arrays.asList("name", "age"));//获取key为"maps"的hash集合中的多个key的value值
 
        
    }
 
    //操作zset   redisTemplate.opsForZSet()
    @Test
    public void testZset(){
        redisTemplate.opsForZSet().add("zsets", "zhangsan", 100);//创建并放入元素
        redisTemplate.opsForZSet().add("zsets", "lisi", 90);//创建并放入元素
        redisTemplate.opsForZSet().add("zsets", "wangwu", 80);//创建并放入元素
 
        Set<String> zsets = redisTemplate.opsForZSet().range("zsets", 0, -1);//获取所有元素
        for (String zset : zsets) {
            System.out.println(zset);
        }
 
        //获取指定分数范围的值
        Set<ZSetOperations.TypedTuple<String>> zsets = redisTemplate.opsForZSet().rangeByScoreWithScores("zsets", 0, 100);
        for (ZSetOperations.TypedTuple<String> zset : zsets) {
            System.out.println(zset.getValue() + "::" + zset.getScore());
        }
    }
 
}

3,使用注解——@Cacheable和@CacheEvict:

        接下来就是如何使用注解啦,这一步反而是最简单的;

        其实只用到了两个注解,@Cacheable和@CacheEvict,

        第一个注解@Cacheable代表从缓存中查询指定的key,如果有,从缓存中取,不再执行方法。如果没有则执行方法,并且将方法的返回值和指定的key关联起来,放入到缓存中。

        而@CacheEvict则是从缓存中清除指定的key对应的数据。

使用的代码如下:

//有参数
@Cacheable(value="thisredis", key="'users_'+#id")
public User findUser(Integer id) {
	User user = new User();
	user.setUsername("hlhdidi");
	user.setPassword("123");
	user.setUid(id.longValue());
	System.out.println("log4j2坏啦?");
	logger.info("输入user,用户名:{},密码:{}",user.getUsername(),user.getPassword());
	return user;
 }
 
@CacheEvict(value="thisredis",   key="'users_'+#id",condition="#id!=1")
public void delUser(Integer id) {
   // 删除user
   System.out.println("user删除");
}
 
//无参数
@RequestMapping("/get")
@Cacheable(value="thisredis")
@ResponseBody
public List<User> xx(){
	return userMapper.selectAll();
}
 
@RequestMapping("/get3")
@CacheEvict(value="thisredis")
@ResponseBody
public String xx3(){
	return "ok";
}

可以看出,我们用@Cacheable的value属性指定具体缓存,并通过key将其放入缓存中。

        这里key非常灵活,支持spring的el表达式,可以通过方法参数产生可变的key(见findUser方法),也可以通过其指定在什么情况下,使用/不使用缓存(见delUser方法)。

七,注意:

1,Redis中的对象必须序列化:

        通过redisTemplate存入redis中的key和value都是经过序列化后的对象,如果我们存入的对象的实体类没有实现序列化接口,那么就会报错,如下:

2,StringRedisTemplate 和 RedisTemplate的区别:

        两者的关系是StringRedisTemplate继承RedisTemplate。

        两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管RedisTemplate中的数据。

        SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。

        StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。

        RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。

总结

        当你的redis数据库里面本来存的是字符串数据、或者你要存取的数据就是字符串类型数据的时候,那么你就使用StringRedisTemplate即可,

        但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,那么使用RedisTemplate是更好选择。

3,写这个Config类和不写有什么区别呢?

        采用StringRedisTemplate的,不需要写Config配置类,因为Spring给他弄了序列化了,我们不需要在配置了,都是字符串;

        RestTemplate是默认采用JDK的序列化的,这样不便于阅读,所以我们通过配置类去配置RestTemplate序列化的方式。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot使用Redis有多种方式,下面是一个简单的示例: 首先,确保在`pom.xml`文件添加Redis的依赖项: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 然后,在`application.properties`(或`application.yml`)文件配置Redis连接信息: ```properties spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password= ``` 接下来,我们可以使用Spring Data Redis提供的`RedisTemplate`进行Redis操作。例如,存储和获取一个字符串值: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; @Component public class RedisExample { @Autowired private RedisTemplate<String, String> redisTemplate; public void setValue(String key, String value) { redisTemplate.opsForValue().set(key, value); } public String getValue(String key) { return redisTemplate.opsForValue().get(key); } } ``` 上面的示例,我们使用了`RedisTemplate`来执行Redis操作。通过自动注入,我们可以在Spring Boot应用程序的其他类使用`RedisExample`类。在其他地方,我们可以通过调用`setValue`方法来存储一个键值对,通过调用`getValue`方法来获取对应的值。 这只是Redis在Spring Boot的基本用法示例,你可以根据自己的需求进行更复杂的操作,如存储对象、使用Hash等。希望对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值