【Redis】解析Redis和Java传递数据
在 Java 中使用 Redis 之前需要导入 jedis.jar 包,由于 Redis 是基于 key-value 进行数据存储,java 中的数据存储到 Redis 中有许多方式,这里笔者介绍采用 JSON 字符串和对象序列化两种方式。
1,使用 JSON 方式
-
首先将 Java 对象转化为 JSON 字符串
-
然后将 JSON 字符串存储到 Redis 中
-
最后把 JSON 字符串从 Redis 中取出来,并且转化为 Java 对象
首先导入和 JSON 使用相关的包: gson.jar
实体类 Person 的代码如下:
package cn.wxg.person;import java.io.Serializable;
public class Person{
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> String name; </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> age; </span><span style="color: rgba(0, 0, 255, 1)">public</span> Person(String name, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> age) { </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">(); </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name; </span><span style="color: rgba(0, 0, 255, 1)">this</span>.age =<span style="color: rgba(0, 0, 0, 1)"> age; } </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Person() { </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">(); } </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getName() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> name; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setName(String name) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getAge() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> age; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setAge(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> age) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.age =<span style="color: rgba(0, 0, 0, 1)"> age; } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String toString() { </span><span style="color: rgba(0, 0, 255, 1)">return</span> "Person [name=" + name + ", age=" + age + "]"<span style="color: rgba(0, 0, 0, 1)">; }
}
(1). 将 Java 对象通过 JSON 存储到 Redis 中
//创建 Jedis 对象 Jedis jedis=new Jedis("127.0.0.1");</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">添加需要存储的数据</span> Person person=<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Person(); List</span><Person> persons=<span style="color: rgba(0, 0, 255, 1)">new</span> ArrayList<Person><span style="color: rgba(0, 0, 0, 1)">(); persons.add(</span><span style="color: rgba(0, 0, 255, 1)">new</span> Person("jame",3<span style="color: rgba(0, 0, 0, 1)">)); persons.add(</span><span style="color: rgba(0, 0, 255, 1)">new</span> Person("james",3<span style="color: rgba(0, 0, 0, 1)">)); persons.add(</span><span style="color: rgba(0, 0, 255, 1)">new</span> Person("ja",3<span style="color: rgba(0, 0, 0, 1)">)); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">将数据转化为JSON字符串,存储到Redis中</span> jedis.set("person",<span style="color: rgba(0, 0, 255, 1)">new</span> Gson().toJson(persons));</pre>
(2). 将 Redis 中的 JSON 字符串读取出,然后转化为 Java 对象
//创建 Jedis 对象 Jedis jedis=new Jedis("127.0.0.1"); //读取数据 String str = jedis.get("person"); //再将数据转化为 Java 对象 List<Person> fj = new Gson().fromJson(str, List.class); //输出数据 Iterator<Person> iterator = fj.iterator(); while(iterator.hasNext()){System.out.println(iterator.next()); }
这种通过 Json 的方式比较好理解,关于这种方式的更多信息还可以参见详解 JAVA 对象 JSON 的解析
2,使用对象序列化方式
在使用这种方式之前,需要存储到实体类需要序列化,否则就不能存储。
实体类 Person 的代码如下:
package cn.wxg.person;import java.io.Serializable;
public class Person implements Serializable{
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">long</span> serialVersionUID = 1L<span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> String name; </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> age; </span><span style="color: rgba(0, 0, 255, 1)">public</span> Person(String name, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> age) { </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">(); </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name; </span><span style="color: rgba(0, 0, 255, 1)">this</span>.age =<span style="color: rgba(0, 0, 0, 1)"> age; } </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Person() { </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">(); } </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getName() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> name; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setName(String name) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getAge() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> age; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setAge(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> age) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.age =<span style="color: rgba(0, 0, 0, 1)"> age; } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String toString() { </span><span style="color: rgba(0, 0, 255, 1)">return</span> "Person [name=" + name + ", age=" + age + "]"<span style="color: rgba(0, 0, 0, 1)">; }
}
工具类的方法 SerializeUtil 如下:
package cn.wxg.util;import java.io.*;
public class SerializeUtil {
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] serialize(Object object) { ObjectOutputStream oos </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; ByteArrayOutputStream baos </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 序列化</span> baos = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ByteArrayOutputStream(); oos </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ObjectOutputStream(baos); oos.writeObject(object); </span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] bytes =<span style="color: rgba(0, 0, 0, 1)"> baos.toByteArray(); </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bytes; } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) { e.printStackTrace(); </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; } } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> Object unserialize(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] bytes) { ByteArrayInputStream bais </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 反序列化</span> bais = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ByteArrayInputStream(bytes); ObjectInputStream ois </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ObjectInputStream(bais); </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> ois.readObject(); } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) { e.printStackTrace(); </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; } }
}
(1) 将对象序列化,并且存储到 Redis 中
//创建 Jedis 对象 Jedis jedis=new Jedis("127.0.0.1"); //需要存储的数据 Person person=new Person(); List<Person> persons=new ArrayList<Person>(); persons.add(new Person("jame",3)); persons.add(new Person("james",3)); persons.add(new Person("ja",3)); //对存储的数据序列化 byte[] bt = SerializeUtil.serialize(persons); //将字节数据存储到 Redis 中 jedis.set("persons".getBytes(),bt);
(2) 从 Redis 中读取数据,然后反序列化,得到 Java 对象
//创建 Jedis 对象 Jedis jedis=new Jedis("127.0.0.1"); //需要存储的数据 Person person=new Person(); List<Person> persons=new ArrayList<Person>(); persons.add(new Person("jame",3)); persons.add(new Person("james",3)); persons.add(new Person("ja",3)); //对存储的数据序列化 byte[] bt = SerializeUtil.serialize(persons); //将字节数据存储到 Redis 中 jedis.set("persons".getBytes(),bt);
这种方式效率比第一种高,推荐第二种。
3,Redis 的使用地方
Redis 可以用于性能优化,在这篇文章中SpringMVC 详解 AOP中,说到了如何进行程序性能监听。如果我们发现程序的速度表较慢的话,可以尝试使用 Redis 进行缓存优化。
使用 Redis 缓存的思路为:
@RequestMapping("querybook.do") public ModelAndView querybook(Integer bookId){ //查看在 Redis 中是否有该书籍的信息 Jedis jedis=new Jedis(); Book book=jedis.get(bookId.toString()); if(book!=null){ //直接把 Redis 读取的数据返回 return book; }else{ //从数据库中读取数据 book=Database.query(bookId); //将数据存储到 Redis 中 jedis.set("book".getBytes(),SerializeUtil.serialize(book)); //将数据返回 return book; } }
这里笔者再总结一下,就是在用户请求的时候,首先查看 Redis 中是否有该数据(因为从 Redis 中取数据的速度比从关系型数据库中取要快得多),如果有就直接从 Redis 中取,如果没有就从数据库中取,然后再把取出来的数据放到 Redis 中,这样的话下次用户请求的时候就可以直接从 Redis 中读取数据了。
使用 Redis 作为中间缓存,会增加很多逻辑控制代码。比如使用 Oracle 作为关系型数据库,Redis 作为中间缓存,那么 Oracle 和 Redis 的数据是不同步的,这时候对用户的一些基本操作(增、删、改、查)就会添加很多控制代码,以保证 Oracle 和 Redis 中的数据一致性。