Spring Boot 如何统计每个URL对应的API接口调用次数
问题根因
- Service层每次调用都直接实例化了新的空
Sortner对象,没有从数据库查询对应id的已有记录,空对象的counter字段默认值为null,运算时自动拆箱为0,加1后结果永远为1 - 没有将计数更新后的值持久化到数据库,下次调用接口仍无法获取到历史计数
- 字符串拼接逻辑错误:当前代码是将
sortner.getCounter()的输出结果和字符串"1"做拼接,而非数值相加,即使counter有历史值,也会得到21这类错误的拼接结果
修复步骤
第一步:确认Repo层定义
你的Repo层需要继承JpaRepository并指定实体和主键类型,示例如下:
public interface SortnerRepository extends JpaRepository<Sortner, Integer> { }
第二步:修改Service层逻辑
在Service中注入SortnerRepository,修改查询逻辑:先查库、更新计数、持久化、再返回结果,示例代码如下:
@Service public class SortnerService { // 注入Repo @Resource private SortnerRepository sortnerRepository; public String findById(Integer id) { // 1. 从数据库查询对应id的记录,不存在可按业务逻辑抛出异常或做兜底处理 Sortner sortner = sortnerRepository.findById(id) .orElseThrow(() -> new RuntimeException("对应id的url不存在")); // 2. 计数+1,建议新增url时默认赋值counter为0,避免此处空指针 Integer newCount = sortner.getCounter() + 1; sortner.setCounter(newCount); // 3. 将更新后的计数持久化到数据库 sortnerRepository.save(sortner); // 4. 返回结果 return "no. of times api called =>" + newCount; } }
第三步:补充新增url逻辑的初始化配置
新增url保存到数据库时,需要将counter字段初始化为0,避免后续计数时出现空指针异常,示例新增逻辑参考:
public Sortner addUrl(String url) { Sortner sortner = new Sortner(); sortner.setUrl(url); // 初始化调用次数为0 sortner.setCounter(0); return sortnerRepository.save(sortner); }
扩展优化建议
如果你的接口并发量较高,直接查库+更新的方式会有计数不准的问题,可以考虑用数据库自带的原子更新操作,避免并发下的计数丢失,例如在Repo层自定义更新语句:
@Modifying @Query("update Sortner s set s.counter = s.counter + 1 where s.id = :id") int incrementCounter(@Param("id") Integer id);
调用时先执行该原子更新语句,再查询最新值返回即可。
内容的提问来源于stack exchange,提问作者Chitrang Sharma
相关产品推荐
相关产品推荐

