2021-03-26 10:04发布
根据redis的存储原理,Redis的key和value都支持二进制安全的字符串
1.利用序列化和反序列化的方式
存储java对象我们可以通过对象的序列化与反序列化完成存储于取出,这样就可以使用redis存储java对象了
步骤:创建一个序列化和反序列化的工具类
public class SerializeUtil {
public static byte[] serialize(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
//序列化
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (Exception e) {
}
return null;
public static Object unserialize(byte[] bytes) {
ByteArrayInputStream bais = null;
//反序列化
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
每次存储和取出对象时都是需要调用方法序列与反序列的
方法2:将java对象转换为json字符串,利用json与java对象之间可以相互转换的方式进行存值和取值
具体存值和取值在上一篇文章中有写json与java对象的相互转换问题
下面是一个如何使用Redisson创建Java活动对象的示例。使用活动对象需要@REntity和@RId批注。
Java
1
@REntity
2
public class MyObject {
3
4
@RId
5
private String id;
6
7
@RIndex
8
private String field1;
9
10
11
private Integer field2;
12
13
14
private Long field3;
15
16
创建RLO并将其存储在Redis中后,您也可以使用Redisson进行搜索。可用的搜索条件包括:
· Condition.eq:将属性限制为定义值的“ EQUALS”条件。
· Condition.and: “ AND”条件,用于嵌套条件的集合。
· Condition.or:嵌套条件集合的“ OR”条件。
· http://Condition.in:将属性限制为一组定义值的“ IN”条件。
· Condition.gt: “大于”条件将属性限制为定义的值。
· Conditions.ge: “大于等于”条件,用于将属性限制为定义的值。
· Conditions.lt: “小于”条件,用于将属性限制为定义的值。
· Conditions.le: “小于或等于”条件将属性限制为定义的值。
以下是如何在Redisson中搜索Java活动对象的示例。此示例搜索将找到所有对象,其中field1 =值且field2 <12 field1 =值且field2> 23,或field3在[1,2]范围内。
RLiveObjectService liveObjectService = redisson.getLiveObjectService();
liveObjectService.persist(new MyObject());
Collection objects = liveObjectService.find(MyObject.class,
Conditions.or(Conditions.and(Conditions.eq("field1", "value"), Conditions.lt("field2", 12)),
Conditions.and(Conditions.eq("field1", "value2"), Conditions.gt("field2", 23)),
http://Conditions.in("field3", 1L, 2L));
Redisson PRO为Java对象实现了Redis搜索引擎,该引擎比开源版本快10倍,同时还降低了JVM内存消耗。
想用Redis存储java对象,首先需要把java对象序列化成byte数组,然后再进行存储。取出数据后,再反序列化成java对象即可。由此我们知道,每次存储和读取都需要进行序列化和反序列化。可以选择java自带的序列化功能(速度较慢,被序列化的类必须实现Serializable接口),也可以选择一些第三方写的牛逼的序列化工具,这里介绍使用kryo。引入pom依赖:
com.esotericsoftware
kryo
4.0.0
redis.clients
jedis
2.9.0
编写一个基本的序列化和反序列化类,
KryoSerializeUtil.java
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
/**
* 使用Kryo
* 把java对象序列化和反序列化
* 虽然所序列化和反序列化的类无需实现java.io.Serializable接口,
* 但还是建议实现java.io.Serializable接口,避免类修改后无法反序列化
* @author LAN
* @date 2018年11月13日
*/
public class KryoSerializeUtil {
* 把java对象序列化成byte数组
* @param object
* @return
if(object==null) {
Output output = null;
Kryo kryo = new Kryo();
output = new Output(baos);
kryo.writeObject(output, object);
output.flush();
return baos.toByteArray();
} finally {
if(baos!=null) baos.close();
} catch (IOException e) {
e.printStackTrace();
output.close();
* 把byte数组反序列化得到java对象
* @param bytes
* @param clazz
public static T unserialize(byte[] bytes, Class clazz) {
if(bytes==null || bytes.length==0) {
Input input = new Input(bytes);
T obj = kryo.readObject(input, clazz);
input.close();
return obj;
编写一个RedisUtil实现储存和读取java对象
RedisUtil.java
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisUtil {
private static String redisUrl = "127.0.0.1";
private static int redisPort = 6379;
private static String redisPassword = null;
private static int database = 1;// 可选0-15
private static final Logger logger = LoggerFactory.getLogger(RedisUtil.class);
private static volatile JedisPool jedisPool = null;
private RedisUtil() {
* 服务器整个应用关闭后(不是单个方法结束后),可考虑调用此方法销毁连接池
* @date 2018年11月14日
public static void destroy() {
if(jedisPool==null) return;
if(!jedisPool.isClosed()) jedisPool.close();
jedisPool.destroy();
private static Jedis getConnection() {
if (jedisPool == null) {
synchronized (RedisUtil.class) {// 线程安全
logger.debug("=================创建jedisPool Start=================");
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(200);//最大连接数, 默认8个
config.setMaxIdle(8);//最大空闲连接数, 默认8个
config.setMaxWaitMillis(1000 * 100);//获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
config.setTestOnBorrow(true);
jedisPool = new JedisPool(config, redisUrl, redisPort, 100000, redisPassword, database);
logger.debug("=================创建jedisPool End=================");
return jedisPool.getResource();
*
* @param key 存储的键
* @param o 存储的java对象
* @param expire 设置过期时间,单位:秒,小于0时为永不过期
public static void set(String key, Object o, int expire) {
Jedis jedis = null;
jedis = getConnection();
if(o==null) {
jedis.del(key.getBytes());
return;
byte[] data = KryoSerializeUtil.serialize(o);
if(expire>0) {
jedis.setex(key.getBytes(), expire, data);
}else {
jedis.set(key.getBytes(), data);
}finally {
if(jedis!=null) jedis.close();//新版本的close方法,如果是从JedisPool中取出的,则会放回到连接池中,并不会销毁。
public static void set(String key, Object o) {
set(key, o, -1);
public static T get(String key, Class clazz) {
byte[] data = jedis.get(key.getBytes());
if(data==null || data.length==0){
T t = (T) KryoSerializeUtil.unserialize(data, clazz);
return t;
通过set方法,可把java对象保存到Redis中,当然也可保存List对象等,并且可以设置过期时间(针对缓存特别有用);通过get方法,可以直接拿到存进去的java对象。注意,上述代码中如果使用jedis版本较低时,每个finally块中释放jedis连接的方法是不一样的,旧版本可能要用jedisPool.returnResource释放连接回到连接池中。
写一个main方法测试:
TestRedis.java
package com.lan.LanUtil;
import com.lan.LanUtil.utils.RedisUtil;
public class TestRedis {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("天天学习,好好进步!");
RedisUtil.set("sb", sb1);
List list = new ArrayList<>();
sb1 = new StringBuilder("进步!进步!进步!");
list.add(sb1);
list.add(new StringBuilder("好好学习,天天向上!"));
RedisUtil.set("list", list);
StringBuilder sb2 = RedisUtil.get("sb", StringBuilder.class);
List list2 = RedisUtil.get("list", ArrayList.class);
System.out.println(sb2);
for(StringBuilder s:list2) {
System.out.println(s);
运行结果:
其实对复杂的java类及List等都是可以进行存取的,事实上能存取什么java数据类型完全与序列化工具有关,和redis是无关的。
Redis 支持五种数据类型:String(字符串)、Hash(哈希)、List(列表),set(集合)、zset( sorted set:有序集合)
想用Redis存储java对象,首先需要把java对象序列化成byte数组,然后再进行存储。取出数据后,再反序列化成java对象即可。由此我们知道,每次存储和读取都需要进行序列化和反序列化。可以选择java自带的序列化功能(速度较慢,被序列化的类必须实现Serializable接口),也可以选择一些第三方写的牛逼的序列化工具,这里介绍使用kryo。引入pom依赖,代码如下:
com.esotericsoftware kryo 4.0.0 redis.clients jedis 2.9.0
· Condition.in:将属性限制为一组定义值的“ IN”条件。
Collection
Conditions.in("field3", 1L, 2L));
redis,你要搞高并发的话,不可避免,要把底层的缓存搞得很好mysql,高并发,做到了,那么也是通过一系列复杂的分库分表,订单系统,事务要求的,QPS到几万,比较高了要做一些电商的商品详情页,真正的超高并发,QPS上十万,甚至是百万,一秒钟百万的请求量光...
1。重现安装liunx系统,最好下其他版本的镜像,再下载redis2。可以去网上下载其他人的已经安装好redis的镜像,直接可以用
1、在线安装方式,找到安装的地址,删除安装目录,重新拉取rpm包,测试是否是环境问题,如果环境本身没有问题再查看自己的安装步骤,逐个命令的排查,锁定问题;2、离线安装方式,找到自己的安装包,确定安装包本身没有问题,那么查看tar解压后的安装目录结构...
RDB定时快照方式(snapshot): RDB 将数据库的快照(snapshot)以二进制的方式保存到磁盘中。AOF基于语句追加文件的方式:则以协议文本的方式,将所有对数据库进行过写入的命令(及其参数)记录到 AOF 文件,以此达到记录数据库状态的目的。一般来说, 如果想...
区别:RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。 AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不...
最多设置5个标签!
根据redis的存储原理,Redis的key和value都支持二进制安全的字符串
1.利用序列化和反序列化的方式
存储java对象我们可以通过对象的序列化与反序列化完成存储于取出,这样就可以使用redis存储java对象了
步骤:创建一个序列化和反序列化的工具类
public class SerializeUtil {
public static byte[] serialize(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
//序列化
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (Exception e) {
}
return null;
}
public static Object unserialize(byte[] bytes) {
ByteArrayInputStream bais = null;
try {
//反序列化
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
}
return null;
}
}
每次存储和取出对象时都是需要调用方法序列与反序列的
方法2:将java对象转换为json字符串,利用json与java对象之间可以相互转换的方式进行存值和取值
具体存值和取值在上一篇文章中有写json与java对象的相互转换问题
下面是一个如何使用Redisson创建Java活动对象的示例。使用活动对象需要@REntity和@RId批注。
Java
1
@REntity
2
public class MyObject {
3
4
@RId
5
private String id;
6
7
@RIndex
8
private String field1;
9
10
@RIndex
11
private Integer field2;
12
13
@RIndex
14
private Long field3;
15
16
}
创建RLO并将其存储在Redis中后,您也可以使用Redisson进行搜索。可用的搜索条件包括:
· Condition.eq:将属性限制为定义值的“ EQUALS”条件。
· Condition.and: “ AND”条件,用于嵌套条件的集合。
· Condition.or:嵌套条件集合的“ OR”条件。
· http://Condition.in:将属性限制为一组定义值的“ IN”条件。
· Condition.gt: “大于”条件将属性限制为定义的值。
· Conditions.ge: “大于等于”条件,用于将属性限制为定义的值。
· Conditions.lt: “小于”条件,用于将属性限制为定义的值。
· Conditions.le: “小于或等于”条件将属性限制为定义的值。
以下是如何在Redisson中搜索Java活动对象的示例。此示例搜索将找到所有对象,其中field1 =值且field2 <12 field1 =值且field2> 23,或field3在[1,2]范围内。
Java
1
RLiveObjectService liveObjectService = redisson.getLiveObjectService();
2
liveObjectService.persist(new MyObject());
3
4
Collection objects = liveObjectService.find(MyObject.class,
5
Conditions.or(Conditions.and(Conditions.eq("field1", "value"), Conditions.lt("field2", 12)),
6
Conditions.and(Conditions.eq("field1", "value2"), Conditions.gt("field2", 23)),
7
http://Conditions.in("field3", 1L, 2L));
8
Redisson PRO为Java对象实现了Redis搜索引擎,该引擎比开源版本快10倍,同时还降低了JVM内存消耗。
想用Redis存储java对象,首先需要把java对象序列化成byte数组,然后再进行存储。取出数据后,再反序列化成java对象即可。由此我们知道,每次存储和读取都需要进行序列化和反序列化。可以选择java自带的序列化功能(速度较慢,被序列化的类必须实现Serializable接口),也可以选择一些第三方写的牛逼的序列化工具,这里介绍使用kryo。引入pom依赖:
编写一个基本的序列化和反序列化类,
KryoSerializeUtil.java
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
/**
* 使用Kryo
* 把java对象序列化和反序列化
* 虽然所序列化和反序列化的类无需实现java.io.Serializable接口,
* 但还是建议实现java.io.Serializable接口,避免类修改后无法反序列化
* @author LAN
* @date 2018年11月13日
*/
public class KryoSerializeUtil {
/**
* 把java对象序列化成byte数组
* @author LAN
* @date 2018年11月13日
* @param object
* @return
*/
public static byte[] serialize(Object object) {
if(object==null) {
return null;
}
ByteArrayOutputStream baos = null;
Output output = null;
try {
Kryo kryo = new Kryo();
baos = new ByteArrayOutputStream();
output = new Output(baos);
kryo.writeObject(output, object);
output.flush();
return baos.toByteArray();
} finally {
try {
if(baos!=null) baos.close();
} catch (IOException e) {
e.printStackTrace();
}
output.close();
}
}
/**
* 把byte数组反序列化得到java对象
* @author LAN
* @date 2018年11月13日
* @param bytes
* @param clazz
* @return
*/
public static T unserialize(byte[] bytes, Class clazz) {
if(bytes==null || bytes.length==0) {
return null;
}
Kryo kryo = new Kryo();
Input input = new Input(bytes);
T obj = kryo.readObject(input, clazz);
input.close();
return obj;
}
}
编写一个RedisUtil实现储存和读取java对象
RedisUtil.java
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisUtil {
private static String redisUrl = "127.0.0.1";
private static int redisPort = 6379;
private static String redisPassword = null;
private static int database = 1;// 可选0-15
private static final Logger logger = LoggerFactory.getLogger(RedisUtil.class);
private static volatile JedisPool jedisPool = null;
private RedisUtil() {
}
/**
* 服务器整个应用关闭后(不是单个方法结束后),可考虑调用此方法销毁连接池
* @author LAN
* @date 2018年11月14日
*/
public static void destroy() {
if(jedisPool==null) return;
if(!jedisPool.isClosed()) jedisPool.close();
jedisPool.destroy();
}
private static Jedis getConnection() {
if (jedisPool == null) {
synchronized (RedisUtil.class) {// 线程安全
if (jedisPool == null) {
logger.debug("=================创建jedisPool Start=================");
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(200);//最大连接数, 默认8个
config.setMaxIdle(8);//最大空闲连接数, 默认8个
config.setMaxWaitMillis(1000 * 100);//获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
config.setTestOnBorrow(true);
jedisPool = new JedisPool(config, redisUrl, redisPort, 100000, redisPassword, database);
logger.debug("=================创建jedisPool End=================");
}
}
}
return jedisPool.getResource();
}
/**
*
* @author LAN
* @date 2018年11月14日
* @param key 存储的键
* @param o 存储的java对象
* @param expire 设置过期时间,单位:秒,小于0时为永不过期
*/
public static void set(String key, Object o, int expire) {
Jedis jedis = null;
try {
jedis = getConnection();
if(o==null) {
jedis.del(key.getBytes());
return;
}
byte[] data = KryoSerializeUtil.serialize(o);
if(expire>0) {
jedis.setex(key.getBytes(), expire, data);
}else {
jedis.set(key.getBytes(), data);
}
}finally {
if(jedis!=null) jedis.close();//新版本的close方法,如果是从JedisPool中取出的,则会放回到连接池中,并不会销毁。
}
}
public static void set(String key, Object o) {
set(key, o, -1);
}
public static T get(String key, Class clazz) {
Jedis jedis = null;
try {
jedis = getConnection();
byte[] data = jedis.get(key.getBytes());
if(data==null || data.length==0){
return null;
}
T t = (T) KryoSerializeUtil.unserialize(data, clazz);
return t;
}finally {
if(jedis!=null) jedis.close();//新版本的close方法,如果是从JedisPool中取出的,则会放回到连接池中,并不会销毁。
}
}
}
通过set方法,可把java对象保存到Redis中,当然也可保存List对象等,并且可以设置过期时间(针对缓存特别有用);通过get方法,可以直接拿到存进去的java对象。注意,上述代码中如果使用jedis版本较低时,每个finally块中释放jedis连接的方法是不一样的,旧版本可能要用jedisPool.returnResource释放连接回到连接池中。
写一个main方法测试:
TestRedis.java
package com.lan.LanUtil;
import java.util.ArrayList;
import java.util.List;
import com.lan.LanUtil.utils.RedisUtil;
public class TestRedis {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("天天学习,好好进步!");
RedisUtil.set("sb", sb1);
List list = new ArrayList<>();
sb1 = new StringBuilder("进步!进步!进步!");
list.add(sb1);
list.add(new StringBuilder("好好学习,天天向上!"));
RedisUtil.set("list", list);
StringBuilder sb2 = RedisUtil.get("sb", StringBuilder.class);
List list2 = RedisUtil.get("list", ArrayList.class);
System.out.println(sb2);
for(StringBuilder s:list2) {
System.out.println(s);
}
}
}
运行结果:
其实对复杂的java类及List等都是可以进行存取的,事实上能存取什么java数据类型完全与序列化工具有关,和redis是无关的。
Redis 支持五种数据类型:String(字符串)、Hash(哈希)、List(列表),set(集合)、zset( sorted set:有序集合)
根据redis的存储原理,Redis的key和value都支持二进制安全的字符串
1.利用序列化和反序列化的方式
存储java对象我们可以通过对象的序列化与反序列化完成存储于取出,这样就可以使用redis存储java对象了
步骤:创建一个序列化和反序列化的工具类
想用Redis存储java对象,首先需要把java对象序列化成byte数组,然后再进行存储。取出数据后,再反序列化成java对象即可。由此我们知道,每次存储和读取都需要进行序列化和反序列化。可以选择java自带的序列化功能(速度较慢,被序列化的类必须实现Serializable接口),也可以选择一些第三方写的牛逼的序列化工具,这里介绍使用kryo。引入pom依赖,代码如下:
Redis 支持五种数据类型:String(字符串)、Hash(哈希)、List(列表),set(集合)、zset( sorted set:有序集合)
下面是一个如何使用Redisson创建Java活动对象的示例。使用活动对象需要@REntity和@RId批注。
Java
1
@REntity
2
public class MyObject {
3
4
@RId
5
private String id;
6
7
@RIndex
8
private String field1;
9
10
@RIndex
11
private Integer field2;
12
13
@RIndex
14
private Long field3;
15
16
}
创建RLO并将其存储在Redis中后,您也可以使用Redisson进行搜索。可用的搜索条件包括:
· Condition.eq:将属性限制为定义值的“ EQUALS”条件。
· Condition.and: “ AND”条件,用于嵌套条件的集合。
· Condition.or:嵌套条件集合的“ OR”条件。
· Condition.in:将属性限制为一组定义值的“ IN”条件。
· Condition.gt: “大于”条件将属性限制为定义的值。
· Conditions.ge: “大于等于”条件,用于将属性限制为定义的值。
· Conditions.lt: “小于”条件,用于将属性限制为定义的值。
· Conditions.le: “小于或等于”条件将属性限制为定义的值。
以下是如何在Redisson中搜索Java活动对象的示例。此示例搜索将找到所有对象,其中field1 =值且field2 <12 field1 =值且field2> 23,或field3在[1,2]范围内。
Java
1
RLiveObjectService liveObjectService = redisson.getLiveObjectService();
2
liveObjectService.persist(new MyObject());
3
4
Collection
5
Conditions.or(Conditions.and(Conditions.eq("field1", "value"), Conditions.lt("field2", 12)),
6
Conditions.and(Conditions.eq("field1", "value2"), Conditions.gt("field2", 23)),
7
Conditions.in("field3", 1L, 2L));
8
Redisson PRO为Java对象实现了Redis搜索引擎,该引擎比开源版本快10倍,同时还降低了JVM内存消耗。
相关问题推荐
redis,你要搞高并发的话,不可避免,要把底层的缓存搞得很好mysql,高并发,做到了,那么也是通过一系列复杂的分库分表,订单系统,事务要求的,QPS到几万,比较高了要做一些电商的商品详情页,真正的超高并发,QPS上十万,甚至是百万,一秒钟百万的请求量光...
1。重现安装liunx系统,最好下其他版本的镜像,再下载redis2。可以去网上下载其他人的已经安装好redis的镜像,直接可以用
1、在线安装方式,找到安装的地址,删除安装目录,重新拉取rpm包,测试是否是环境问题,如果环境本身没有问题再查看自己的安装步骤,逐个命令的排查,锁定问题;2、离线安装方式,找到自己的安装包,确定安装包本身没有问题,那么查看tar解压后的安装目录结构...
RDB定时快照方式(snapshot): RDB 将数据库的快照(snapshot)以二进制的方式保存到磁盘中。AOF基于语句追加文件的方式:则以协议文本的方式,将所有对数据库进行过写入的命令(及其参数)记录到 AOF 文件,以此达到记录数据库状态的目的。一般来说, 如果想...
区别:RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。 AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不...