【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)">;
}

}

Person.java

(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>&lt;Person&gt; persons=<span style="color: rgba(0, 0, 255, 1)">new</span> ArrayList&lt;Person&gt;<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)">;
}

}

Person.java

工具类的方法 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)">;
    }
    
}

}

SerializeUtil.java

(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 中的数据一致性。