Ujorm3:面向 JavaBeans 和 Records 的全新轻量级 ORM

发布: (2026年3月24日 GMT+8 00:27)
6 分钟阅读
原文: Dev.to

Source: Dev.to

请提供您希望翻译的文章正文内容(除代码块和 URL 之外的文本),我将为您翻译成简体中文并保留原有的格式。

为什么需要新的 ORM?

原始的 JDBC API 从来就不是为完整的 ORM 设计的,多年来出现了大量的库和框架,它们各自都有在复杂度、性能和可用性方面的取舍。

Ujorm 3 旨在成为一个 可靠、安全、高效且易于理解 的关系型数据库访问工具:

  • 薄层 包装 JDBC —— 没有隐藏的魔法。
  • 无状态对象原生 SQL —— 你完全掌控发送到数据库的内容。
  • 不处理 SQL 方言 —— 编写普通的 SQL;库仅提供类型安全的映射助手。
  • 不缓存查询结果 —— 只保留少量元数据以提升速度。

第一个发布候选版(RC1)已在 Maven Central 上提供,采用 Apache License 2.0

核心概念

概念描述
SqlQuery (formerly SqlParamBuilder)PreparedStatement 的外观。支持命名参数,消除受检异常,并为 SELECT 返回 Stream
ResultSetMapperResultSet 映射到领域对象。映射模型在首次使用时构建一次并重复使用,显著降低每次查询的开销。
Annotations使用标准的 jakarta.persistence 注解(@Table@Column@Id)。当缺少注解时,库也可以推断映射。
Supported POJOs同时完全支持可变的 JavaBean 以及 不可变的 record
Relations仅支持 M:1(多对一)关系。特意省略 1:M 集合,以避免隐藏查询和 N+1 问题。
Column Labels列可以通过点链标签引用(例如 "city.name")。为安全起见,推荐使用生成的 类型安全元模型Meta* 类)。
EntityManager通过 Crud 对象提供 CRUD 操作(包括批量命令)。支持通过列枚举或对原始对象进行差异比较来进行部分更新。

示例:选择员工

// Static mapper – thread‑safe and reusable
static final ResultSetMapper EMPLOYEE_MAPPER =
        ResultSetMapper.of(Employee.class);

void select() {
    var sql = """
            SELECT ${COLUMNS}
            FROM employee e
            JOIN city c ON c.id = e.city_id
            LEFT JOIN employee b ON b.id = e.boss_id
            WHERE e.id > :employeeId
            """;

    var employees = SqlQuery.run(connection(), query -> query
            .sql(sql)
            // Map columns – the ${COLUMNS} placeholder is replaced automatically
            .column("e.id",   MetaEmployee.id)
            .column("e.name", MetaEmployee.name)
            .column("c.name", MetaEmployee.city, MetaCity.name)
            .column("c.country_code", MetaEmployee.city, MetaCity.countryCode)
            .column("b.name", MetaEmployee.boss, MetaEmployee.name)
            .bind("employeeId", 0L)
            // Convert the ResultSet stream to a List
            .streamMap(EMPLOYEE_MAPPER.mapper())
            .toList());
}

领域类不需要事先注册。
如果你希望保持 SQL 文本不被修改,请使用 label() 而不是 column()。**column()label() 不能在同一个查询中混用。*

基准亮点

  • 运行时生成的映射类(而非反射) → 更低的内存使用,减少 GC 压力。
  • 零外部依赖 → 编译后的基准测试 + Ujorm 3 JAR 为:
org.ujorm
ujorm-orm
3.0.0-RC1

生成元模型(可选)

如果需要类型安全的 Meta* 类,请在 maven-compiler-plugin 中启用注解处理器:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.11.0</version>
    <configuration>
        <annotationProcessorPaths>
            <path>
                <groupId>org.ujorm</groupId>
                <artifactId>ujorm-processor</artifactId>
                <version>3.0.0-RC1</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

摘要

Ujorm 3 提供一种 最小开销透明、且 类型安全 的方式在 Java 中使用关系型数据库。它紧贴 JDBC,同时提供干净、现代的 API,使开发者能够编写清晰、高性能的代码,而无需承担重量级 ORM 隐藏的成本。

在下一个 Java 17+ 项目中尝试它,体验“一切皆可能的最简实现”的简洁性。

<dependency>
    <groupId>org.ujorm</groupId>
    <artifactId>ujorm-meta-processor</artifactId>
    <version>3.0.0-RC1</version>
</dependency>

来自 Benchmark 项目的 Ujorm 模块可用作示例实现的模板。该库的代码库目前已通过 JUnit 测试覆盖,这些测试使用内存中的 H2 数据库(以及模拟对象)。

在发布正式版本之前,我计划为 PostgreSQLMySQLOracleMS SQL Server 数据库添加集成测试。

注意:
如果你为企业客户工作,需要符合标准或在不同数据库之间抽象的可移植性,请改用 JPA/Hibernate。如果你已经找到了满足期望和需求的 ORM 框架,继续使用它即可。然而,如果你在新项目中寻找一种快速、透明且没有隐藏机制的替代方案,Ujorm 3 库绝对值得一试。

项目主页

(可以在此插入项目主页的链接)

更多示例作为 JUnit 测试

(此处可插入额外 JUnit 测试示例的链接或描述)

基准测试

(可以在此插入基准测试的链接或描述)

0 浏览
Back to Blog

相关文章

阅读更多 »

SJF4J:Java 的结构化 JSON 门面

介绍 在 Java 中使用 JSON 通常意味着在两种方式之间进行选择: - 数据绑定 POJO —— 强类型,但刚性 - 树模型 JsonNode / Ma...

两数之和 - Java

使用哈希解决 Two Sum 我的思考过程 当我第一次看到 Two Sum 问题时,我的初始想法很简单: - 目标 = 9 - 当前数字 = 2 我不需要…