注意
commands代表RedisCommands commands = RedisUtils.getCommands();
Product实体类:
@Data
public class Product implements Serializable {
private String productName;
private String place;
private String firm;
}
JSON格式的字符串
只需要把对象转换成JSON格式的字符串并存储到数据库中,获取反之
缺点:对象信息容易丢失
Product p = new Product();
p.setProductName("name");
p.setFirm("apple inc");
p.setPlace("china");
commands.set("Product:1001", JSONUtil.toJsonStr(p));
log.info("===>" + JSONUtil.toBean((String) commands.get("Product:1001"),Product.class));
使用Maven依赖(不需要特定的工具只需要JSON转换可以了)
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
效果
字节数组(自定义序列化器)
/**
* 当对象在I/O流中传输时,这个对象必须实现Serializable接口
*/
public class ObjectRedisSerializer implements RedisCodec<String, Object> {
/**
* 这个方法将key从redis取出来的时候转换成字符串类型
* 将key的字节缓冲(ByteBuffer)转换成string类型
*
* @param bytes Raw bytes of the key, must not be {@literal null}.
* @return
*/
@Override
public String decodeKey(ByteBuffer bytes) {
// 在系统中分配内存,(为什么需要分配,8GB的内存条中有JVM的空间[用于运行java],Redis是另一个空间,JVM无法直接读取,需要创建一个额外的空间读取)
ByteBuffer buffer = ByteBuffer.allocate(bytes.capacity());
buffer.put(bytes);
// 将字节数组以UTF-8的编码转换成String并返回
return new String(buffer.array(), StandardCharsets.UTF_8);
}
/**
* 从redis取出来的字节数组转换成任意的Object对象
*
* @param bytes Raw bytes of the value, must not be {@literal null}.
* @return
*/
@Override
public Object decodeValue(ByteBuffer bytes) {
// 在系统中分配内存
ByteBuffer buffer = ByteBuffer.allocate(bytes.capacity());
buffer.put(bytes);
// 构建字节数组的输入流,这样就可以在JVM的内存中将这个字节数组反序列化成任意的Object对象
try (ByteArrayInputStream bais = new ByteArrayInputStream(buffer.array())) {
// 再通过对象输入流将其转换即可
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException("无法反序列化value", e);
}
}
/**
* 字符串的key序列化成字节数组保存到redis
* @param key the key, may be {@literal null}.
*
* @return
*/
@Override
public ByteBuffer encodeKey(String key) {
return ByteBuffer.wrap(key.getBytes(StandardCharsets.UTF_8));
}
/**
* Object序列化成字节数组保存到redis
* @param value the value, may be {@literal null}.
*
* @return
*/
@Override
public ByteBuffer encodeValue(Object value) {
// 构建字节数组的输出流
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ObjectOutputStream oos = new ObjectOutputStream(baos);
// 将对象写入流中变成字节数组
oos.writeObject(value);
// 从流中获取字节数组
byte[] bytes = baos.toByteArray();
// 将字节数组包装成ByteBuffer对象并返回
return ByteBuffer.wrap(bytes);
} catch (IOException e) {
throw new RuntimeException("无法序列化object", e);
}
}
}
效果
Spring中装配
装配String类型的RedisTemplate
装配String类型的RedisTemplate,用于操作redis数据库,这个template只能用于操作key和value都是String类型的数据
@Bean
public RedisTemplate<String,String> stringRedisTemplate(){
// 创建StringRedisTemplate并注入连接工厂
return new StringRedisTemplate(connectionFactory());
}
装配自定义的RedisTemplate(推荐)
市场推荐使用这种方法
装配自定义的RedisTemplate,通过使用不同的序列化器,来定制序列化key和value的数据类型
@Bean
public RedisTemplate<String,Object> redisTemplate(){
RedisTemplate<String,Object> template = new RedisTemplate();
// 使用StringRedisSerializer来序列化和反序列化key
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
// 使用Jackson序列化器来序列化和反序列化value
// 底层使用 js序列化 的包
template.setValueSerializer(RedisSerializer.json());
template.setHashValueSerializer(RedisSerializer.json());
// 注入RedisConnectionFactory
template.setConnectionFactory(connectionFactory());
return template;
}