使用Java优雅的实现先查询缓存再查询数据库

前言:strawberry:

在访问量大的时候,为了提高查询效率,我们会将数据先缓存到redis中。先查询redis,查询不到再去查询数据库,实现这个逻辑也不复杂,写一个 if(...)else{...} 也就行了。这种做法也不是不行,就是看起来有点儿粗糙,所以我想换一种更优雅的写法。

举个栗子:chestnut:

现有一个使用商品名称查询商品的需求,要求先查询缓存,查不到则去数据库查询;从数据库查询到之后加入缓存,再查询时继续先查询缓存。

思路分析

可以写一个条件判断,伪代码如下:

//先从缓存中查询
String goodsInfoStr = redis.get(goodsName);
if(StringUtils.isBlank(goodsInfoStr)){
	//如果缓存中查询为空,则去数据库中查询
	Goods goods = goodsMapper.queryByName(goodsName);
	//将查询到的数据存入缓存
	goodsName.set(goodsName,JSONObject.toJSONString(goods));
	//返回商品数据
	return goods;
}else{
	//将查询到的str转换为对象并返回
	return JSON.parseObject(goodsInfoStr, Goods.class);
}
复制代码

上面这串代码也可以实现查询效果,看起来也不是很复杂,但是这串代码是 不可复用的 ,只能用在这个场景。假设在我们的系统中还有很多类似上面商品查询的需求,那么我们需要到处写这样的 if(...)else{...} 。作为一个程序员,不能把类似的或者重复的代码统一起来是一件很难受的事情,所以需要对这种场景的代码进行优化。

上面这串代码的问题在于: 入参不固定、返回值也不固定,如果仅仅是参数不固定,使用泛型即可。但最关键的是查询方法也是不固定的,比如查询商品和查询用户肯定不是一个查询方法吧。

所以如果我们可以把一个方法(即上面的各种查询方法)也能当做一个参数传入一个统一的判断方法就好了,类似于:

/**
 * 这个方法的作用是:先执行method1方法,如果method1查询或执行不成功,再执行method2方法
 */
public static<T> T selectCacheByTemplate(method1,method2)
复制代码

想要实现上面的这种效果,就不得不提到Java8的新特性: 函数式编程

原理介绍

在Java中有一个package: java.util.function ,里面全部是接口,并且都被 @FunctionalInterface 注解所修饰。

Function分类

  • Consumer(消费):接受参数,无返回值
  • Function(函数):接受参数,有返回值
  • Operator(操作):接受参数,返回与参数同类型的值
  • Predicate(断言):接受参数,返回boolean类型
  • Supplier(供应):无参数,有返回值

具体我就不在赘述了,可以参考: blog.csdn.net/hua226/arti…

代码实现:cake:

那么接下来就来使用Java优雅的实现先查询缓存再查询数据库吧!

项目代码

配置文件

pom.x

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
让一个 Java 程序优雅地一直保持监听状态,需要注意以下几点: 1. 使用优秀的框架:选择一个稳定、易用的框架可以大大减少程序的开发难度和出错率。例如,Spring Boot 框架提供了很多功能强大的组件,可以快速搭建一个稳定的、可维护的服务。 2. 使用多线程:使用多线程可以充分利用系统资源,提高程序的并发处理能力。可以使用线程池来管理线程,避免线程过多导致系统资源不足。 3. 使用优秀的消息队列:使用消息队列可以有效地解耦程序的各个部分,提高系统的可靠性和可维护性。例如,使用 RabbitMQ 或者 Kafka 可以轻松地实现消息的异步处理和分布式部署。 4. 优化程序性能:对程序进行性能优化可以提高程序的吞吐量和响应速度。例如,使用缓存、降低数据库访问次数等。 下面是一个示例代码,使用了 Spring Boot 和 RabbitMQ 来实现一个优雅地一直保持监听状态的程序: ```java @EnableRabbit @SpringBootApplication public class Application { private static final String QUEUE_NAME = "testQueue"; @Autowired private RabbitTemplate rabbitTemplate; @RabbitListener(queues = QUEUE_NAME) public void handleMessage(String message) { System.out.println("Received message: " + message); } public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public ConnectionFactory connectionFactory() { CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost"); connectionFactory.setUsername("guest"); connectionFactory.setPassword("guest"); return connectionFactory; } @Bean public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) { RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); rabbitTemplate.setQueue(QUEUE_NAME); return rabbitTemplate; } } ``` 在上面的代码中,使用了 Spring Boot 和 RabbitMQ 来实现一个优雅地一直保持监听状态的程序。使用了 Spring Boot 的自动配置功能,可以快速搭建一个稳定的、可维护的服务。同使用 RabbitMQ 来处理消息,可以轻松地实现异步处理和分布式部署。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值