Redis
1 redis介绍: redis是开源的 key-value形式存储数据,C语言编写的框架
特点 : 1 高性能:提供多种语言的API set效率 11万次/秒 get效率8.1万次/秒
2 数据完全存放在内存中,支持数据持久化
3 value 可以是字符串,hash(map) 列表list 集合(set) 有序集合(sorted set)
2 适用场景 《1》缓存 《2》消息队列
3 命令 :
1 list
llen keyList :获取keyList的长度大小 lpop keyList:取出并移除keyList第一个元素,左边的元素 rpop keyList:取出并移除keyList最后一个元素,右边的元素 LINDEX key index:获取该索引下的元素。 lrem key count value:删除count个value。(count为正数,从头开始,删除count个value元素;count为负,则从尾部向头删除|count|个value元素;count为0,则所有的元素为value的都删除) LSET key index value:设置索引为index下的元素为value.超出索引范围报错。 LTRIM key start end:清空索引在start 和end之外的元素,索引从0开始,两端保留,两端之外的清空。 RPOPLPUSH srckey dstkey:源队列srckey,目标队列dstkey,将srckey的最后一个移除,并放到dstkey的第一个。
2 set
sadd key value : 向set添加元素
srem key value :从set中移除元素
smembers key : 取出所有set元素
SISMEMBER key value: 查看value是否存在set中
SUNION key1 key2 ... keyN:将所有key合并后取出来,相同的值只取一次
scard key : 获取set中元素的个数
SRANDMEMBER key: Return a random element from a Set, without removing the element.随机取出一个
SDIFF key1 key2 ... keyN:获取第一set中不存在后面几个set里的元素。
SDIFFSTORE dstkey key1 key2 ... keyN:和sdiff相同,获取key1中不存在其他key里的元素,但要存储到dstkey中。
SINTER key1 key2 ... keyN:取出这些set的交集
SINTERSTORE dstkey key1 key2 ... keyN:取出这些key的交集并存储到dstkey
SMOVE srckey dstkey member:将元素member从srckey中转移到dstkey中,这个操作是原子的。
Redis整合Spring 单击版
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 整合单机版redis -->
<!-- 创建jedisPoolConfig配置对象 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="20"></property>
<property name="maxIdle" value="2"></property>
</bean>
<!-- 创建jedisPool连接单机版redis -->
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg>
<constructor-arg name="host" value="127.0.0.1"></constructor-arg>
<constructor-arg name="port" value="6379"></constructor-arg>
</bean>
</beans>
在远程服务上执行命令 $ redis-cli -h host -p port -a password
Redis 操作对象:(要求对象必须要序列化)
1 创建对象序列化工具:
/**
* 序列化就是将一个对象转换为二进制的数据流。这样就可以进行传输,或者保存到文件中。如果一个类的对象要想实现序列化,就必须实现serializable接口。在此接口中没有任何的方法,此接口只是作为一个标识,表示本类的对象具备了序列化的能力而已。
* 反序列化:将二进制数据流转换成相应的对象。
* 如果想要完成对象的序列化,则还要依靠ObjectOutputStream和ObjectInputStream,前者属于序列化操作,而后者属于反序列化操作。
*
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class SerializationUtil {
/**
* 序列化
*
* @param object
* @return
*/
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;
}
/**
* 反序列化
*
* @param bytes
* @return
*/
public static Object deserialize(byte[] bytes) {
ByteArrayInputStream bais = null;
try {
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
}
return null;
}
}
测试:
// 存入一个 user对象 jedis.set("user".getBytes(), SerializationUtil.serialize(user)); // 获取 byte[] bs = jedis.get("user".getBytes()); User desUser = (User) SerializationUtil.deserialize(bs); System.out.println(desUser.getId() + ":" + desUser.getName());
使用fastjson将对象转为json字符串后存储
public class RedisOps { public static void setJsonString(String key,Object object){ Jedis jedis = RedisConnection.getJedis(); jedis.set(key, JSON.toJSONString(object)); jedis.close(); } public static Object getJsonObject(String key,Class clazz){ Jedis jedis = RedisConnection.getJedis(); String value = jedis.get(key); jedis.close(); return JSON.parseObject(value,clazz); } }
2 List<User> userList (对象集合)在缓存中的存储和获取。
将List<User> userList转成字节数组 方便加入缓存中
private static byte[] cacheUserList(List<User> userList) {
if (userList.isEmpty()) {
throw new NullPointerException("Can't serialize null");
}
byte[] value = null;
ByteArrayOutputStream bos = null;
ObjectOutputStream os = null;
try {
bos = new ByteArrayOutputStream();
os = new ObjectOutputStream(bos);
for (User user : userList) {
os.writeObject(user);
}
os.writeObject(null);
bos.close();
os.close();
value = bos.toByteArray();
} catch (Exception e) {
throw new IllegalArgumentException("Non-serializable object", e);
}
return value;
}
将字节数组转成相应的list<User>
private static List<User> getUserCache(byte[] in) {
List<User> userList = new ArrayList<User>();
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
if (in != null) {
bis = new ByteArrayInputStream(in);
ois = new ObjectInputStream(bis);
while (true) {
User user = (User) ois.readObject();
if (user == null) {
break;
} else {
userList.add(user);
}
}
}
bis.close();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return userList;
}
测试:
//将userList加入缓存
redis.set("Key".getBytes(), cacheUserList(userList));
//获取缓存中userList数据
byte[] in = jedis.get("Key".getBytes());
List<User> userArr = getUserCache(in);
3 RedisUtil工具类
package com.utils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisUtil {
/*构造函数私有化 防止别人new*/
private RedisUtil(){};
private static String host="localhost";
private static int port=6379;
private static int timeout=10000;
private static JedisPool jedis=null;
private static JedisPoolConfig jedisPoolConfig=null;
/*连接池中创建连接*/
static{
jedisPoolConfig=new JedisPoolConfig();
/*最大连接数*/
jedisPoolConfig.setMaxTotal(1024);
/*最大空闲实例数*/
jedisPoolConfig.setMaxIdle(200);
/*等待连接池给链接的最大时间 毫秒*/
jedisPoolConfig.setMaxWaitMillis(10000);
/*在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;*/
jedisPoolConfig.setTestOnBorrow(true);
jedis=new JedisPool(jedisPoolConfig, host, port, timeout);
}
public synchronized static Jedis getRedis(){
if(jedis!=null){
return jedis.getResource();
}
else{
return new JedisPool(jedisPoolConfig, host, port, timeout).getResource();
}
}
public static void closeRedis(final Jedis jedis){
if(jedis!=null){
jedis.close();
}
}
// 存对象
public static void setObject(Jedis jedis, String key, Object obj) throws Exception {
ObjectOutputStream oos = null; //对象输出流
ByteArrayOutputStream bos = null; //内存缓冲流
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
byte[] byt = bos.toByteArray();
jedis.set(key.getBytes(), byt);
bos.close();
oos.close();
}
// 取对象
public static Object getObject(Jedis jedis, String key) throws Exception {
byte[] byt = jedis.get(key.getBytes());
ObjectInputStream ois = null; //对象输入流
ByteArrayInputStream bis = null; //内存缓冲流
Object obj = null;
bis = new ByteArrayInputStream(byt);
ois = new ObjectInputStream(bis);
obj = ois.readObject();
bis.close();
ois.close();
return obj;
}
}
4 在创建的RedisUtil工具类中添加方法
// 存对象
public static void setObject(Jedis jedis, String key, Object obj) throws Exception {
ObjectOutputStream oos = null; //对象输出流
ByteArrayOutputStream bos = null; //内存缓冲流
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
byte[] byt = bos.toByteArray();
jedis.set(key.getBytes(), byt);
bos.close();
oos.close();
}
// 取对象
public static Object getObject(Jedis jedis, String key) throws Exception {
byte[] byt = jedis.get(key.getBytes());
ObjectInputStream ois = null; //对象输入流
ByteArrayInputStream bis = null; //内存缓冲流
Object obj = null;
bis = new ByteArrayInputStream(byt);
ois = new ObjectInputStream(bis);
obj = ois.readObject();
bis.close();
ois.close();
return obj;
}
测试:
RedisUtil.setObject(RedisUtil.getRedis(), "ddd", user);
User ui=(User) RedisUtil.getObject(RedisUtil.getRedis(), "ddd");
redis的map,list set,string的用法
/**
* 操作普通键值对
*/
@Test
public void test01(){
//存入1个key=name value=hello的键值对
jedis.set("name", "hello");
String value = jedis.get("name"); //获取key=name的值
System.out.println(value);
jedis.del("name");
value = jedis.get("name"); //获取key=name的值
System.out.println(value);
}
/**
* 操作List
*/
@Test
public void test02(){
//将zhoufeng 加入students数组的开头,如果该元素是第一个元素,那么会自动创建students数组
jedis.rpush("students", "first");
//将zhangsan加入到students的末尾
jedis.lpush("students", "end");
//移除students的第一个元素
jedis.lpop("students");
//移除students的最后一个元素
jedis.rpop("students");
//移除制定的元素,第二个参数表示要移除的个数,因为list中是允许出现重复元素的
jedis.lrem("student", 1, "first") ;
//获取students数组的所有元素
List <String> students = jedis.lrange("students", 0, -1) ;
System.out.println(students);
}
/**
* 操作Set
*/
@Test
public void test03(){
//添加元素
jedis.sadd("teachers", "zhangsan");
jedis.sadd("teachers", "lisi","hello");
jedis.sadd("teachers", "wangwu");
//判断Set是否包含制定元素
Boolean b1 = jedis.sismember("teachers", "wangwu");
Boolean b2 = jedis.sismember("teachers", "xxxxx");
System.out.println(b1 + " " + b2);
//获取Set内所有的元素
Set<String> members = jedis.smembers("teachers");
Iterator<String> it = members.iterator() ;
while(it.hasNext()){
System.out.println(it.next());
}
// jedis.sunion(keys...) 可以将多个Set合并成1个并返回合并后的Set
}
/**
* 操作带排序功能的Set
*/
@Test
public void test04(){
//添加元素,会根据第二个参数排序
jedis.zadd("emps", 5 , "aaa") ;
jedis.zadd("emps", 1 , "bbbb") ;
jedis.zadd("emps", 3 , "ccc") ;
jedis.zadd("emps", 2 , "ddd") ;
//获取所有元素
Set<String> emps = jedis.zrange("emps", 0, -1) ;
Iterator<String> it = emps.iterator() ;
while(it.hasNext()){
System.out.println(it.next());
}
}
/**
* 存入对象,使用Map作为对象
*/
@Test
public void test05(){
Map<String , String > car = new HashMap<String , String >() ;
car.put("COLOR", "red") ;
car.put("SIZE", "2T");
car.put("NO", "8888");
jedis.hmset("car", car);
//获取整个对象
Map<String, String> result = jedis.hgetAll("car");
Iterator<Entry<String, String>> it = result.entrySet().iterator();
while(it.hasNext()){
Entry<String, String> entry = it.next() ;
System.out.println("key:" + entry.getKey() + " value:" + entry.getValue());
}
//也可以获取制定的属性
String no = jedis.hget("car", "NO") ;
System.out.println("NO:" + no);
}
redis通常在业务层处理缓存 实例代码如下:
public JSONObject selectByExample(Long id){
User user=new User();
//user=userMapper.selectByPrimaryKey(id);
String us=RedisUtil.getRedis().get("user");
Map<String, String> hash=new HashMap<String, String>();
// hash= (Map<String, String>)JSON.parse("dd");
System.out.println(us);
if(us!=null){
return JSON.parseObject(us);
}
else{
user=userMapper.selectByPrimaryKey(id);
String userString=JSON.toJSONString(user);
RedisUtil.getRedis().set("user", userString);
return JSON.parseObject(userString);
}
}