Redis 客户端

一、客户端简介

1.1 jedis

        以 Redis 命令作为方法名称,学习成本低,简单实用。但是 Jedis 实例是线程不安全的,多线程环境下需要基于连接池来使用。

1.2 lettuce

        Lettuce 是基于 Netty 实现的,支持同步、异步和响应式编程方式,并且是线程安全的。支持 Redis 的哨兵模式、集群模式和管道模式。

1.3 Redisson

        Redisson 是一个基于 Redis 实现的分布式、可伸缩的 Java 数据结构集合。包含了诸如 MapQueueLockSemaphoreAtomicLong 等强大功能。

1.4 Spring Data Redis

        Spring Data Redis 的底层可以兼容 jedis lettuceSpring Data Redis 定义了一套 api,底层既可以用 jedis 实现,又可以使用 letture 实现。

二、Jedis

2.1 简介

        Jedis Redis 官方推荐的 Java 连接开发工具。要在 Java 开发中使用好 Redis 中间件,必须对 Jedis 熟悉才能写出漂亮的代码。

2.2 案例演示

2.2.1 新建 Maven 项目

2.2.2 导入依赖

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.2.0</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.58</version>
</dependency>

2.2.3 编写测试代码

public class App {
	public static void main( String[] args ){
		Jedis jedis = new Jedis("127.0.0.1",6379);
		System.out.println("连接成功");
		// 查看服务是否正在运行
		System.out.println("服务正在运行:"+jedis.ping());
	}
}

2.2.4 测试

2.3 常用 API

2.3.1 基本操作

public static void main( String[] args ){
		Jedis jedis = new Jedis("127.0.0.1", 6379);
	
		// 验证密码,如果没有设置密码这段代码省略
		// jedis.auth("password");
		
		// 连接
		jedis.connect();
		
		// 断开连接
		jedis.disconnect(); 
		
		// 清空所有的key
		jedis.flushAll(); 
	}

2.3.2 操作 key

	public static void main( String[] args ){
		Jedis jedis = new Jedis("127.0.0.1", 6379);
		System.out.println("清空数据:"+jedis.flushDB());
		System.out.println("判断某个键是否存在:"+jedis.exists("username"));
		System.out.println("新增<'username','kuangshen'>的键值对:"+jedis.set("username", "xhf"));
		System.out.println("新增<'password','password'>的键值对:"+jedis.set("password", "password"));
		System.out.print("系统中所有的键如下:");
		Set<String> keys = jedis.keys("*");
		System.out.println(keys);
		System.out.println("删除键password:"+jedis.del("password"));
		System.out.println("判断键password是否存在:"+jedis.exists("password"));
		System.out.println("查看键username所存储的值的类型:"+jedis.type("username"));
		System.out.println("随机返回key空间的一个:"+jedis.randomKey());
		System.out.println("重命名key:"+jedis.rename("username","name"));
		System.out.println("取出改后的name:"+jedis.get("name"));
		System.out.println("按索引查询:"+jedis.select(0));
		System.out.println("删除当前选择数据库中的所有key:"+jedis.flushDB());
		System.out.println("返回当前数据库中key的数目:"+jedis.dbSize());
		System.out.println("删除所有数据库中的所有key:"+jedis.flushAll());
	}

2.3.3 操作 String

