当前位置: 首页 > news >正文

Redis缓存--Jedis

一、Jedis实例

二、JedisPool

如果应用非常频繁地创建和销毁 Jedis 实例,虽然节省了系统资源与网络带宽,但会大大降低系统性能。因为创建和销毁 Socket 连接是比较耗时的。此时可以使用 Jedis 连接池来解决该问题。 

使用 JedisPool 与使用 Jedis 实例的区别是,JedisPool 是全局性的,整个类只需创建一次即可,然后每次需要操作 Redis 时,只需从 JedisPool 中拿出一个 Jedis 实例直接使用即可。

public class JedisPoolTest {private JedisPool jedisPool = new JedisPool("redis", 6379);// value为String的情况@Testpublic void test01() {try (Jedis jedis = jedisPool.getResource()) {jedis.set("name", "张三");jedis.mset("age", "23", "depart", "行政部");System.out.println("name = " + jedis.get("name"));System.out.println("age = " + jedis.get("age"));System.out.println("depart = " + jedis.get("depart"));}}
}

使用完毕后,无需释放 Jedis 实例,只需返回 JedisPool 即可。 

三、JedisPooled

对于每次对 Redis 的操作都需要使用 try-with-resource 块是比较麻烦的,而使用JedisPooled 则无需再使用该结构来自动释放资源了。

public class JedisPooledTest {private JedisPooled jedisPooled = new JedisPooled("redis", 6379);// value为String的情况@Testpublic void test01() {jedisPooled.set("name", "张三");jedisPooled.mset("age", "23", "depart", "行政部");System.out.println("name = " + jedisPooled.get("name"));System.out.println("age = " + jedisPooled.get("age"));System.out.println("depart = " + jedisPooled.get("depart"));}
}

四、连接Sentinel高可用集群

对于 Sentinel 高可用集群的连接,直接使用 JedisSentinelPool 即可。在该客户端只需注册所有 Sentinel 节点及其监控的 Master 的名称即可,无需出现 master-slave 的任何地址信息。

其采用的也是 JedisPool,使用完毕的 Jedis 也需要通过 close()方法将其返回给连接池。

public class JedisSentinelPoolTest {private JedisSentinelPool jedisPool;{HashSet<String> sentinels = new HashSet<>();sentinels.add("redis:26380");sentinels.add("redis:26381");sentinels.add("redis:26382");jedisPool = new JedisSentinelPool("mymaster", sentinels);}// value为String的情况@Testpublic void test01() {try (Jedis jedis = jedisPool.getResource()) {jedis.set("name", "张三");jedis.mset("age", "23", "depart", "行政部");System.out.println("name = " + jedis.get("name"));System.out.println("age = " + jedis.get("age"));System.out.println("depart = " + jedis.get("depart"));}}
}

五、连接分布式系统

对于 Redis 的分布式系统的连接,直接使用 JedisCluster 即可。

 其底层采用的也是 Jedis 连接池技术。每次使用完毕后,无需显式关闭,其会自动关闭。 

对于 JedisCluster 常用的构造器有两个。一个是只需一个集群节点的构造器,这个节点可以是集群中的任意节点,只要连接上了该节点,就连接上了整个集群。但该构造器存在一个风险:其指定的这个节点在连接之前恰好宕机,那么该客户端将无法连接上集群。所以,推荐使用第二个构造器,即将集群中所有节点全部罗列出来。这样就会避免这种风险了。 

