本文章为系列文章,如需系统观看请按照文章顺序阅读,如有所了解,解决针对性问题,可直接阅读,谢谢支持!
Java操作Redis有很多种方式,主要有Jedis,redisson,lettuce等还有Spring家族的spring-data-redis
是Redis的Java实现客户端,提供了比较全面的Redis命令的支持
实现了分布式和可扩展的Java数据结构,提供很多分布式相关操作服务,例如,分布式锁,分布式集合,延迟队列
用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器,主要在一些分布式缓存框架上使用比较多
一般我们都会选择 spring-data-redis
redis的连接工厂类,根据Redis配置连接上Redis服务
熟悉Spring操作JDBC都知道JdbcTemplate作用,这个类也一样,spring 封装了 RedisTemplate 对象来进行对redis的各种操作,它支持所有的 redis 原生的 api
针对Jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口
提供了对key的bound(绑定)便捷化操作API,可以通过bound封装指定的key,然后进行一系列的操作而无须“显式”的再次指定Key
当数据存储到Redis时,键(key)和值(value)都是通过Spring提供的Serializer序列化到数据库的。RedisTemplate默认使用的是JdkSerializationRedisSerializer,StringRedisTemplate默认使用的是StringRedisSerializer
spring-data-redis中redisTemplate默认使用JDK的序列化策略,会出现两个问题
spring-data-redis默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略
key和hashKey:推荐使用 StringRedisSerializer: 简单的字符串序列化
value和hashValue:推荐使用Jackson2JsonRedisSerializer
当你的redis数据库里面本来存的是字符串数据或者你要存取的数据就是字符串类型数据的时候,那么你就使用StringRedisTemplate即可,但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,那么使用RedisTemplate是更好的选择
SpringBoot2.1.5、Redis5.0.5、Maven3.5.0、mybatis-Plus3.2.0
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-redis
com.alibaba
fastjson
1.2.7
org.springframework.boot
spring-boot-starter-test
test
spring:
#Redis配置
redis:
host: test201
port: 6379
password:
#这些都有默认配置,如果没有特殊需求可不写
#连接超时时间(2.0中该参数的类型为Duration,这里在配置的时候需要指明单位
timeout: 2000ms
#连接池最大连接数(使用负值表示没有限制)
max-active: 8
#连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
#连接池中的最大空闲连接
max-idle: 8
#连接池中的最小空闲连接
min-idle: 0
上边咱们说默认的RedisTemplate使用的序列化方式是JDK的,会存在特殊字符的问题而且性能损耗较大,我们创建Java Config修改默认实现的RedisTemplate序列化方式
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Redis的配置类
* SDR项目操作Redis的话需要使用RedisTemplate对象
* 但是该对象默认使用的数据序列化方法是JDK的,可能会存在特殊字符
*
* key和hashKey 我们推荐使用String序列化
* value 我们推荐是JSON存储,使用Json序列化
*/
//添加Configuration注解,否则该类不会被加载
@Configuration
public class RedisConfig {
/**
* @Bean:创建对象放到IOC容器中
* RedisConnectionFactory:Redis的连接工厂,根据application.yml文件中的Redis的配置做Redis连接和连接池的管理
该对象在项目初始化时被创建,有一个实现类是 LettuceConnectionFactory
*/
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory){
//创建原生的RedisTemplate对象
RedisTemplate redisTemplate = new RedisTemplate();
//设置连接工厂
redisTemplate.setConnectionFactory(connectionFactory);
// 使用Jackson2JsonRedisSerialize替换 默认的JDK序列化
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//创建JSON序列化的对象,value使用JSON序列化方式
ObjectMapper om = new ObjectMapper();
//设置序列化的策略
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//启用默认的类型
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//引用JSON序列化
jackson2JsonRedisSerializer.setObjectMapper(om);
//创建String序列化,我们的key使用String序列化方式
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
redisTemplate.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用JSON
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用JSON
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
//使用该配置
redisTemplate.afterPropertiesSet();
//返回修改后的RedisTemplate对象
return redisTemplate;
}
}
package com.tian.redis;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.*;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.*;
import java.util.concurrent.TimeUnit;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Day0512RedisApplicationTests {
@Test
public void contextLoads() {
}
//注入RedisTemplate
@Autowired
private RedisTemplate redisTemplate;
/**
* 操作String
*/
@Test
public void test1(){
//获取操作String'类型的对象
ValueOperations valueOperations = redisTemplate.opsForValue();
//存储数据
try {
valueOperations.set("user1","添哥");
valueOperations.set("user2","小添哥哥");
System.out.println("存储数据成功");
//获取数据
String user1 = (String)valueOperations.get("user1");
String user2 = (String)valueOperations.get("user2");
System.out.println(user1 + "==>" + user2);
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 操作list
*/
@Test
public void test2(){
ListOperations operations = redisTemplate.opsForList();
Long num = operations.leftPushAll("l1", "l11", "l22", "l33", "l44");
System.out.println("插入数据个数===》" + num);
//取值
List list = operations.range("l1", 0, -1);
for (Object o : list) {
System.out.println("list---》"+o);
}
}
/**
* 操作set
*/
@Test
public void test3(){
SetOperations operations = redisTemplate.opsForSet();
Long num = operations.add("s1", "s11", "s22", "s33", "s44", "s11", "s22", "s55");
System.out.println(num);
//获取
Set set = operations.members("s1");
for (Object o : set) {
System.out.println(o);
}
}
/**
* 操作zset
*/
@Test
public void test4(){
ZSetOperations operations = redisTemplate.opsForZSet();
operations.add("z1","z10",100.00);
operations.add("z1","z20",200.00);
operations.add("z1","z5",50.00);
//获取值
Set set = operations.range("z1", 0, -1);
for (Object o : set) {
System.out.println(o);
}
}
/**
* 操作Hash
*/
@Test
public void test5(){
HashOperations operations = redisTemplate.opsForHash();
//存储学生1
operations.put("stu:1:info","name","小添");
operations.put("stu:1:info","classRoom","快刀班");
//存储学生2
HashMap map = new HashMap<>();
//添加学生信息
map.put("name","晓添");
map.put("classRoom","吃瓜班");
operations.putAll("stu:2:info",map);
//获取数据1
Object name = operations.get("stu:1:info","name");
Object classRoom = operations.get("stu:1:info","classRoom");
System.out.println("学生1==》"+name+"==>"+classRoom);
//获取数据2
Map entries = operations.entries("stu:2:info");
//遍历map
Set set = entries.keySet();
for (Object o : set) {
System.out.println(o + "==>" + entries.get(o));
}
}
/**
* 对key的操作
*/
@Test
public void test6(){
//判断key是否存在
Boolean hasKey = redisTemplate.hasKey("stu:2:info");
System.out.println("stu:2:info===>"+hasKey);
//设置过期时间,k3键10秒过期
redisTemplate.expire("k3",10, TimeUnit.SECONDS);
//设置l1键在2020 5 13 7点过期
redisTemplate.expireAt("l1",new Date(2020,5,13,7,00,00));
}
}
//下方两个测试是使用RedisUtil中封装使用boundHashOps方式操作
@Test
public void t1(){
Student student = new Student();
student.setId("100");
student.setName("石靓仔");
student.setSex("男");
student.setBirth("1995-06-26");
redisUtil.putSome(Student.class,"student",student.getId(),student);
}
@Test
public void t2(){
List studentList = new ArrayList<>();
Cursor> student = redisUtil.getSome("student", Student.class);
while (student.hasNext()){
System.out.println(student.getCursorId());
Map.Entry next = student.next();
Student student1 = (Student) next.getValue();
studentList.add(student1);
}
for (Student student1 : studentList) {
System.out.println(student1);
}
}
封装一些常用的操作,大家可以根据自己的需求进行封装,这个作为参考吧
package com.tian.springbootredis.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* ClassName: RedisUtils
* Description:
* date: 2019/11/11 0011 下午 19:59
*
* @author stt
* @since JDK 1.8
*/
@Component
public class RedisUtil {
@Autowired
public RedisTemplate redisTemplate;
// =============================common============================
/**
26
* 指定缓存失效时间
27
* @param key 键
28
* @param time 时间(秒)
29
* @return
30
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key 获取过期时间
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断key是否存在
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public boolean del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
return redisTemplate.delete(key[0]);
}
return redisTemplate.delete(CollectionUtils.arrayToList(key)) > 0 ? true : false;
}
return false;
}
/**
* 匹配所有的key
* @param pettern
* @return
*/
public Set keys(String pettern){
if(pettern.trim() != "" && pettern != null){
return redisTemplate.keys(pettern);
}
return null;
}
// ============================String=============================
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 递增
* @param key 键
* @param delta 要增加几(大于0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
* @param key 键
* @param delta 要减少几(小于0)
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// ================================Map=================================
/**
* HashGet
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
* @param key 键
* @return 对应的多个键值
*/
public List
收藏等于学会,多多支持我吧!长期稳定输出优质系列文章!!!
页面更新:2024-03-08
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号