在生产过程中经常会用到redis这种nosql数据存储,以达到快速的查询等操作。
在参考网上与相关图书资料后,决定自己动手实践以下redis对对象的存储与读取,以便以后在工作中可以拿来主意。
redis主要存储类型最常用的五种数据类型:
String
Hash
List
Set
Sorted set
redis存储对象需要序列化和反序列化
为什么要实现序列化接口?
当一个类实现了Serializable接口(该接口仅为标记接口,不包含任何方法定义),表示该类可以序列化.序列化的目的是将一个实现了Serializable接口的对象转换成一个字节序列,可以。 把该字节序列保存起来(例如:保存在一个文件里),以后可以随时将该字节序列恢复为原来的对象。甚至可以将该字节序列放到其他计算机上或者通过网络传输到其他计算机上恢复,只要该计 算机平台存在相应的类就可以正常恢复为原来的对象。 实现:要序列化一个对象,先要创建某些OutputStream对象,然后将其封装在一个ObjectOutputStream对象内,再调用writeObject()方法即可序列化一个对象;反序列化也类似。
注意:使用对象流写入到文件是不仅要保证该对象是序列化的,而且该对象的成员对象也必须是序列化的
实体必须实现了序列化(Serializable)接口:
package db;
import java.io.Serializable;
import java.util.Date;
/**
* Created by dongzy on 2017/8/9.
*/
public class CustomerDictType implements Serializable{
private String customerDictTypeId;
private String tableName;
private String remark;
private java.util.Date updateTime;
private String updateUser;
public String getUpdateUser() {
return updateUser;
}
public void setUpdateUser(String updateUser) {
this.updateUser = updateUser;
}
public String getCustomerDictTypeId() {
return customerDictTypeId;
}
public void setCustomerDictTypeId(String customerDictTypeId) {
this.customerDictTypeId = customerDictTypeId;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
单元测试代码:
@Test
public void test1(){
CustomerDictTypeDao customerDictTypeDao = new CustomerDictTypeDao();
List<CustomerDictTypeEntity> customerDictTypeEntityList = (List<CustomerDictTypeEntity>) customerDictTypeDao.addOrderByField
(CustomerDictTypeDao.CUSTOMER_DICT_TYPE_ID,true).getEntities();
for(CustomerDictTypeEntity customerDictTypeEntity : customerDictTypeEntityList){
//redis存入对象
redisClient.set(customerDictTypeEntity,customerDictTypeEntity.getCustomerDictTypeId());
}
//redis取出对象
CustomerDictTypeEntity customerDictType = (CustomerDictTypeEntity) redisClient.get(customerDictTypeEntityList.get(0).getCustomerDictTypeId());
System.out.print(customerDictType.getTableName());
//redis存入对象集合
redisClient.setList((List<?>) customerDictTypeEntityList,"test");
//redis取出对象集合
List<CustomerDictTypeEntity> customerDictTypes = (List<CustomerDictTypeEntity>) redisClient.getList("test");
System.out.print(customerDictTypes.toString());
}
redisClient类代码(get\set方法):
package redisTest;
import db.CustomerDictTypeEntity;
import redis.clients.jedis.Jedis;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by dongzy on 2017/6/7.
*/
public class RedisClient {
private static Jedis redisClient;
private static int dbindex;
/**
* 有参构造器
* @param dbIndex
*/
public RedisClient(int dbIndex){
this.dbindex = dbIndex;
}
/**
* 无参构造器
*/
public RedisClient(){
this.dbindex = 0;
}
public static void set(Object object,String key)
{
try
{
redisClient = RedisClientPool.jedisPool.getResource();
redisClient.select(dbindex);
redisClient.set(key.getBytes(), SerializeUtil.serialize(object));
}
catch (Exception e)
{
// 销毁对象
RedisClientPool.jedisPool.returnBrokenResource(redisClient);
}
finally
{
// 还原到连接池
RedisClientPool.jedisPool.returnResource(redisClient);
}
}
public static void setList(List<?> object,String key)
{
try
{
redisClient = RedisClientPool.jedisPool.getResource();
redisClient.select(dbindex);
redisClient.set(key.getBytes(), SerializeUtil.serializeList(object));
}
catch (Exception e)
{
// 销毁对象
RedisClientPool.jedisPool.returnBrokenResource(redisClient);
}
finally
{
// 还原到连接池
RedisClientPool.jedisPool.returnResource(redisClient);
}
}
public static List<?> getList(String key)
{
List<Object> object = null;
try
{
redisClient = RedisClientPool.jedisPool.getResource();
redisClient.select(dbindex);
byte[] ob = redisClient.get(key.getBytes());
object = SerializeUtil.unserializeList(ob);
return object;
}
catch (Exception e)
{
// 销毁对象
RedisClientPool.jedisPool.returnBrokenResource(redisClient);
}
finally
{
// 还原到连接池
RedisClientPool.jedisPool.returnResource(redisClient);
}
return null;
}
public static Object get(String key)
{
Object object = null;
try
{
redisClient = RedisClientPool.jedisPool.getResource();
redisClient.select(dbindex);
byte[] ob = redisClient.get(key.getBytes());
object = SerializeUtil.unserialize(ob);
return object;
}
catch (Exception e)
{
// 销毁对象
RedisClientPool.jedisPool.returnBrokenResource(redisClient);
}
finally
{
// 还原到连接池
RedisClientPool.jedisPool.returnResource(redisClient);
}
return null;
}
/**
* 保存数据 类型为 Map
* <一句话功能简述>
* <功能详细描述>
* @param flag
* @param mapData
* @see [类、类#方法、类#成员]
*/
public static void setMapDataToRedis(String flag,Map<String,String> mapData)
{
try
{
redisClient = RedisClientPool.jedisPool.getResource();
redisClient.select(dbindex);
redisClient.hmset(flag,mapData);
}
catch (Exception e)
{
// 销毁对象
RedisClientPool.jedisPool.returnBrokenResource(redisClient);
}
finally
{
// 还原到连接池
RedisClientPool.jedisPool.returnResource(redisClient);
}
}
/**
* 保存数据 类型为 key-value
* <一句话功能简述>
* <功能详细描述>
* @param flag
* @param field
* @param value
* @see [类、类#方法、类#成员]
*/
public static void setDataToRedis(String flag,String field,String value)
{
try
{
redisClient = RedisClientPool.jedisPool.getResource();
redisClient.select(dbindex);
redisClient.hset(flag, field, value);
}
catch (Exception e)
{
// 销毁对象
RedisClientPool.jedisPool.returnBrokenResource(redisClient);
}
finally
{
// 还原到连接池
RedisClientPool.jedisPool.returnResource(redisClient);
}
}
/**
* 获取Map数据
* <一句话功能简述>
* <功能详细描述>
* @param flag
* @return
* @see [类、类#方法、类#成员]
*/
public static Map<String,String> getMapData(String flag)
{
Map<String,String> dataMap = null;
try
{
redisClient = RedisClientPool.jedisPool.getResource();
redisClient.select(dbindex);
dataMap = redisClient.hgetAll(flag);
}
catch (Exception e)
{
// 销毁对象
RedisClientPool.jedisPool.returnBrokenResource(redisClient);
}
finally
{
// 还原到连接池
RedisClientPool.jedisPool.returnResource(redisClient);
}
return dataMap;
}
public static long deleteData(String flag)
{
long result = 0;
try
{
redisClient = RedisClientPool.jedisPool.getResource();
redisClient.select(dbindex);
result = redisClient.del(flag);
}
catch (Exception e)
{
// 销毁对象
RedisClientPool.jedisPool.returnBrokenResource(redisClient);
}
finally
{
// 还原到连接池
RedisClientPool.jedisPool.returnResource(redisClient);
}
return result;
}
/**
* 根据key和字段获取数据
* <一句话功能简述>
* <功能详细描述>
* @param flag
* @param field
* @return
* @see [类、类#方法、类#成员]
*/
public static String getData(String flag,String field)
{
String data = null;
try
{
redisClient = RedisClientPool.jedisPool.getResource();
redisClient.select(dbindex);
data = redisClient.hget(flag, field);
}
catch (Exception e)
{
// 销毁对象
RedisClientPool.jedisPool.returnBrokenResource(redisClient);
}
finally
{
// 还原到连接池
RedisClientPool.jedisPool.returnResource(redisClient);
}
return data;
}
public static void main(String[] args) throws Exception
{
RedisClient.testMap();
}
public void testList()
{
Jedis redis = RedisClientPool.jedisPool.getResource();
//hset key field value将哈希表key中的域field的值设为value。
redis.hset("table", "field1", "value1");
redis.hset("table", "field2", "value2");
redis.hset("table", "field3", "value3");
//返回哈希表key中,一个或多个给定域的值。
List<String> list = redis.hmget("table","field1","field2","field3");
for(String tmp : list)
{
System.out.println(tmp);
}
}
public static void testMap()
{
//同时将多个field - value(域-值)对设置到哈希表key中。
Map<String,String> map = new ConcurrentHashMap<String,String>();
for (int i = 0;i < 10000;i++)
{
map.put("field"+i, "value"+i);
}
if (null != getData("table", "field1"))
{
deleteData("table");
}
//得到map下面的username的值
Map<String,String> maps = getMapData("table");
System.out.println(maps.size());
setMapDataToRedis("table",map);
//HGETALL key返回哈希表key中,所有的域和值。
maps = getMapData("table");
System.out.println(maps.size());
}
}
RedisClientPool类代码(获取redis连接):
package redisTest; /**
* Created by dongzy on 2017/6/7.
*/
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import util.PropertiesUtils;
import xmlTest.Dom4JTest;
import java.util.Map;
/**
* 取redis 连接池
* <一句话功能简述>
* <功能详细描述>
*
* @author khj
* @see [相关类/方法]
* @since [产品/模块版本]
*/
public class RedisClientPool
{
public static RedisClientPool redisClientPool = getInstance();
public static JedisPool jedisPool;
public static synchronized RedisClientPool getInstance()
{
if (null == redisClientPool)
{
redisClientPool = new RedisClientPool();
}
return redisClientPool;
}
public RedisClientPool()
{
if (null == jedisPool)
{
init();
}
}
/**
* 初始化Jedis
* <一句话功能简述>
* <功能详细描述>
* @return
* @see [类、类#方法、类#成员]
*/
private static JedisPoolConfig initPoolConfig()
{
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 控制一个pool最多有多少个状态为idle的jedis实例
jedisPoolConfig.setMaxIdle(1000);
// 最大能够保持空闲状态的对象数
jedisPoolConfig.setMaxIdle(300);
// 超时时间
jedisPoolConfig.setMaxWaitMillis(1000);
// 在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;
jedisPoolConfig.setTestOnBorrow(true);
// 在还会给pool时,是否提前进行validate操作
jedisPoolConfig.setTestOnReturn(true);
return jedisPoolConfig;
}
/**
* 初始化jedis连接池
*/
public static void init()
{
JedisPoolConfig jedisPoolConfig = initPoolConfig();
//PropertiesUtils工具类见附件一
String host = PropertiesUtils.getValue("redis.host");//"localhost";
int port = Integer.parseInt(PropertiesUtils.getValue("redis.port"));//6379;
int timeout = Integer.parseInt(PropertiesUtils.getValue("redis.timeout"));//60000;
/* Map map = Dom4JTest.getValue("share");
int port = (int) map.get("port");
int timeout = 60000;
String host = (String) map.get("host");*/
// int port = 6379;
// int timeout = 60000;
// String host = "172.16.8.32";
// 构造连接池
jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout);
}
}
SerializeUtil 类代码(对象、对象集合的序列化反序列化):
package redisTest;
import com.phhc.corewebservices.prescription.Exception_Exception;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* Created by dongzy on 2017/8/8.
*/
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();
oos.close();
baos.close();
return bytes;
} catch (Exception e) {
}
return null;
}
//序列化list对象
public static byte[] serializeList(List<?> list){
ObjectOutputStream oos = null;
ByteArrayOutputStream bos = null;
try {
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
for(Object object : list){
oos.writeObject(object);
}
oos.writeObject(null);
oos.close();
bos.close();
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//反序列化对象
public static Object unserialize( byte[] bytes) {
ByteArrayInputStream bais = null;
try {
// 反序列化
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
ois.close();
bais.close();
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//反序列化list对象
public static List<Object> unserializeList(byte[] bytes){
List<Object> list = new ArrayList<Object>();
ByteArrayInputStream bais = null;
try {
// 反序列化
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
if(bytes != null) {
bais = new ByteArrayInputStream(bytes);
ois = new ObjectInputStream(bais);
while (true) {
Object object = (Object) ois.readObject();
if (object == null) {
break;
} else {
list.add(object);
}
}
}
ois.close();
bais.close();
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
附件一:
文件读取PropertiesUtils类(RedisPool获取连接串使用):
package util;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
/**
* Created by dongzy on 2017/6/7.
*/
public class PropertiesUtils {
private static Properties properties = null;
static {
if(null == properties){
properties = new Properties();
InputStreamReader reader = null;
try{
reader = new InputStreamReader(PropertiesUtils.class.getClassLoader().getResourceAsStream("resources.properties"),"utf-8");
properties.load(reader);
reader.close();
}catch (Exception e){
e.printStackTrace();
}finally {
if(reader != null){
reader = null;
}
}
}
}
private PropertiesUtils(){}
public static String getValue(String key){
return properties.getProperty(key);
}
public static String getValue(){
SAXReader reader = new SAXReader();
try {
Document doc = reader.read(new File("F:\\svn\\RedisStudy\\src\\main\\resources\\redisconnection.xml"));
Element ele = doc.getRootElement();
Iterator it = ele.elementIterator();
while(it.hasNext()){
System.out.println(it.next());
}
} catch (DocumentException e) {
e.printStackTrace();
}
return null;
}
public static void main(String args[]) throws ParseException {
String a = null;
try {
if(a.equals("")){
System.out.println("null");
}
} catch (Exception e) {
e.printStackTrace();
}
String date = "1945/1/28 0:00:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
Date time = (Date) sdf.parseObject(date);
System.out.println(time);
//getValue();
}
}
附件二:
resources.properties
redis.host=172.16.8.32
redis.port=6379
redis.timeout=60000