Java 21和Spring Boot 3升级笔记(四)数据访问层适配

发表于 2024-10-29 22:31 1191 字 6 min read

Spring AI学习笔记(四)工具调用和MCPSpring AI学习笔记(三)RAG从文档入库到回答Spring AI学习笔记(二)ChatClient从怎么调到怎么封装Spring AI学习笔记(一)它到底解决什么问题java新版本-java25学习笔记(四)用JFR和GC日志做一次体检java新版本-java25学习笔记(三)虚拟线程要和资源边界一起看java新版本-java25学习笔记(二)运行时基线先统一java新版本-java25学习笔记(一)LTS版本对比和学习路线主流AI Agent能力对比与工程选型我用Kiro做了个自己的工具站盘一盘虚拟线程我用Trae做了个AstrBot的AI角色扮演插件Python初学笔记(六)常用标准库先学这几个Python初学笔记(五)读写文件和处理异常Python初学笔记(四)函数让代码开始有结构Python初学笔记(三)条件、循环和推导式Python初学笔记(二)变量和基础类型比想象中重要Python初学笔记(一)先把环境和运行方式弄明白主流AI大模型能力对比Java 21和Spring Boot 3升级笔记(五)日志指标与可观测性Java 21和Spring Boot 3升级笔记(四)数据访问层适配Java 21和Spring Boot 3升级笔记(三)虚拟线程使用边界Java 21和Spring Boot 3升级笔记(二)Jakarta迁移要点Java 21和Spring Boot 3升级笔记(一)工程基线整理How Can We Tolerate Magic Values! Major Overhaul of JPA Specification!处理生僻字乱码:JPA框架对于Oracle的NVarchar2,NChar,NClob类型支持Redis Stream能不能当轻量消息队列用RocketMQ 5学习笔记:普通消息之外要看什么事件流不是换个消息队列这么简单Kubernetes学习笔记04:发布、排障和观测Kubernetes学习笔记03:配置、密钥和存储Kubernetes学习笔记02:Deployment、Service和IngressKubernetes学习笔记01:Pod和控制器mysql索引原理02--存储引擎索引的实现mysql索引原理01--索引的数据结构
This post is not yet available in English. Showing the original.
  升级 Java 21 和 Spring Boot 3 时,数据访问层一定要重点看。因为很多项目真正复杂的地方不在 Controller,而在 Repository、Mapper、事务、分页、动态查询这些位置。   Spring Boot 3 带来的 Hibernate 6、Jakarta...

前言

  升级 Java 21 和 Spring Boot 3 时,数据访问层一定要重点看。因为很多项目真正复杂的地方不在 Controller,而在 Repository、Mapper、事务、分页、动态查询这些位置。

  Spring Boot 3 带来的 Hibernate 6、Jakarta Persistence、连接池和驱动版本变化,都会影响数据库访问。即使项目不用 JPA,只用 MyBatis,也要检查驱动、分页插件、类型处理器和事务边界。

  这篇不是讲某一个 ORM 框架,而是记录升级时我会怎么检查数据访问层。

先跑核心 SQL

  升级后不要只跑启动测试。数据访问问题很可能在接口执行时才出现。

我会先挑几类核心 SQL:

1.按主键查询。 2.分页查询。 3.动态条件查询。 4.批量插入或更新。 5.涉及日期、枚举、JSON 字段的查询。 6.带事务的业务流程。

这些 SQL 能覆盖大部分风险。尤其是分页和动态条件,框架版本变化后最容易出现细节问题。

比如 MyBatis 里如果用了分页插件,要确认插件版本支持当前 Spring Boot 和 MyBatis 版本。不要只看编译通过,必须实际查一页数据。

驱动版本要跟上

  数据库驱动不要长期锁在很老的版本。

升级 Java 21 后,老驱动可能还能用,但不代表没有兼容隐患。MySQL、PostgreSQL、Oracle 的 JDBC 驱动都应该看一下官方兼容范围。

如果项目里手动指定了驱动版本,可以考虑交给 Spring Boot 依赖管理,或者至少把版本升级到明确支持当前 JDK 的版本。

连接配置也要复查,比如:

spring:
  datasource:
    hikari:
      maximum-pool-size: 30
      connection-timeout: 30000

这些参数不是越大越好。升级后如果引入虚拟线程,请求并发可能提高,连接池反而更容易成为瓶颈。

事务边界要重新审一遍

  事务问题平时不显眼,一出问题就很麻烦。升级时可以顺手审一下事务边界。

常见问题还是那些:

1.事务方法不是 public。 2.同类内部方法调用导致事务不生效。 3.事务里调用外部接口。 4.事务范围过大。 5.异常被吞掉导致没有回滚。

比如:

@Transactional
public void createOrder(CreateOrderCommand command) {
    orderRepository.save(command.toOrder());
    payClient.createPayOrder(command);
}

这种把外部支付调用放在事务里的写法就要谨慎。升级不是必须改业务设计,但它是一个重新检查老问题的机会。

类型映射要重点测

  数据访问层里最容易藏问题的是类型映射。

比如:

1.数据库datetime和 JavaLocalDateTime。 2.数据库date和 JavaLocalDate。 3.枚举字段。 4.JSON 字段。 5.Oracle 的number和 Java 数字类型。 6.大文本字段。

这些字段平时不一定每个接口都会走到。升级 Hibernate、MyBatis 或 JDBC 驱动后,最好准备一些有代表性的数据测试。

如果项目里有自定义 TypeHandler 或 AttributeConverter,也要单独跑。比如枚举值转换、JSON 字符串转换,这些地方非常依赖框架调用时机。

动态查询不要写散

  很多 Java 项目越做越久,查询条件会越来越多。JPA Specification、MyBatis XML、MyBatis Plus Wrapper 都可能写得很散。

升级时我会顺手看有没有明显的重复条件、魔法字符串和拼接 SQL。

比如:

queryWrapper.eq(Order::getStatus, status)
        .like(StringUtils.hasText(keyword), Order::getOrderNo, keyword);

这种用 lambda 字段引用,比到处写"order_no"要稳一些。不是说所有项目都要换框架,而是动态查询最好有统一风格,不要同一个模块里三种写法混着来。

慢 SQL 也要顺手看

  升级本身不等于优化,但升级后很适合做一次慢 SQL 复查。

因为 JDK、框架、驱动都变了,如果某些接口变慢,要能判断是升级引起的,还是老问题被放大了。

可以重点看:

1.分页是否走索引。 2.模糊查询是否可控。 3.批量更新是否分批。 4.事务是否长期持有锁。 5.连接池等待是否增加。

如果项目有监控,最好对比升级前后的接口耗时和数据库耗时。没有监控时,至少核心接口要手动压一下。

小结

  Java 21 和 Spring Boot 3 升级时,数据访问层不能只求编译通过。数据库驱动、连接池、事务、类型映射、分页插件、动态查询都要实际验证。

  我的建议是先列核心 SQL 和核心业务流程,用真实数据跑一轮。数据访问层稳住了,整个升级才算真正有底。

If you enjoyed this, leave a comment~

© 2019 - 2026 VincentHo @VincentHo
Powered by theme astro-koharu · Inspired by Shoka