当redis里面需要存储 “key-字符串,value-对象” 时,是不能直接存对象,而是需要将序列化后或转换为JSON后的对象存进redis。
redis没有实现内部序列化对象的功能,所以需要自己提前序列化对象及转换为Json对象。
序列化的方法有很多,比如java原生序列化(需要实现Serializable接口)、json序列化、protobuff序列化。
protobuff序列化:告诉我对象的class,内部有schema来描述你的class是什么结构,class必须有get/set方法这种标准的类,而不是string等类
关于Serializable和protobuff序列化的介绍在我的上一篇文章:点击打开链接
由于之前对redis有很大兴趣,在使用redis当做数据缓存;所以趁着这些天的时间,自己写了一个将数据插入redis的demo;这里仅供自己后期学习笔记参考,若有不对的地方,请轻拍砖!
第一种:将数据对象转换为JSONString存入redis
1.首先pom文件导入
org.apache.commons
commons-pool2
2.4.2
redis.clients
jedis
2.9.0
jar
compile
com.dyuproject.protostuff
protostuff-core
1.0.8
com.dyuproject.protostuff
protostuff-runtime
1.0.8
2.redis.properties文件配置及 spring文件配置
redis.pool.maxTotal=1000
redis.pool.maxIdle=200
redis.pool.maxWaitMillis=2000
redis.pool.testOnBorrow=true
jedis.host=127.0.0.1
jedis.port=6379
3.写一个RedisUtil来获取和释放redis资源,得到Jedis对象
/**
* Created by ${HeJD} on 2018/6/29.
*/
@Component
public class RedisUtil {
/**
* 日志记录
*/
private static final Logger LOG = LoggerFactory.getLogger(RedisUtil.class);
/**
* redis 连接池,这里jedisPool我们再之前spring配置中配置好了,交给spring管理,这里可以自动注入
*/
@Autowired
private JedisPool jedisPool;
public void setPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
/**
* 获取jedis
* @return
*/
public Jedis getResource(){
Jedis jedis =null;
try {
jedis =jedisPool.getResource();
} catch (Exception e) {
LOG.info("can't get the redis resource");
}
return jedis;
}
/**
* 关闭连接
* @param jedis
*/
public void disconnect(Jedis jedis){
jedis.disconnect();
}
/**
* 将jedis 返还连接池
* @param jedis
*/
public void returnResource(Jedis jedis){
if(null != jedis){
try {
jedisPool.returnResource(jedis);
} catch (Exception e) {
LOG.info("can't return jedis to jedisPool");
}
}
}
/**
* 无法返还jedispool,释放jedis客户端对象,
* @param jedis
*/
public void brokenResource(Jedis jedis){
if (jedis!=null) {
try {
jedisPool.returnBrokenResource(jedis);
} catch (Exception e) {
LOG.info("can't release jedis Object");
}
}
}
}
import java.util.Map;
/**
* Created by ${HeJD} on 2018/6/29.
*/
public interface RedisCacheStorage {
/**
* 在redis数据库中插入 key 和value
* @param key
* @param value
* @return
*/
boolean set(K key,V value);
/**
* 在redis数据库中插入 key 和value 并且设置过期时间
* @param key
* @param value
* @param exp 过期时间
* @return
*/
boolean set(K key, V value, int exp);
/**
* 根据key 去redis 中获取value
* @param key
* @return
*/
V get(K key,Object object);
/**
* 删除redis库中的数据
* @param key
* @return
*/
boolean remove(K key);
/**
* 设置哈希类型数据到redis 数据库
* @param cacheKey 可以看做一张表
* @param key 表字段
* @param value
* @return
*/
boolean hset(String cacheKey,K key,V value);
/**
* 获取哈希表数据类型的值
* @param cacheKey
* @param key
* @return
*/
V hget(String cacheKey,K key,Object object);
/**
* 获取哈希类型的数据
* @param cacheKey
* @return
*/
Map hget(String cacheKey,Object object);
}
import com.mmall.service.RedisCacheStorage;
import com.mmall.util.RedisUtil;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisException;
import java.util.HashMap;
import java.util.Map;
/**
* Created by ${HeJD} on 2018/6/29.
*/
@Service("redisCacheStorage")
public class RedisCacheStorageImpl implements RedisCacheStorage{
//日志记录
private Logger log= LoggerFactory.getLogger(RedisCacheStorageImpl.class);
/**
* 默认过时时间
*/
private static final int EXPRIE_TIME =3600*24;
/**
* 获取Jedis相关操作
*/
@Autowired
private RedisUtil redisUtil;
@Override
public boolean set(String key, V value) {
return set(key,value,EXPRIE_TIME);
}
@Override
public boolean set(String key, V value, int exp) {
Jedis jedis=null;
if(StringUtils.isEmpty(key)){
return false;
}
try {
//获取jedis对象
jedis= redisUtil.getResource();
//使用对象转换为Json格式插入redis
JSONObject json = JSONObject.fromObject(value);//将java对象转换为json对象
String jsonValue = json.toString();//将json对象转换为json字符串
jedis.setex(key,exp,jsonValue);
}catch (Exception e){
//释放jedis对象
redisUtil.brokenResource(jedis);
log.info("client can't connect server");
return false;
}finally {
//返还连接池
redisUtil.returnResource(jedis);
return true;
}
}
@Override
public V get(String key,Object object) {
Jedis jedis=null;
V v=null;
if(StringUtils.isEmpty(key)){
log.info("redis取值,key为空");
return null;
}
try{
jedis=redisUtil.getResource(); //获取连接
String jsonValue=jedis.get(key); //从redis得到值,得到的是json字符串,因为我们之前插入的时候是使用的json字符串
if(StringUtils.isEmpty(jsonValue)){
return null;
}
JSONObject obj = new JSONObject().fromObject(jsonValue);//将json字符串转换为json对象
v = (V)JSONObject.toBean(obj,object.getClass());//将建json对象转换为你想要的java对象
return v;
}catch (Exception e){
//释放jedis对象
if(jedis!=null){
redisUtil.brokenResource(jedis);
}
log.info("client can't get value");
return null;
}finally {
//返还连接池
redisUtil.returnResource(jedis);
}
}
@Override
public boolean remove(String key) {
Jedis jedis=null;
try{
jedis=redisUtil.getResource();
if(StringUtils.isEmpty(key)){
log.info("redis取值,key为空");
return false;
}
jedis.del(key);
}catch (Exception e) {
//释放jedis对象
if(jedis!=null){
redisUtil.brokenResource(jedis);
}
log.info(" del fail from redis");
return false;
}finally{
//返还连接池
redisUtil.returnResource(jedis);
return true;
}
}
@Override
public boolean hset(String cacheKey, String key, V value) {
Jedis jedis =null;
//将key 和value 转换成 json 对象
JSONObject json = JSONObject.fromObject(cacheKey);//将java对象转换为json对象
String jCacheKey = json.toString();//将json对象转换为json字符串
JSONObject json2 = JSONObject.fromObject(value);//将java对象转换为json对象
String jsonValue = json2.toString();//将json对象转换为json字符串
//操作是否成功
boolean isSucess =true;
if(StringUtils.isEmpty(jCacheKey)){
log.info("cacheKey is empty");
return false;
}
try {
jedis =redisUtil.getResource();
//执行插入哈希
jedis.hset(jCacheKey, key, jsonValue);
} catch (Exception e) {
log.info("client can't connect server");
isSucess =false;
if(null !=jedis){
//释放jedis 对象
redisUtil.brokenResource(jedis);
}
return false;
}finally{
if (isSucess) {
//返还连接池
redisUtil.returnResource(jedis);
}
return true;
}
}
@Override
public V hget(String cacheKey, String key,Object object) {
Jedis jedis =null;
V v =null;
JSONObject json = JSONObject.fromObject(cacheKey);//将java对象转换为json对象
String jCacheKey = json.toString();//将json对象转换为json字符串
if(StringUtils.isEmpty(jCacheKey)){
log.info("cacheKey is empty");
return null;
}
try {
//获取客户端对象
jedis =redisUtil.getResource();
//执行查询
String jsonValue = jedis.hget(jCacheKey, key);
//判断值是否非空
if(StringUtils.isEmpty(jsonValue)){
return null;
}else{
JSONObject obj = new JSONObject().fromObject(jsonValue);//将json字符串转换为json对象
v = (V)JSONObject.toBean(obj,object.getClass());//将建json对象转换为java对象
}
//返还连接池
redisUtil.returnResource(jedis);
} catch (JedisException e) {
log.info("client can't connect server");
if(null !=jedis){
//redisUtil 对象
redisUtil.brokenResource(jedis);
}
}
return v;
}
@Override
public Map hget(String cacheKey,Object object) {
JSONObject json = JSONObject.fromObject(cacheKey);//将java对象转换为json对象
String jCacheKey = json.toString();//将json对象转换为字符串
//非空校验
if(StringUtils.isEmpty(jCacheKey)){
log.info("cacheKey is empty!");
return null;
}
Jedis jedis =null;
Map result =null;
V v=null;
try {
jedis =redisUtil.getResource();
//获取列表集合 因为插入redis的时候是jsonString格式,所以取出来key是String value也是String
Map map = jedis.hgetAll(jCacheKey);
if(null !=map){
for(Map.Entry entry : map.entrySet()){
if(result ==null){
result =new HashMap();
}
JSONObject obj = new JSONObject().fromObject(entry.getValue());//将json字符串转换为json对象
v = (V)JSONObject.toBean(obj,object.getClass());//将建json对象转换为java对象
result.put(entry.getKey(), v);
}
}
} catch (JedisException e) {
log.info("client can't connect server");
if(null !=jedis){
//释放jedis 对象
redisUtil.brokenResource(jedis);
}
}
return result;
}
}
/**
* Created by ${HeJD} on 2018/6/29.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class RedisCacheStorageTest {
@Autowired
private RedisCacheStorage redisCacheStorage;
@Test
public void testSetGet() throws Exception {
System.out.print("开始执行测试");
User user=new User();
user.setUsername("admin7");
user.setPassword("admin8");
redisCacheStorage.set("Akey7",user);
User user2= redisCacheStorage.get("Akey7",new User());
System.out.print("======="+user2.getUsername()+"====="+user2.getPassword());
}
}
public class SerializeUtil {
/*
* 序列化
* */
public static byte[] serizlize(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) {
e.printStackTrace();
}finally {
try {
if(baos != null){
baos.close();
}
if (oos != null) {
oos.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return null;
}
/*
* 反序列化
* */
public static Object deserialize(byte[] bytes){
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
try{
bais = new ByteArrayInputStream(bytes);
ois = new ObjectInputStream(bais);
return ois.readObject();
}catch(Exception e){
e.printStackTrace();
}finally {
try {
} catch (Exception e2) {
e2.printStackTrace();
}
}
return null;
}
}
package com.mmall.service.impl;
/**
* Created by ${HeJD} on 2018/7/1.
*/
import com.mmall.service.RedisCacheStorage;
import com.mmall.util.RedisUtil;
import com.mmall.util.SerializeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisException;
import java.util.HashMap;
import java.util.Map;
/**
* Created by ${HeJD} on 2018/6/29.
*/
@Service("redisCacheStorage2") //这里注入的名称不能相同,方便程序识别
public class RedisCacheStorageImpl2 implements RedisCacheStorage {
//日志记录
private Logger log= LoggerFactory.getLogger(RedisCacheStorageImpl2.class);
/**
* 默认过时时间
*/
private static final int EXPRIE_TIME =3600*24;
/**
* 获取Jedis相关操作
*/
@Autowired
private RedisUtil redisUtil;
@Override
public boolean set(String key, V value) {
return set(key,value,EXPRIE_TIME);
}
@Override
public boolean set(String key, V value, int exp) {
Jedis jedis=null;
if(StringUtils.isEmpty(key)){
return false;
}
try {
//获取jedis对象
jedis= redisUtil.getResource();
//序列化对象后插入到redis
//我们需要使用 public String setex(byte[] key, int seconds, byte[] value),所以将key.getBytes()
jedis.setex(key.getBytes(),exp, SerializeUtil.serizlize(value));
}catch (Exception e){
//释放jedis对象
redisUtil.brokenResource(jedis);
log.info("client can't connect server");
return false;
}finally {
//返还连接池
redisUtil.returnResource(jedis);
return true;
}
}
@Override
public V get(String key,Object object) {
Jedis jedis=null;
V v=null;
if(StringUtils.isEmpty(key)){
log.info("redis取值,key为空");
return null;
}
try{
jedis=redisUtil.getResource(); //获取连接
//我们存入的时候使用的是key.getBytes(),所以取的时候也要使用它的key数组
byte valueByte[]=jedis.get(key.getBytes()); //从redis得到值
if(valueByte.length<=0){
return null;
}
//反序列化取出我们的数据
v=(V)SerializeUtil.deserialize(valueByte); //将值转换为我们插入redis之前的数据类型
return v;
}catch (Exception e){
//释放jedis对象
if(jedis!=null){
redisUtil.brokenResource(jedis);
}
log.info("client can't get value");
return null;
}finally {
//返还连接池
redisUtil.returnResource(jedis);
}
}
@Override
public boolean remove(String key) {
Jedis jedis=null;
try{
jedis=redisUtil.getResource();
if(StringUtils.isEmpty(key)){
log.info("redis取值,key为空");
return false;
}
jedis.del(key.getBytes());
}catch (Exception e) {
//释放jedis对象
if(jedis!=null){
redisUtil.brokenResource(jedis);
}
log.info(" del fail from redis");
return false;
}finally{
//返还连接池
redisUtil.returnResource(jedis);
return true;
}
}
@Override
public boolean hset(String cacheKey, String key, V value) {
Jedis jedis =null;
byte valueDate[]= SerializeUtil.serizlize(value);
//操作是否成功
boolean isSucess =true;
if(StringUtils.isEmpty(cacheKey)){
log.info("cacheKey is empty");
return false;
}
try {
jedis =redisUtil.getResource();
//执行插入哈希
//public Long hset(byte[] key, byte[] field, byte[] value)
jedis.hset(cacheKey.getBytes(),key.getBytes(),valueDate);
} catch (Exception e) {
log.info("client can't connect server");
isSucess =false;
if(null !=jedis){
//释放jedis 对象
redisUtil.brokenResource(jedis);
}
return false;
}finally{
if (isSucess) {
//返还连接池
redisUtil.returnResource(jedis);
}
return true;
}
}
@Override
public V hget(String cacheKey, String key,Object object) {
Jedis jedis =null;
V v =null;
if(cacheKey.getBytes().length<=0){
log.info("cacheKey is empty");
return null;
}
try {
//获取客户端对象
jedis =redisUtil.getResource();
//执行查询
byte valueDate[] = jedis.hget(cacheKey.getBytes(), key.getBytes());
//判断值是否非空
if(valueDate.length<0){
return null;
}else{
//反序列化拿到数据
v= (V)SerializeUtil.deserialize(valueDate);
return v;
}
} catch (JedisException e) {
log.info("client can't connect server");
if(null !=jedis){
//redisUtil 对象
redisUtil.brokenResource(jedis);
}
}finally {
//返还连接池
redisUtil.returnResource(jedis);
}
return v;
}
@Override
public Map hget(String cacheKey,Object object) {
//非空校验
if(StringUtils.isEmpty(cacheKey)){
log.info("cacheKey is empty!");
return null;
}
Jedis jedis =null;
Map result =new HashMap();
try {
jedis =redisUtil.getResource();
//获取列表集合 因为插入redis的时候是key和value都是字节数组,所以返回的结果也是字节数组
Map map= jedis.hgetAll(cacheKey.getBytes());
if(null !=map){
for(Map.Entry entry : map.entrySet()){
result.put(new String(entry.getKey()),(V)SerializeUtil.deserialize(entry.getValue()));
}
}
} catch (JedisException e) {
log.info("client can't connect server");
if(null !=jedis){
//释放jedis 对象
redisUtil.brokenResource(jedis);
}
}
return result;
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class RedisCacheStorageTest {
@Autowired
@Qualifier("redisCacheStorage2")
private RedisCacheStorage redisCacheStorage;
@Test
public void testSet() throws Exception {
System.out.print("开始执行测试");
User user=new User();
user.setUsername("admin9");
user.setPassword("admin12");
redisCacheStorage.set("Akey9",user);
User user2= (User) redisCacheStorage.get("Akey9",new User());
System.out.print("======="+user2.getUsername()+"====="+user2.getPassword());
}
}
结果:
redis中的结果也贴一下吧:
127.0.0.1:6379> keys *
1) "Akey9"
2) "Akey7"
127.0.0.1:6379> get Akey7
"{\"password\":\"admin8\",\"role\":0,\"answer\":\"
ime\":null,\"phone\":\"\",\"updateTime\":null,\"id
\":\"admin7\"}"
127.0.0.1:6379> get Akey9
"\xac\xed\x00\x05sr\x00\x13com.mmall.pojo.User,\aC
x06answert\x00\x12Ljava/lang/String;L\x00\ncreateT
x00\x05emailq\x00~\x00\x01L\x00\x02idt\x00\x13Ljav
q\x00~\x00\x01L\x00\x05phoneq\x00~\x00\x01L\x00\bq
roleq\x00~\x00\x03L\x00\nupdateTimeq\x00~\x00\x02L
ppppt\x00\aadmin12ppppt\x00\x06admin9"
127.0.0.1:6379>