Jedis客户端Jedis是一个基于Java的Redis客户端连接工具旨在提升性能与易用性。其地址是 https://github.com/redis/jedis 。创建工程创建一个普通maven工程然后在pom文件添加以下依赖dependency groupIdredis.clients/groupId artifactIdjedis/artifactId version4.2.0/version /dependency dependency groupIdjunit/groupId artifactIdjunit/artifactId version3.8.1/version scopetest/scope /dependency使用JedisJedis的方法名几乎与Redis命令相同。每次使用时直接创建Jedis实例即可。Jedis实例创建之后其底层会创建一个指定Redis服务器的Socket连接所以为了节省资源每次使用完Jedis实例后要立即调用close方法关闭连接。value为StringTest public void test() { Jedis jedis new Jedis(192.168.220.128, 6379); jedis.set(name, Alice); jedis.mset(age, 18,depart,IT); String value jedis.get(name); System.out.println(Value for name: value); jedis.close(); }value为HashTest public void test2() { Jedis jedis new Jedis(192.168.220.128, 6379); jedis.hset(employee, name, Bob); MapString, String employeeData new HashMap(); employeeData.put(age, 30); employeeData.put(department, IT); jedis.hset(employee, employeeData); String name jedis.hget(employee, name); ListString empjedis.hmget(employee, department,age); System.out.println(Employee Name: name); System.out.println(Employee Department: emp.get(0)); System.out.println(Employee Age: emp.get(1)); jedis.close(); }value为ListTest public void test3() { Jedis jedis new Jedis(192.168.220.128, 6379); jedis.rpush(names, ali, Bob, Charlie); ListString employees jedis.lrange(names, 0, -1); System.out.println(Employees: employees); jedis.close(); }value为setTest public void test4() { Jedis jedis new Jedis(192.168.220.128, 6379); jedis.sadd(midWares, Redis, Nginx, RocketMQ); SetString employees jedis.smembers(midWares); System.out.println(Employees: employees); jedis.close(); }value为ZSetTest public void test5() { Jedis jedis new Jedis(192.168.220.128, 6379); jedis.zadd(scores, 90, Alice); jedis.zadd(scores, 85, Bob); jedis.zadd(scores, 95, Charlie); jedis.zadd(scores, 33, Harry); jedis.zadd(scores, 31, Oliver); // 获取前三个员工的名字 ListString employees jedis.zrevrange(scores, 0, 2); System.out.println(Top3: employees); ListTuple scores jedis.zrevrangeWithScores(scores, 0, -1); for (Tuple tuple : scores) { System.out.println(tuple.getScore():tuple.getElement()); } jedis.close(); }使用JedisPool频繁的创建和销毁Jedis实例虽然节省系统资源和网络带宽但会降低系统性能因为创建和销毁连接比较耗时此时可以使用Jedis连接池来解决该问题。JedisPool是全局性的整个类只需要创建一次即可然后每次操作Redis时从JedisPool中拿出一个Redis实例即可。使用完毕无需释放Redis实例返回给JedisPool即可。public class JedisPoolTest { private JedisPool pool new JedisPool(192.168.220.128, 6379); Test public void test() { try (Jedis jedis pool.getResource()) { jedis.set(name, Alice); String value jedis.get(name); System.out.println(Value for name: value); } } }使用JedisPooled每次对Redis操作都需要使用try-with-resource块比较麻烦使用JedisPooled 就无需使用该结构来释放资源了。public class JedisPooledTest { private JedisPooled pool new JedisPooled(192.168.220.128, 6379); Test public void test() { pool.set(name, Alice); String value pool.get(name); System.out.println(Value for name: value); } }连接Sentinel高可用集群直接使用JedisSentinelPool即可。在该客户端只需注册Sentinel节点及其监控的Master的名称即可无需出现master-slave的任何地址信息。其采用的也是JedisPool使用完毕需要通过close方法将其返回给连接池。public class JedisSentinelPoolTest { private JedisSentinelPool pool; { HashSetString sentinels new HashSet(); sentinels.add(redis:26380); sentinels.add(redis:26381); sentinels.add(redis:26382); poolnew JedisSentinelPool(mymaster,sentinels); } Test public void test() { try (Jedis jedis pool.getResource()) { jedis.set(name, Alice); String value jedis.get(name); System.out.println(Value for name: value); } } }连接分布式系统使用JedisCluster即可。底层采用的也是Jedis连接池技术每次使用完毕无需显示关闭其会自动关闭。JedisCluster常用的构造器有两个只需一个集群节点的构造器。这个节点可以是集群中的任意节点只要连上该节点就连上了整个集群。但是这样会存在一个问题如果连接之前这个节点恰好宕机那么就连不上集群了。所以不推荐使用。将集群中所有节点罗列出来。这样就避免了这种风险。public class JedisClusterTest { private JedisCluster jedisCluster; { HashSetHostAndPort nodes new HashSet(); nodes.add(new HostAndPort(127.0.0.1,6380)); nodes.add(new HostAndPort(127.0.0.1,6381)); nodes.add(new HostAndPort(127.0.0.1,6382)); nodes.add(new HostAndPort(127.0.0.1,6383)); nodes.add(new HostAndPort(127.0.0.1,6384)); nodes.add(new HostAndPort(127.0.0.1,6385)); nodes.add(new HostAndPort(127.0.0.1,6386)); nodes.add(new HostAndPort(127.0.0.1,6387)); jedisCluster new JedisCluster(nodes); } Test public void test() { jedisCluster.set(name, Alice); String value jedisCluster.get(name); System.out.println(Value for name: value); } }操作事务Jedis提供了multi、watch、unwatch来对应Redis中的multi、watch、unwatch命令。Jedis的multi返回一个Transaction对象其exec和discard用于执行和取消事务。抛出Java异常public class JedisTxTest { private JedisPool jedisPool new JedisPool(192.168.220.128,6379); Test public void test() { try (Jedis jedis jedisPool.getResource()) { jedis.set(name, Alice); jedis.set(age, 30); Transaction tx jedis.multi(); try { tx.set(name, Bob); int i 3/0; tx.set(age, 25); tx.exec(); } catch (Exception e) { System.out.println(Transaction failed: e.getMessage()); tx.discard(); } finally { String name jedis.get(name); String age jedis.get(age); System.out.println(Name: name); System.out.println(Age: age); } } } }输出结果是全部回滚的结果抛出Redis异常Test public void test2() { try (Jedis jedis jedisPool.getResource()) { jedis.set(name, Alice); jedis.set(age, 30); Transaction tx jedis.multi(); try { tx.set(name, Bob); tx.incr(name); tx.set(age, 25); tx.exec(); } catch (Exception e) { System.out.println(Transaction failed: e.getMessage()); // redis异常不会被Java代码捕获到。 tx.discard(); } finally { String name jedis.get(name); String age jedis.get(age); System.out.println(Name: name); System.out.println(Age: age); } } }输出结果如下说明Redis运行时异常不会被java捕获到不影响代码的运行。watchTest public void test3() { try (Jedis jedis jedisPool.getResource()){ jedis.set(age, 30); System.out.println(加1前的值是jedis.get(age)); jedis.watch(age); Transaction tx jedis.multi(); tx.incr(age); tx.exec(); System.out.println(加1前的值是jedis.get(age)); } }SpringBoot整合RedisSpring Boot中一般使用RedisTemplate类来操作Redis。创建SpringBoot项目添加依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency在配置文件中增加Redis相关配置spring: # 配置单机版Redis redis: host: localhost port: 6379 password: 1111 # # 配置Sentinel高可用集群 # sentinel: # master: mymaster # nodes: # - localhost:26380 # - localhost:26381 # - localhost:26382 # # 配置分布式系统 # cluster: # nodes: # - localhost:6380 # - localhost:6381 # - localhost:6382 # - localhost:6383 # - localhost:6384 # - localhost:6385 # 配置缓存 cache: type: redis cache-names: pc修改实体类注意要将实体类缓存到Redis实体类必须序列化所以要实现序列化接口 Serializable。修改具体的实现类主要修改写操作方法和读操作方法。写操作的方法如下Autowired private RedisTemplateString, Object redisTemplate; Autowired private ProductDao productDao; Transactional // CacheEvict 用于实现value指定缓存空间中缓存数据的清空。allEntries为true表示清空该缓存空间中的所有数据。 // 如果不想清空所有可以通过key属性指定要清空的缓存数据的key。 CacheEvict(value pc, allEntries true) public void saveProduct(Product product) { productDao.save(product); }读操作的方法如下// Cacheable 用于实现方法的结果进行缓存。value指定缓存空间key指定缓存数据的key。 // 如果缓存中存在指定key的数据则直接返回缓存中的数据如果不存在则执行方法体中的代码并将结果存入缓存中。 Cacheable(value pc, key product_all) public ListProduct getAllProducts() { return productDao.findAll(); } // #name 表示方法参数name的值。也可以使用#root.args[0]来表示第一个参数的值。 Cacheable(value pc, key product_#name) public Product getProductByName(String name) { return productDao.findByName(id); } Autowired private RedisTemplateString, Object redisTemplate; // 获取营业额的方法适用于方法中获取缓存的值再参与计算的场景 public Double findTurnover(){ // 从Redis中获取营业额数据 BoundValueOperationsString, Object opsForValue redisTemplate.boundValueOps(turnover); // get方法的参数是要获取的缓存数据的key这里假设营业额数据的key为turnover Double turnover (Double) opsForValue.get(); if (turnover null) { // 如果Redis中没有数据则从数据库中查询并存入Redis turnover queryTurnoverFromDatabase(); opsForValue.set(turnover,10, TimeUnit.MINUTES); // 将营业额数据存入Redis设置过期时间为10分钟 } return turnover; }修改Application启动类EnableCaching SpringBootApplication public class SpringbootRedisApplication { public static void main(String[] args) { SpringApplication.run(SpringbootRedisApplication.class, args); }