前言
Jedis和SpringDataRedis有何区别?
-
Jedis是Redis官方推荐的面向Java的操作Redis的客户端。
-
SpringDataRedis 中包含 StringRedisTemplate(操作键值对都是字符串的) 、RedisTemplate(操作键值对可能不是字符串的复杂键值对的),是对 JedisApi 的高度封装。
SpringDataRedis相对于Jedis来说可以方便地更换Redis的Java客户端,比Jedis多了自动管理连接池的特性,方便与其他Spring框架进行搭配使用如:SpringCache。
本文对第二条的SpringDataRedis进行讲解。
一、引入依赖:
<!-- redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 对象池,使用redis时必须引入 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
二、配置文件
spring:
redis:
host: 127.0.0.1
port: 6379
password: 123456
# 连接超时时间
timeout: 10000ms
# Redis默认情况下有16个分片,这里配置具体使用的分片
database: 0
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制) 默认 8
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
max-wait: -1ms
# 连接池中的最大空闲连接 默认 8
max-idle: 8
# 连接池中的最小空闲连接 默认 0
min-idle: 0
三、操作String
@Autowired
private StringRedisTemplate stringRedisTemplate;
//.....省略
//字符串的键值对存入redis(若已经有了“aaa”,再次set会覆盖原来的值)
stringRedisTemplate.opsForValue().set("aaa", "111");
//字符串的键值对存入redis,设置过期时间为 2秒
//stringRedisTemplate.opsForValue().set("aaa", "111", 2, TimeUnit.SECONDS);
//检查 key是否存在
//Boolean hasBoolean = stringRedisTemplate.hasKey("isHas");
//根据 key删除记录
//Boolean deleteBoolean = stringRedisTemplate.delete(key);
//从redis中根据键获取值
String value = stringRedisTemplate.opsForValue().get("aaa");
四、操作Map
@Autowired
private RedisTemplate redisTemplate;
//.....省略
Map<String, Object> map = new HashMap<>();
map.put("name", "张三");
map.put("password", 123456);
//将map存入redis,key 为 map1
redisTemplate.opsForHash().putAll("map1", map);
//向redis中的map1中增加键值对"age"->"13"
redisTemplate.opsForHash().put("map1", "age", "13");
//设置缓存时间有效期10秒
//redisTemplate.expire("map1", 10, TimeUnit.SECONDS);
//redis中获取整个map
Map<String, Object> resultMap = redisTemplate.opsForHash().entries("map1");
/*
//判断 redis的 map1里有没有键 age
boolean hashKeyBoolean = redisTemplate.opsForHash().hasKey("map1","age");
//redis中获取 map中指定的 key值,没有则返回 null
String name = (String) redisTemplate.opsForHash().get("map1", "name");
//redis中获取 map1中所有的 key
Set<String> resultMapSet=redisTemplate.opsForHash().keys("map1");
//redis中获取 map1中所有的 value
List<String> reslutMapList=redisTemplate.opsForHash().values("map1");
//删除 redis中获取 map1中age的键值对
redisTemplate.opsForHash().delete("map1","age");
//删除整个 map1
Boolean deleteBoolean = redisTemplate.delete("map1");
*/
五、操作List
@Autowired
private RedisTemplate redisTemplate;
//.....省略
List<String> list1 = new ArrayList<>();
list1.add("a1");
list1.add("a2");
list1.add("a3");
//存放到redis
redisTemplate.opsForList().rightPushAll("list1", list1);
//redis中的list1追加元素a4
redisTemplate.opsForList().rightPush("list1", "a4");
//设置缓存时间有效期10秒
//redisTemplate.expire("list1", 10, TimeUnit.SECONDS);
//从redis获取list1中所有元素
List<String> getList1 = (List<String>) redisTemplate.opsForList().range("list1", 0, -1);
六、操作Set
@Autowired
private RedisTemplate redisTemplate;
//.....省略
Set<String> set1 = new HashSet<>();
set1.add("123");
set1.add("456");
set1.add("789");
//存放到 redis
redisTemplate.opsForSet().add("set1", set1);
//设置缓存时间有效期10秒
//redisTemplate.expire("set1", 10, TimeUnit.SECONDS);
//从redis获取
Set<String> resultSet = redisTemplate.opsForSet().members("set1");
七、操作对象
在Redis中存储Java对象通常有以下三种方式:
- 方案一:首先将Java对象转化为json字符串,然后在Redis中存储这个转化后的字符串。
- 方案二:设置Redis的Value和HashValue的序列化方式设置为JDK序列化,然后在Redis中存储序列化后的二进制字节。
- 方案三:设置Redis的Value和HashValue的序列化方式设置为Jackson序列化,这种方案类似于方案一,在Redis中实际存储的是Jackson序列化后的json字符串,不过好处是不需要自己手动序列化/反序列化JSON字符串这个步骤了。
假设有一个对象Student:
public class Student {
private String name;
private String stuendId;
private String teacherName;
private String subject;
private String grade;
private String schoolName;
private String age;
private String fraction;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", stuendId='" + stuendId + '\'' +
", teacherName='" + teacherName + '\'' +
", subject='" + subject + '\'' +
", grade='" + grade + '\'' +
", schoolName='" + schoolName + '\'' +
", age=" + age +
", fraction='" + fraction + '\'' +
'}';
//省略get、set方法......
}
}
方案一示例 (利用fastjson序列化和反序列化):
@Autowired
private RedisTemplate redisTemplate;
//.....省略
Student student = new Student();
student.setAge("11");
student.setName("张三");
student.setGrade("5年级");
//对象序列化为字符串存入redis
redisTemplate.opsForValue().set("student1", JSONObject.toJSONString(student));
//从redis中获取字符串对象
String studentStr = String.valueOf(redisTemplate.opsForValue().get("student1"));
//字符串反序列化为对象
Student resultStudent = JSON.parseObject(studentStr, Student.class);
八、文件上传到redis和从redis下载文件
- 文件上传到redis:
@Autowired
private RedisTemplate redisTemplate;
/**
* 上传文件到redism。key为文件名,需带后缀
*/
public String setfileType(MultipartFile file) {
String fileName = file.getOriginalFilename();
try {
long start = System.currentTimeMillis();
redisTemplate.opsForValue().set(fileName, file.getBytes());
long end = System.currentTimeMillis();
logger.info("文件上传耗时:{}", end - start);
} catch (IOException e) {
e.printStackTrace();
}
return fileName;
}
Spring Boot做文件上传时,如果上传的文件过大会报错The field file exceeds its maximum permitted size of 1048576 bytes。
需要在配置文件里调整修改上传文件的大小,如果max-file-size和max-request-size都传-1则大小不做限制:
properties配置文件:
spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
yaml配置文件:
spring:
#文件上传控制文件的大小,如:max-file-size: 1MB max-request-size: 5MB ,若传-1则不限制大小
servlet:
multipart:
max-file-size: -1
max-request-size: -1
- 从redis获取文件:
/**
* redis获取文件,key是文件名要带后缀
*/
public String getfile(String key) {
//从redis里获取存储的文件byte[]
byte[] file = (byte[]) redisTemplate.opsForValue().get(key);
//byte[]写入缓冲输出流,保存到本地F:/test/,文件名是key要带后缀
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("F:/test/" + key))) {
bos.write(file);//写入数据
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "成功";
}
九、其他操作
redis中根据 key 删除
Boolean deleteBoolean = redisTemplate.delete(key);
判断redis里是否有key
//判断redis里是否有key
Boolean haskey = redisTemplate.hasKey(key);
参考:
RedisTemplate中opsForValue的使用
SpringBoot中Redis的set、map、list、value、实体类等基本操作介绍
RedisTemplate集合使用说明-opsForList(二)