public static void main(String[] args) {
		Jedis jedis = new Jedis("127.0.0.1", 6379);
		jedis.flushDB();
		System.out.println("===========增加数据===========");
		System.out.println(jedis.set("key1","value1"));
		System.out.println(jedis.set("key2","value2"));
		System.out.println(jedis.set("key3", "value3"));
		System.out.println("删除键key2:"+jedis.del("key2"));
		System.out.println("获取键key2:"+jedis.get("key2"));
		System.out.println("修改key1:"+jedis.set("key1", "value1Changed"));
		System.out.println("获取key1的值:"+jedis.get("key1"));
		System.out.println("在key3后面加入值:"+jedis.append("key3", "End"));
		System.out.println("key3的值:"+jedis.get("key3"));
		System.out.println("增加多个键值对:"+jedis.mset("key01","value01","key02","value02","key03","value03"));
		System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03"));
		System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03","key04"));
		System.out.println("删除多个键值对:"+jedis.del("key01","key02"));
		System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03"));
		jedis.flushDB();
		System.out.println("===========新增键值对防止覆盖原先值==============");
		System.out.println(jedis.setnx("key1", "value1"));
		System.out.println(jedis.setnx("key2", "value2"));
		System.out.println(jedis.setnx("key2", "value2-new"));
		System.out.println(jedis.get("key1"));
		System.out.println(jedis.get("key2"));
		System.out.println("===========新增键值对并设置有效时间=============");
		System.out.println(jedis.setex("key3", 2, "value3"));
		System.out.println(jedis.get("key3"));
		try {
			TimeUnit.SECONDS.sleep(3);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(jedis.get("key3"));
		System.out.println("===========获取原值,更新为新值==========");
		System.out.println(jedis.getSet("key2", "key2GetSet"));
		System.out.println(jedis.get("key2"));
		System.out.println("获得key2的值的字串:"+jedis.getrange("key2", 2,4));
	}

2.3.4 操作 List

public static void main(String[] args) {
		Jedis jedis = new Jedis("127.0.0.1", 6379);
		jedis.flushDB();
		System.out.println("===========添加一个list===========");
		jedis.lpush("collections", "ArrayList", "Vector", "Stack","HashMap", "WeakHashMap", "LinkedHashMap");
		jedis.lpush("collections", "HashSet");
		jedis.lpush("collections", "TreeSet");
		jedis.lpush("collections", "TreeMap");
		// -1代表倒数第一个元素,-2代表倒数第二个元素,end为-1表示查询全部
		System.out.println("collections的内容:"+jedis.lrange("collections",0, -1));
		System.out.println("collections区间0-3的元素:"+jedis.lrange("collections",0,3));
		System.out.println("===============================");
		// 删除列表指定的值 ,第二个参数为删除的个数(有重复时),后add进去的值先被删,类似于出栈
		System.out.println("删除指定元素个数:"+jedis.lrem("collections", 2,"HashMap"));
		System.out.println("collections的内容:"+jedis.lrange("collections",0, -1));
		System.out.println("删除下表0-3区间之外的元素:"+jedis.ltrim("collections", 0, 3));
		System.out.println("collections的内容:"+jedis.lrange("collections",0, -1));
		System.out.println("collections列表出栈(左端):"+jedis.lpop("collections"));
		System.out.println("collections的内容:"+jedis.lrange("collections",0, -1));
		System.out.println("collections添加元素,从列表右端,与lpush相对应:"+jedis.rpush("collections", "EnumMap"));
		System.out.println("collections的内容:"+jedis.lrange("collections",0, -1));
		System.out.println("collections列表出栈(右端):"+jedis.rpop("collections"));
		System.out.println("collections的内容:"+jedis.lrange("collections",0, -1));
		System.out.println("修改collections指定下标1的内容:"+jedis.lset("collections", 1, "LinkedArrayList"));
		System.out.println("collections的内容:"+jedis.lrange("collections",0, -1));
		System.out.println("===============================");
		System.out.println("collections的长度:"+jedis.llen("collections"));
		System.out.println("获取collections下标为2的元素:"+jedis.lindex("collections", 2));
		System.out.println("===============================");
		jedis.lpush("sortedList", "3","6","2","0","7","4");
		System.out.println("sortedList排序前:"+jedis.lrange("sortedList", 0,-1));
		System.out.println(jedis.sort("sortedList"));
		System.out.println("sortedList排序后:"+jedis.lrange("sortedList", 0,-1));
	}

2.3.5 操作 Set

public static void main(String[] args) {
		Jedis jedis = new Jedis("127.0.0.1", 6379);
		jedis.flushDB();
		System.out.println("============向集合中添加元素(不重复)============");
		System.out.println(jedis.sadd("eleSet","e1","e2","e4","e3","e0","e8","e7","e5"));
		System.out.println(jedis.sadd("eleSet", "e6"));
		System.out.println(jedis.sadd("eleSet", "e6"));
		System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
		System.out.println("删除一个元素e0:"+jedis.srem("eleSet", "e0"));

		System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
		System.out.println("删除两个元素e7和e6:"+jedis.srem("eleSet","e7","e6"));
		System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
		System.out.println("随机的移除集合中的一个元素:"+jedis.spop("eleSet"));
		System.out.println("随机的移除集合中的一个元素:"+jedis.spop("eleSet"));
		System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
		System.out.println("eleSet中包含元素的个数:"+jedis.scard("eleSet"));
		System.out.println("e3是否在eleSet中:"+jedis.sismember("eleSet","e3"));
		System.out.println("e1是否在eleSet中:"+jedis.sismember("eleSet","e1"));
		System.out.println("e1是否在eleSet中:"+jedis.sismember("eleSet","e5"));
		System.out.println("=================================");
		System.out.println(jedis.sadd("eleSet1","e1","e2","e4","e3","e0","e8","e7","e5"));
		System.out.println(jedis.sadd("eleSet2","e1","e2","e4","e3","e0","e8"));
		System.out.println("将eleSet1中删除e1并存入eleSet3中:"+jedis.smove("eleSet1", "eleSet3", "e1"));//移到集合元素
		System.out.println("将eleSet1中删除e2并存入eleSet3中:"+jedis.smove("eleSet1", "eleSet3", "e2"));
		System.out.println("eleSet1中的元素:"+jedis.smembers("eleSet1"));
		System.out.println("eleSet3中的元素:"+jedis.smembers("eleSet3"));
		System.out.println("============集合运算=================");
		System.out.println("eleSet1中的元素:"+jedis.smembers("eleSet1"));
		System.out.println("eleSet2中的元素:"+jedis.smembers("eleSet2"));
		System.out.println("eleSet1和eleSet2的交集:"+jedis.sinter("eleSet1","eleSet2"));
		System.out.println("eleSet1和eleSet2的并集:"+jedis.sunion("eleSet1","eleSet2"));
		System.out.println("eleSet1和eleSet2的差集:"+jedis.sdiff("eleSet1","eleSet2"));//eleSet1中有,eleSet2中没有
		jedis.sinterstore("eleSet4","eleSet1","eleSet2");

		// 求交集并将交集保存到 dstkey 的集合		
		System.out.println("eleSet4中的元素:"+jedis.smembers("eleSet4"));
	}

2.3.6 操作 Hash

public static void main(String[] args) {
		Jedis jedis = new Jedis("127.0.0.1", 6379);
		jedis.flushDB();
		Map<String,String> map = new HashMap<String,String>();
		map.put("key1","value1");
		map.put("key2","value2");
		map.put("key3","value3");
		map.put("key4","value4");
		
		// 添加名称为hash(key)的hash元素
		jedis.hmset("hash",map);
		
		// 向名称为hash的hash中添加key为key5,value为value5元素
		jedis.hset("hash", "key5", "value5");
		
		// return Map<String,String>
		System.out.println("散列hash的所有键值对为:"+jedis.hgetAll("hash"));

		// return Set<String>
		System.out.println("散列hash的所有键为:"+jedis.hkeys("hash"));
		
		// return List<String>
		System.out.println("散列hash的所有值为:"+jedis.hvals("hash"));
		System.out.println("将key6保存的值加上一个整数,如果key6不存在则添加key6:"+jedis.hincrBy("hash", "key6", 6));
		System.out.println("散列hash的所有键值对为:"+jedis.hgetAll("hash"));
		System.out.println("将key6保存的值加上一个整数,如果key6不存在则添加key6:"+jedis.hincrBy("hash", "key6", 3));
		System.out.println("散列hash的所有键值对为:"+jedis.hgetAll("hash"));
		System.out.println("删除一个或者多个键值对:"+jedis.hdel("hash","key2"));
		System.out.println("散列hash的所有键值对为:"+jedis.hgetAll("hash"));
		System.out.println("散列hash中键值对的个数:"+jedis.hlen("hash"));
		System.out.println("判断hash中是否存在key2:"+jedis.hexists("hash","key2"));
		System.out.println("判断hash中是否存在key3:"+jedis.hexists("hash","key3"));
		System.out.println("获取hash中的值:"+jedis.hmget("hash","key3"));
		System.out.println("获取hash中的值:"+jedis.hmget("hash","key3","key4"));
	}

2.3.7 操作事务

public static void main(String[] args) {
		
		// 创建客户端连接服务端,redis服务端需要被开启
		Jedis jedis = new Jedis("127.0.0.1", 6379);
		jedis.flushDB();
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("hello", "world");
		jsonObject.put("name", "java");
		
		// 开启事务
		Transaction multi = jedis.multi();
		String result = jsonObject.toJSONString();
		try{
			// 向redis存入一条数据
			multi.set("json", result);
			
			// 再存入一条数据
			multi.set("json2", result);
			
			// 这里引发了异常,用0作为被除数
			int i = 100/0;
			
			// 如果没有引发异常,执行进入队列的命令
			multi.exec();
		}catch(Exception e){
			e.printStackTrace();
			
			// 如果出现异常,回滚
			multi.discard();
		}finally{
			System.out.println(jedis.get("json"));
			System.out.println(jedis.get("json2"));
			
			// 最终关闭客户端
			jedis.close();
		}
	}

2.4 Jedis 连接池

        Jedis 本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此我们推荐大家使用 Jedis 连接池代替 Jedis 的直连方式,代码如下:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisConnectionFactory {
    private static final JedisPool jedisPool;

    static {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最大连接
        jedisPoolConfig.setMaxTotal(8);
        // 最大空闲连接
        jedisPoolConfig.setMaxIdle(8);
        // 最小空闲连接
        jedisPoolConfig.setMinIdle(0);
        // 设置最长等待时间, ms
        jedisPoolConfig.setMaxWaitMillis(200);
        jedisPool = new JedisPool(jedisPoolConfig, "192.168.150.101", 6379, 1000, "123321");
    }

    // 获取Jedis对象
    public static Jedis getJedis() {
        return jedisPool.getResource();
    }
}

三、SpringDataRedis

3.1 简介

        SpringData Spring 中数据操作的模块,包含对各种数据库的集成,其中对 Redis 的集成模块就叫做 SpringDataRedis,其特点如下:

        1、提供了对不同 Redis 客户端的整合(Lettuce Jedis

        2、提供了 RedisTemplate 统一 API 来操作 Redis

        3、支持 Redis 的发布订阅模型

        4、支持 Redis 哨兵和 Redis 集群

        5、支持基于 Lettuce 的响应式编程

        6、支持基于JDKJSON、字符串、Spring 对象的数据序列化及反序列化

        7、支持基于 RedisJDKCollection 实现

3.2 快速入门

        SpringDataRedis 中提供了 RedisTemplate 工具类,其中封装了各种对 Redis 的操作。并且将不同数据类型的操作 API 封装到了不同的类型中,如下:

API返回值类型说明
redisTemplate.opsForValue()ValueOperations操作 String 类型数据
redisTemplate.opsForHash()HashOperations操作 Hash 类型数据
redisTemplate.opsForList()ListOperations操作 List 类型数据
redisTemplate.opsForSet()SetOperations操作 Set 类型数据
redisTemplate.opsForZSet()ZSetOperations操作 ZSet 类型数据
redisTemplate通用的命令

3.3 入门案例

3.3.1 添加 maven 依赖

<!-- 引入 redis 依赖-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-pool2</artifactId>
</dependency>

3.3.2 配置 redis 

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: 123456
    lettuce:         # 默认使用 lettuce 连接池
      pool:
        max-active: 8 # 最大连接
        min-idle: 0 # 最小空闲连接
        max-idle: 8  # 最大空闲连接
        max-wait: 100 # 连接等待时间

3.3.3 测试

@SpringBootTest
class RedisApplicationTests {

    @Autowired
    RedisTemplate redisTemplate;
    @Test
    void contextLoads() {

        // 插入一条 string 类型数据
        redisTemplate.opsForValue().set("name", "张三");
        // 读取一条string类型数据
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name="+name);
    }

}

3.4 序列化方式

        打开 RedisDesktopManager 软件,查看我们上一小节创建的 key value,如下图:

        RedisTemplate 可以接收任意 Object 作为值写入 Redis,只不过写入前会把 Object 序列化为字节形式,默认是采用 JDK 序列化,得到的结果就是上面的这个样子。其缺点就是可读性差、内存占用较大。

        为了解决上面出现的问题,我们可以自定义 RedisTemplate 的序列化方式,代码如下:

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        // 创建Template
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 设置序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // key和 hashKey 采用 string 序列化
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        // value和 hashValue采用 JSON序列化
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);
        return redisTemplate;
    }

}

         再次执行 3.3.3 小节的测试代码,可以看到,可以正常的显示相应的 key value 值了,如下图:

