Bee 3.0.0 LTS:小体积 ORM 开始认真处理复杂关联、分片与虚拟线程

2026-09-02 26 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

Bee 3.0.0 LTS 把轻量 ORM 推向了更完整的工程场景:支持多层子表关联查询,分库分表 Sharding 能力同步升级,并增加对虚拟线程的支持。它仍然保持体积小、接口简单和接近 JDBC 的性能特征,3.0.0 LTS 版本体积约为 969K。

对于不想在 Hibernate、MyBatis 与复杂数据访问框架之间反复取舍的团队,这个版本值得从三个角度观察:复杂关系是否更容易表达,分片规则是否能稳定落地,以及虚拟线程是否真的适合当前数据库连接池。

从单表 CRUD 走向多层关联

轻量 ORM 最容易覆盖的是单表增删改查,但真实业务很快会遇到多层关系。例如一个订单包含多个订单项,每个订单项又关联商品、商品分类和库存记录。查询订单列表时,应用通常还希望一次获得这些子对象。

Bee 3.0.0 LTS 的变化重点之一,就是多层子表关联查询。它的价值不只是少写几段 SQL,更重要的是把对象关系和查询结果组织起来,减少手工组装 DTO、重复处理空值以及维护多份映射代码的成本。

不过,多层关联并不意味着所有数据都应该一次性加载。可以按访问场景拆分:

  • 列表页只查询订单和必要的摘要字段;
  • 详情页再加载订单项、商品和库存;
  • 报表场景优先使用明确的投影查询,避免返回完整对象树;
  • 对一对多关系设置分页或数量边界,防止笛卡尔积放大结果集。

ORM 能够表达关联,不代表数据库执行计划一定合理。上线前仍应检查生成 SQL、索引命中情况和关联查询的实际行数。

分库分表的关键是同步规则

分库分表功能真正困难的地方通常不在于把表名改成 order_00order_01,而在于所有读写路径必须使用同一套分片规则。

一个可维护的分片策略至少要明确这些问题:

  1. 分片键是什么,例如 tenant_iduser_idorder_id
  2. 写入、按主键查询和分页查询是否都能携带分片键;
  3. 跨分片查询是否被允许,结果如何排序和合并;
  4. 分片数量变化时,旧数据是否需要迁移;
  5. 事务边界是否可能跨越多个数据库连接。

3.0.0 LTS 对 Sharding 能力进行同步升级,适合已经使用 Bee 数据访问层、又需要将数据水平拆分的项目。但采用前应把分片配置当作基础设施契约管理,而不是散落在业务代码里的字符串拼接。

下面是一份可以改造的配置示例。配置字段名称需要根据项目实际使用的 Bee Sharding API 调整,这里重点展示分片键、数据源和表规则的组织方式:

sharding:
  enabled: true
  shard-key: tenant_id
  data-sources:
    - name: ds_0
      jdbc-url: jdbc:mysql://127.0.0.1:3306/app_0
    - name: ds_1
      jdbc-url: jdbc:mysql://127.0.0.1:3307/app_1
  tables:
    orders:
      actual-data-nodes: ds_${0..1}.orders_${0..15}
      database-strategy:
        algorithm: tenant_id % 2
      table-strategy:
        algorithm: order_id % 16

配置完成后,至少要为以下用例编写测试:同一租户写入与读取命中同一数据源、按主键查询命中单表、缺少分片键时能够被明确拒绝,以及跨分片查询的排序和分页结果符合预期。

虚拟线程不是无限连接池

Bee 3.0.0 LTS 支持虚拟线程,这对 JDBC 等阻塞式 I/O 场景尤其有吸引力。虚拟线程可以降低大量等待任务占用平台线程的成本,让传统同步代码在高并发等待场景下拥有更好的资源利用率。

但虚拟线程不会增加数据库服务器能够处理的并发连接数。应用仍然必须正确设置连接池大小、事务范围和慢查询超时。一个常见错误是为每个请求创建虚拟线程,却让每个线程都长期占用一个数据库连接,最终瓶颈仍然出现在连接池或数据库端。

下面的程序可以直接用 JDK 21 编译运行,验证虚拟线程的基本执行方式:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class VirtualThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
            for (int i = 0; i < 10_000; i++) {
                int taskId = i;
                executor.submit(() -> {
                    Thread.sleep(10);
                    System.out.println("task=" + taskId
                            + ", virtual=" + Thread.currentThread().isVirtual());
                    return null;
                });
            }
        }

        System.out.println("all tasks completed");
    }
}

运行命令:

javac --release 21 VirtualThreadDemo.java
java VirtualThreadDemo

将它接入 Bee 应用时,可以让请求任务运行在虚拟线程执行器中,同时继续使用有上限的 JDBC 连接池。压测时重点观察连接池等待时间、数据库 CPU、事务持续时间和 P99 延迟,而不是只看虚拟线程数量。

小体积带来的工程取舍

Bee 3.0.0 LTS 约 969K 的体积适合对启动速度、依赖数量或部署包大小敏感的服务,也适合 Android、鸿蒙等资源受限场景。它同时覆盖 ORM、Sharding、MongoDB ORM 等使用方向,定位上更像一个小巧的应用数据访问层。

轻量并不等于没有边界。团队需要确认以下事项:

  • 当前项目使用的数据库和驱动是否经过完整验证;
  • 复杂查询是否可以查看并审计最终 SQL;
  • 多层关联是否支持项目需要的分页、排序和懒加载策略;
  • Sharding 场景下的事务、跨分片聚合和数据迁移如何处理;
  • 虚拟线程与连接池、监控系统及上下文传递是否兼容。

采用建议

升级到 Bee 3.0.0 LTS 可以从一个边界清晰的服务开始:先验证普通 CRUD 和原生分页,再验证一组真实的多层关联查询,随后在测试环境接入分片规则,最后使用 JDK 21 对虚拟线程进行压测。

判断升级是否成功,不应只看依赖体积或吞吐量。更可靠的标准是:查询代码是否更容易维护,生成 SQL 是否可控,分片命中是否稳定,数据库连接是否没有成为新的瓶颈。满足这些条件后,Bee 3.0.0 LTS 才真正适合进入生产环境。


相关推荐