public class JedisClusterTest {private JedisCluster jedisCluster;{// 连接Cluster中的任意主节点// HostAndPort node = new HostAndPort("redis", 6380);// jedisCluster = new JedisCluster(node);// 连接整个ClusterHashSet<HostAndPort> nodes = new HashSet<>();nodes.add(new HostAndPort("redis", 6380));nodes.add(new HostAndPort("redis", 6381));nodes.add(new HostAndPort("redis", 6382));nodes.add(new HostAndPort("redis", 6383));nodes.add(new HostAndPort("redis", 6384));nodes.add(new HostAndPort("redis", 6385));jedisCluster = new JedisCluster(nodes);}// value为String的情况@Testpublic void test01() {jedisCluster.set("name", "张三");// 代码中存在注释的多值设置和打印逻辑// jedisCluster.mset("age", "23", "depart", "行政部");System.out.println("name = " + jedisCluster.get("name"));}
}

六、操作事务

对于 Redis 事务的操作,Jedis 提供了 multi()watch()unwatch()方法来对应 Redis 中的 multiwatchunwatch 命令。Jedis multi()方法返回一个 Transaction 对象,其 exec()discard() 方法用于执行和取消事务的执行。

6.1 抛出Java异常

public class JedisTxTest {private JedisPool jedisPool = new JedisPool("redis", 6379);@Testpublic void test01() {try (Jedis jedis = jedisPool.getResource()) {jedis.set("name", "张三");jedis.set("age", "23");Transaction multi = jedis.multi();try {multi.set("name", "李四");// 构造一个Java异常int i = 3 / 0;multi.set("age", "24");multi.exec();} catch (Exception e) {// 一旦发生异常,全部回滚multi.discard();} finally {System.out.println(jedis.get("name")); // 张三System.out.println(jedis.get("age")); // 23}}}
}

6.2 Redis异常

public class JedisTxTest {private JedisPool jedisPool = new JedisPool("redis", 6379);@Testvoid test02() {try (Jedis jedis = jedisPool.getResource()) {jedis.set("name", "张三");jedis.set("age", "23");Transaction multi = jedis.multi();try {multi.set("name", "李四");// 构造一个Redis异常,不会影响后面的执行multi.incr("name");multi.set("age", "24");multi.exec();} catch (Exception e) {// Redis异常不会被Java代码捕获到multi.discard();} finally {System.out.println(jedis.get("name")); // 李四System.out.println(jedis.get("age")); // 24}}}
}

6.3 watch

multi:开启事务,之后的所有命令会被放入事务队列中,不会立即执行,直到调用 exec 才会批量执行。

watch key:监视指定的键,若在事务执行前这些键被其他客户端修改,则事务会被打断(不执行),用于实现乐观锁。

unwatch:取消对所有键的监视,通常在事务执行前或放弃事务时使用。

@Test
void test03() {try (Jedis jedis = jedisPool.getResource()) {jedis.set("age", "23");System.out.println("增一前的age值:" + jedis.get("age")); // 23jedis.watch("age");Transaction multi = jedis.multi();multi.incr("age");multi.exec();System.out.println("增一后的age值:" + jedis.get("age"));}
}

七、SpringBoot整合Redis

@CacheEvict 用于实现 value 指定缓存空间中缓存数据的清空。

allEntries true 指定清空该缓存空间所有数据。如果不想清空所有,则需通过 key 属性指定要清理的 key 数据。

@Service
public class ProductServiceImpl implements ProductService {@Autowiredprivate ProductDao dao;@Autowiredprivate RedisTemplate<Object, Object> rt;@Override@Transactional(rollbackFor = Exception.class)@CacheEvict(value = "pc", allEntries = true)public void saveProduct(Product product) {dao.insertProduct(product);}
}
@Override
@Cacheable(value = "pc", key = "'product_' + #name")
public List<Product> findProductsByName(String name) {return dao.selectProductsByName(name);
}@Override
@Cacheable(value = "pc", key = "'product_all'")
public List<Product> findAllProducts() {return dao.selectAllProducts();
}// @Cacheable 用于指定将查询结果使用指定的 key 缓存到指定缓存空间
// 如果再有对该查询数据的访问,则会先从缓存中查看。
@Override
public Double findTurnover() {// 获取Redis中指定key("turnover")的操作对象,用于后续对该key的读写操作// rt 是代码中注入的 RedisTemplate<Object, Object> 对象// 它是 Spring 封装的 Redis 操作模板,提供了对 Redis 各种数据类型(String、Hash、List 等)的通用操作方法// boundValueOps("turnover"):绑定指定 key 并返回操作对象// bound 意为 “绑定”,表示后续的所有操作都会针对指定的 key(这里是 turnover),无需每次操作都显式传入 key// // ValueOps 表示该操作对象专门用于处理 Redis 中的 String 类型数据(即 key-value 都是字符串或可序列化对象的键值对)// BoundValueOperations:绑定 key 后的操作工具类BoundValueOperations<Object, Object> ops = rt.boundValueOps("turnover");// 从Redis缓存中获取key为"turnover"的值Object turnover = ops.get();// 判断缓存中是否存在该数据(若不存在则为null)if (turnover == null) {// 创建当前日期对象Date date = new Date();// 创建日期格式化对象,指定格式为"yyyy-MM-dd"SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 从数据库中查询当天(格式化后的日期)的营业额数据turnover = dao.selectTurnover(sdf.format(date));}// 将营业额数据存入Redis缓存,并设置过期时间为10秒(10秒后自动失效)ops.set(turnover, 10, TimeUnit.SECONDS);// 将获取到的营业额数据转换为Double类型并返回return (Double) turnover;
}
http://www.dtcms.com/a/511919.html

相关文章:

  • 三点式振荡器(Colpitts/Hartley)的相关问题
  • 西安淘宝网站建设公司ui设计需要学哪些课程
  • h5游戏免费下载:任意球大师
  • DL2421P1 24V DFN1006封装低电容ESD保护二极管0.3pF,80W,1.5A IPP@8/20uS VC53V
  • 【Threejs-sdk】使用 mogl.js 快速匹配烘焙.
  • 泸州市住房和城乡建设局网站企业信息查询系统官网上海
  • Web原生架构 vs 传统C/S架构:在数据库管理中的性能与安全差异
  • HTTPS 爬虫实战指南 从握手原理到反爬应对与流量抓包分析
  • 淘宝客网站开发服务商酒类营销网站
  • QT:控件VLC播放视频时,如何获得鼠标事件
  • 杭州网站建站商城网站都有什么功能
  • 南宁企业网站设计陕西建设厅网站首页
  • 高频疲劳试验机主要技术规格
  • C++内存管理的理解
  • 当EtherCAT遇上PROFINET:我们的“协议小翻译”让矿井安全手拉手
  • 【完整源码+数据集+部署教程】【制造业&盒子】食品物品检测系统源码&数据集全套:改进yolo11-MultiSEAMHead
  • 在windows学习Kubernetes的几个障碍
  • MySQL数据库管理、DDL、DQL、DML、DCL等总结
  • Telink BLE SDK软件架构
  • 计算机毕设java医院挂号系统 基于Java的医院智能挂号与信息管理系统 Java医院挂号及医疗信息综合平台
  • 上海市500强企业名单单页面优化
  • 【0443】signalfd + epoll 完成事件监听+指定信号处理(演示demo)
  • 湛江有没有做网站的算卦网站哪里可以做
  • 布局具身智能时代(上):深兰科技“具身视觉导航大脑”技术的商业化探索
  • test002
  • RTPENGINE redis 测试
  • 在Ubuntu中安装Docker
  • 佛山市专注网站建设平台网站制作二级网页怎么做
  • 百度收录情况查询南通seo公司网站
  • 【MySQL】慢查寻的发现和解决优化(思维导图版)