@SpringBootTest
class RedisApplicationTests {

    @Autowired
    RedisTemplate<String,Object> redisTemplate;
    @Test
    void contextLoads() {

        // 插入一条 string 类型数据
        redisTemplate.opsForValue().set("name", "张三");
        // 读取一条string类型数据
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name="+name);
    }

}

         接下来测试下存储对象,代码如下:

    @Test
    void testUser() {

        // 插入对象
        redisTemplate.opsForValue().set("user:100", new User("张三","21"));
        // 读取对象
        Object user = redisTemplate.opsForValue().get("user:100");
        System.out.println("user="+user);
    }

        redis 自动化的把我们的对象转换成了 json 格式,并且当我们自动获取对象的时候还能够反序列化成一个对象。 

        帮我们序列化的同时,还给我们写入了一个 @Class 属性,正是因为有这个字节码的路径才可以反序列的时候帮我们找到对应的对象。

3.5 StringRedisTemplate

        尽管 JSON 的序列化方式可以满足我们的需求,但依然存在一些问题,如图:

        为了在反序列化时知道对象的类型,JSON 序列化器会将类的 class 类型写入 json 结果中,存入 Redis,会带来额外的内存开销。

        为了节省内存空间,我们并不会使用 JSON 序列化器来处理 value,而是统一使用 String 序列化器,要求只能存储 String 类型的 key value。当需要存储 Java 对象时,手动完成对象的序列化和反序列化。如下图:

        Spring 默认提供了一个 StringRedisTemplate 类,它的 key value 的序列化方式默认就是 String 方式。省去了我们自定义 RedisTemplate 的过程,接下来编写测试代码,如下:

@SpringBootTest
class JedisApplicationTests {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

	// JSON工具
    private static final ObjectMapper mapper = new ObjectMapper();

    @Test
    void testStringTemplate() throws IOException {
        // 准备对象
        User user = new User("虎哥", "18");
        // 手动序列化
        String json = mapper.writeValueAsString(user);
        // 写入一条数据到redis
        stringRedisTemplate.opsForValue().set("user:200", json);
        // 读取数据
        String val = stringRedisTemplate.opsForValue().get("user:200");
        // 反序列化
        User user1 = mapper.readValue(val, User.class);
        System.out.println("user1 = " + user1);
    }
}

3.6 小节

        RedisTemplate 的两种序列化实践方案:

        方案一:

    1、自定义 RedisTemplate

    2、修改 RedisTemplate 的序列化器为 GenericJackson2JsonRedisSerializer

        方案二:

1、使用 StringRedisTemplate

2、写入 Redis 时,手动把对象序列化为 JSON
 
3、读取 Redis 时,手动把读取到的 JSON 反序列化为对象

3.7 redis 工具类

@Component
public class RedisUtil {

	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	// =============================common============================
	/**
	 * 指定缓存失效时间
	 * @param key 键
	 * @param time 时间(秒)
	 */
	public boolean expire(String key, long time) {
		try {
			if (time > 0) {
				redisTemplate.expire(key, time, TimeUnit.SECONDS);
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 根据key 获取过期时间
	 * @param key 键 不能为null
	 * @return 时间(秒) 返回0代表为永久有效
	 */
	public long getExpire(String key) {
		return redisTemplate.getExpire(key, TimeUnit.SECONDS);
	}
	/**
	 * 判断key是否存在
	 * @param key 键
	 * @return true 存在 false不存在
	 */
	public boolean hasKey(String key) {
		try {
			return redisTemplate.hasKey(key);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 删除缓存
	 * @param key 可以传一个值 或多个
	 */
	@SuppressWarnings("unchecked")
	public void del(String... key) {
		if (key != null && key.length > 0) {
			if (key.length == 1) {
				redisTemplate.delete(key[0]);
			} else {
				redisTemplate.delete(CollectionUtils.arrayToList(key));
			}
		}
	}
	// ============================String=============================
	/**
	 * 普通缓存获取
	 * @param key 键
	 * @return 值
	 */
	public Object get(String key) {
		return key == null ? null : redisTemplate.opsForValue().get(key);
	}
	/**
	 * 普通缓存放入
	 * @param key 键
	 * @param value 值
	 * @return true成功 false失败
	 */
	public boolean set(String key, Object value) {
		try {
			redisTemplate.opsForValue().set(key, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 普通缓存放入并设置时间
	 * @param key 键
	 * @param value 值
	 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
	 * @return true成功 false 失败
	 */
	public boolean set(String key, Object value, long time) {
		try {
			if (time > 0) {
				redisTemplate.opsForValue().set(key, value, time,
						TimeUnit.SECONDS);
			} else {
				set(key, value);
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 递增
	 * @param key 键
	 * @param delta 要增加几(大于0)
	 */
	public long incr(String key, long delta) {
		if (delta < 0) {
			throw new RuntimeException("递增因子必须大于0");
		}
		return redisTemplate.opsForValue().increment(key, delta);
	}
	/**
	 * 递减
	 * @param key 键
	 * @param delta 要减少几(小于0)
	 */
	public long decr(String key, long delta) {
		if (delta < 0) {
			throw new RuntimeException("递减因子必须大于0");
		}
		return redisTemplate.opsForValue().increment(key, -delta);
	}
	// ================================Map=================================
	/**
	 * HashGet
	 * @param key 键 不能为null
	 * @param item 项 不能为null
	 */
	public Object hget(String key, String item) {
		return redisTemplate.opsForHash().get(key, item);
	}
	/**
	 * 获取hashKey对应的所有键值
	 * @param key 键
	 * @return 对应的多个键值
	 */
	public Map<Object, Object> hmget(String key) {
		return redisTemplate.opsForHash().entries(key);
	}
	/**
	 * HashSet
	 * @param key 键
	 * @param map 对应多个键值
	 */
	public boolean hmset(String key, Map<String, Object> map) {
		try {
			redisTemplate.opsForHash().putAll(key, map);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * HashSet 并设置时间
	 * @param key 键
	 * @param map 对应多个键值
	 * @param time 时间(秒)
	 * @return true成功 false失败
	 */
	public boolean hmset(String key, Map<String, Object> map, long time) {
		try {
			redisTemplate.opsForHash().putAll(key, map);
			if (time > 0) {
				expire(key, time);
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 向一张hash表中放入数据,如果不存在将创建
	 *
	 * @param key 键
	 * @param item 项
	 * @param value 值
	 * @return true 成功 false失败
	 */
	public boolean hset(String key, String item, Object value) {
		try {
			redisTemplate.opsForHash().put(key, item, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 向一张hash表中放入数据,如果不存在将创建
	 *
	 * @param key 键
	 * @param item 项
	 * @param value 值
	 * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
	 * @return true 成功 false失败
	 */
	public boolean hset(String key, String item, Object value, long time) {
		try {
			redisTemplate.opsForHash().put(key, item, value);
			if (time > 0) {
				expire(key, time);
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 删除hash表中的值
	 *
	 * @param key 键 不能为null
	 * @param item 项 可以使多个 不能为null
	 */
	public void hdel(String key, Object... item) {
		redisTemplate.opsForHash().delete(key, item);
	}
	/**
	 * 判断hash表中是否有该项的值
	 *
	 * @param key 键 不能为null
	 * @param item 项 不能为null
	 * @return true 存在 false不存在
	 */
	public boolean hHasKey(String key, String item) {
		return redisTemplate.opsForHash().hasKey(key, item);
	}
	/**
	 * hash递增 如果不存在,就会创建一个 并把新增后的值返回
	 *
	 * @param key 键
	 * @param item 项
	 * @param by 要增加几(大于0)
	 */
	public double hincr(String key, String item, double by) {
		return redisTemplate.opsForHash().increment(key, item, by);
	}
	/**
	 * hash递减
	 *
	 * @param key 键
	 * @param item 项
	 * @param by 要减少记(小于0)
	 */
	public double hdecr(String key, String item, double by) {
		return redisTemplate.opsForHash().increment(key, item, -by);
	}

	// ============================set=============================
	/**
	 * 根据key获取Set中的所有值
	 * @param key 键
	 */
	public Set<Object> sGet(String key) {
		try {
			return redisTemplate.opsForSet().members(key);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * 根据value从一个set中查询,是否存在
	 *
	 * @param key 键
	 * @param value 值
	 * @return true 存在 false不存在
	 */
	public boolean sHasKey(String key, Object value) {
		try {
			return redisTemplate.opsForSet().isMember(key, value);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 将数据放入set缓存
	 *
	 * @param key 键
	 * @param values 值 可以是多个
	 * @return 成功个数
	 */
	public long sSet(String key, Object... values) {
		try {
			return redisTemplate.opsForSet().add(key, values);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	/**
	 * 将set数据放入缓存
	 *
	 * @param key 键
	 * @param time 时间(秒)
	 * @param values 值 可以是多个
	 * @return 成功个数
	 */
	public long sSetAndTime(String key, long time, Object... values) {
		try {
			Long count = redisTemplate.opsForSet().add(key, values);
			if (time > 0)
				expire(key, time);
			return count;
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	/**
	 * 获取set缓存的长度
	 *
	 *
	 * @param key 键
	 */
	public long sGetSetSize(String key) {
		try {
			return redisTemplate.opsForSet().size(key);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	/**
	 * 移除值为value的
	 *
	 * @param key 键
	 * @param values 值 可以是多个
	 * @return 移除的个数
	 */
	public long setRemove(String key, Object... values) {
		try {
			Long count = redisTemplate.opsForSet().remove(key, values);
			return count;
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}

	// ===============================list=================================
	/**
	 * 获取list缓存的内容
	 *
	 * @param key 键
	 * @param start 开始
	 * @param end 结束 0 到 -1代表所有值
	 */
	public List<Object> lGet(String key, long start, long end) {
		try {
			return redisTemplate.opsForList().range(key, start, end);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * 获取list缓存的长度
	 *
	 * @param key 键
	 */
	public long lGetListSize(String key) {
		try {
			return redisTemplate.opsForList().size(key);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	/**
	 * 通过索引 获取list中的值
	 *
	 * @param key 键
	 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0
								时,-1,表尾,-2倒数第二个元素,依次类推
	 */
	public Object lGetIndex(String key, long index) {
		try {
			return redisTemplate.opsForList().index(key, index);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * 将list放入缓存
	 *
	 * @param key 键
	 * @param value 值
	 */
	public boolean lSet(String key, Object value) {
		try {
			redisTemplate.opsForList().rightPush(key, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 将list放入缓存
	 * @param key 键
	 * @param value 值
	 * @param time 时间(秒)
	 */
	public boolean lSet(String key, Object value, long time) {
		try {
			redisTemplate.opsForList().rightPush(key, value);
			if (time > 0)
				expire(key, time);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 将list放入缓存
	 *
	 * @param key 键
	 * @param value 值
	 * @return
	 */
	public boolean lSet(String key, List<Object> value) {
		try {
			redisTemplate.opsForList().rightPushAll(key, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 将list放入缓存
	 *
	 * @param key 键
	 * @param value 值
	 * @param time 时间(秒)
	 * @return
	 */
	public boolean lSet(String key, List<Object> value, long time) {
		try {
			redisTemplate.opsForList().rightPushAll(key, value);
			if (time > 0)
				expire(key, time);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 根据索引修改list中的某条数据
	 *
	 * @param key 键
	 * @param index 索引
	 * @param value 值
	 * @return
	 */
	public boolean lUpdateIndex(String key, long index, Object value) {
		try {
			redisTemplate.opsForList().set(key, index, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 移除N个值为value
	 *
	 * @param key 键
	 * @param count 移除多少个
	 * @param value 值
	 * @return 移除的个数
	 */
	public long lRemove(String key, long count, Object value) {
		try {
			Long remove = redisTemplate.opsForList().remove(key, count,
					value);
			return remove;
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐的小三菊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值