CentOS 8 安装 Apache Torque 指南

在 CentOS 8 上从零安装 Apache Torque 4.0(4.x 系列最终版),覆盖 EOL 后阿里云 vault 换源、JDK 11 与 Maven 3.5.4 安装、el8 显式 JAVA_HOME 配置、Maven 插件生成 OM 类与官方 jar 手工 classpath 直跑两种方案,并跑通 Derby 内存库上的真实增删改查,命令与回显均实测通过。

Apache TorqueApache Torque2026/10/15

CentOS 8 安装 Apache Torque 指南

目标:在 CentOS 8 上从零搭建 Apache Torque 4.0(4.x 系列最终版)的开发与运行环境(JDK 11 + Maven 3.5.4 + Derby 10.14.2.0 嵌入式数据库),处理 CentOS 8 停止维护(EOL)后的软件源迁移与 el8 显式 JAVA_HOME 两大事项,跑通「XML schema → OM 类生成 → 建表 SQL 生成 → 建库 → 增删改查」完整链路;本文全部命令与回显均已在 CentOS 8.4.2105 实测通过。

Apache Torque 是 Apache DB 项目下的对象关系映射(ORM)框架。与 Hibernate 等基于反射的主流框架不同,Torque 从手写或逆向生成的 XML schema 出发,预生成数据对象(Data Object)、Peer 门面与记录映射器等全部 Java 类,运行时直接调用生成类访问数据库,无反射开销、无运行期配置魔法。CentOS 8 已于 2021 年底停止维护,官方源下线,因此本文先解决 EOL 软件源迁移,再完成 Torque 环境搭建。

一、环境信息

本节先固定可复现的基线环境,后续所有命令均在此环境执行。列出操作系统、架构、JDK、构建工具与组件版本,便于读者对照复现。

  • 操作系统:CentOS 8.4.2105(centos:8 官方基线,EOL 版本)
  • 架构:x86_64
  • JDK:OpenJDK 11.0.13.0.8-1.el8_4(dnf 包 java-11-openjdk-devel,8.4 vault 中的最高 JDK 大版本)
  • 构建工具:Apache Maven 3.5.4(dnf 包 maven,Red Hat 发行版 3.5.4-5)
  • 组件版本:Torque 4.0(4.x 系列最终版),运行时坐标 org.apache.torque:torque-runtime:4.0
  • 嵌入式数据库:Apache Derby 10.14.2.0(org.apache.derby:derby,内存模式)
  • Maven 坐标:org.apache.torque:torque-runtime:4.0、org.apache.torque:torque-maven-plugin:4.0、org.apache.torque:torque-templates:4.0
  • 验证用工作目录:/root/torque-demo(Maven 工程)、/root/jar-run(jar 直跑)

系统与版本确认(实时回显):

cat /etc/os-release | head -2
NAME="CentOS Linux"
VERSION="8 (Core)"
uname -m
x86_64

💡 说明:Torque 是库而非服务,环境中不存在需要常驻的守护进程;数据库选用 Derby 嵌入式内存模式(跟随 JVM 存活),因此「安装完成」的判定标准是跑通一个含建表与增删改查的最小程序,而不是某个端口处于监听状态。

二、前置条件

本节说明安装前必须满足的条件。CentOS 8 的最大特殊性在于:官方源已下线,必须先迁移到归档源才能安装任何软件。

  1. 具有 root 或 sudo 权限的 CentOS 8 系统(本文实测基线为 8.4.2105,其他 8.x 小版本需把后文源地址中的版本号一并替换)。
  2. 明确本机可用的归档源站点。CentOS 8 EOL 后官方归档 vault.centos.org 对多数网络环境返回 403(实测 Cannot download repomd.xml),本文使用阿里云归档源 mirrors.aliyun.com/centos-vault/,实测直连可用。
  3. 可访问 Maven 中央仓库 repo1.maven.org(Torque 全部构件均托管于 Maven Central)。
  4. 至少 2 GB 可用磁盘空间(JDK + Maven + 依赖合计约 500 MB)。

归档源连通性确认(实时回显):

curl -sI --max-time 20 https://mirrors.aliyun.com/centos-vault/8.4.2105/BaseOS/x86_64/os/repodata/repomd.xml | head -3
HTTP/1.1 200 OK
Date: Wed, 15 Oct 2026 01:35:42 GMT
Server: nginx

三、版本选型说明

本节给出 Torque 的版本谱系与 el8 平台的 JDK 约束,帮助读者确定安装组合。以下 Torque 版本列表与发布时间均从 Maven Central 的构件目录实时核验(maven-metadata.xml 与各版本 pom 的 Last-Modified 时间):

版本线最新版发布日期(Maven Central 实测)JDK 基线(官网声明)适用场景
3.x(已淘汰)3.32010 年前后Java 1.3+极老项目兼容,不建议新用
4.x(本文实测)4.02013-02-27JDK 1.6+经典生成式 ORM,单体 runtime,文档最多
5.x5.12022-01-05(5.0 为 2020-08-14)JDK 1.8+模块化改造起点
6.x6.02024-05-08JDK 11+移除老旧依赖后的现代基线
7.x(当前主线)7.02025-07-31JDK 17+当前 production release,最新特性

关于维护状态需要如实说明:Torque 4.0 发布于 2013 年 2 月,此后项目经历了 5.0(2020 年)、5.1(2022 年)、6.0(2024 年)到 7.0(2025 年 7 月 31 日)的持续演进,项目仍在活跃维护,Maven Central 上当前 release 为 7.0;但 4.x 分支自 4.0 之后未再发布补丁版本,4.x 系列的最终版就是 4.0。官网(db.apache.org/torque)当前推荐新项目使用 7.0。

本文实际采用 4.0:它是 Torque 生成式 ORM 教程与社区资料覆盖最完整的版本,运行时为单体 jar(依赖 commons-configuration 1.6、commons-dbcp 1.3 等 11 个),对 JDK 基线要求最低(官网声明 JDK 1.6+),与 el8 平台的 JDK 供给恰好匹配。实测其在 JDK 11 与 JDK 17 上全链路(生成、编译、运行)均可跑通。

el8 平台的 JDK 选型受限于归档仓库的内容,实测核验结果:8.4.2105 vault 中没有 java-17-openjdk 包(dnf list available "java-17-openjdk*" 无匹配),JDK 11 的最新补丁为 11.0.13.0.8-1.el8_4,Maven 为 3.5.4-6.el8。因此本文组合为 JDK 11 + Maven 3.5.4。若读者使用 8.5 及以上的小版本归档仓库,可自行检查是否已出现 java-17-openjdk,并相应提高 JDK 基线。

数据库适配是 4.0 的一个硬约束,实测核验结果:torque-runtime 4.0 内置适配器仅有 Mssql、Hsqldb、Mysql、Derby、Oracle、Postgres、None 七种(jar tf torque-runtime-4.0.jar | grep adapter 实测),不包含 H2 适配器;同时 SQL 生成模板包(org.apache.torque.templates.sql)支持的 DDL 方言也只有 derby、hsqldb、mssql、mysql、oracle、postgresql 六种。因此本文选用 Derby 10.14.2.0:完全嵌入、零安装,且官方模板原生支持。Derby 版本上有一个实测踩坑:10.16.1.1 的字节码是 Java 17(class file major 61),在 JDK 11 加载驱动直接抛 UnsupportedClassVersionError;10.14.2.0 是 Java 8 字节码,JDK 8/11/17 均实测可运行,故统一采用 10.14.2.0。

Maven Central 上的版本核验回显:

curl -s --max-time 30 https://repo1.maven.org/maven2/org/apache/torque/torque/maven-metadata.xml | grep -E "latest|<version>" | head -9
    <latest>7.0</latest>
    <release>7.0</release>
    <versions>
      <version>3.3</version>
      <version>4.0-beta1</version>
      <version>4.0</version>
      <version>5.0</version>
      <version>5.1</version>
      <version>6.0</version>
      <version>7.0</version>
    </versions>

四、方案 A:Maven 依赖安装(在线,推荐)

本节面向常规 Java 项目开发,先迁移 EOL 软件源,再通过 dnf 安装 JDK 11 与 Maven,配置 el8 特有的显式 JAVA_HOME,最后用 torque-maven-plugin 生成 OM 类与建表 SQL 并跑通增删改查。

4.1 方案说明

方案 A 的链路是:配置阿里云 vault 归档源 → dnf 安装 java-11-openjdk-devel 与 maven → 显式设置 JAVA_HOME 指向 JDK 11(el8 关键步骤)→ 创建 Maven 工程,声明 torque-maven-plugin(classpath 模板包模式)与 torque-runtime、Derby 依赖 → 手写 schema 并生成 OM 类与建表 DDL → 编译运行验证程序。优点是版本由 pom 统一管控、生成与编译一体化;缺点是首次构建需要联网下载依赖。

4.2 配置 EOL 软件源(vault 换源)

CentOS 8 EOL 后,镜像内置的 mirrorlist 指向已下线的 mirror 服务。直接把 mirror.centos.org 改成 vault.centos.org 是网上最常见的做法,但实测该域名在当前网络环境返回 403:

sed -i "s/mirror.centos.org/vault.centos.org/g; s/^#.*baseurl=http/baseurl=http/g; s/^mirrorlist=http/#mirrorlist=http/g" /etc/yum.repos.d/CentOS-*.repo
dnf -q makecache 2>&1 | tail -3
CentOS Linux 8 - AppStream                                                                                                                                                                             62  B/s |  38  B     00:01
Errors during downloading metadata for repository 'appstream':
  - Status code: 403 for https://vault.centos.org/8/AppStream/x86_64/os/repodata/repomd.xml
Error: Failed to download metadata for repo 'appstream': Cannot download repomd.xml: Cannot download repodata/repomd.xml: All mirrors were tried

实测结论:vault.centos.org 对本环境返回 403,dnf makecache 失败。改用阿里云归档源,重写 repo 文件(注意版本号 8.4.2105 与实际小版本一致):

rm -f /etc/yum.repos.d/CentOS-*.repo
cat > /etc/yum.repos.d/CentOS-Base.repo <<'EOF'
[baseos]
name=CentOS-8.4.2105 - BaseOS
baseurl=https://mirrors.aliyun.com/centos-vault/8.4.2105/BaseOS/x86_64/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
enabled=1

[appstream]
name=CentOS-8.4.2105 - AppStream
baseurl=https://mirrors.aliyun.com/centos-vault/8.4.2105/AppStream/x86_64/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
enabled=1

[extras]
name=CentOS-8.4.2105 - Extras
baseurl=https://mirrors.aliyun.com/centos-vault/8.4.2105/extras/x86_64/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
enabled=1
EOF
dnf -q makecache; echo "CACHE_EXIT=$?"
CACHE_EXIT=0

验证点:dnf makecache 返回码 0,三个仓库元数据全部拉取成功。

4.3 安装 JDK 11 与 Maven(含 el8 显式 JAVA_HOME)

查询归档仓库中可用的 JDK 与 Maven 版本(实时回显):

dnf -q list --showduplicates java-11-openjdk-devel 2>/dev/null | tail -3
dnf -q list --showduplicates maven | tail -2
Available Packages
java-11-openjdk-devel.x86_64    1:11.0.12.0.7-0.el8_4    appstream
java-11-openjdk-devel.x86_64    1:11.0.13.0.8-1.el8_4    appstream
Available Packages
maven.x86_64    3.5.4-6.el8    appstream

安装(实时回显):

dnf -q install -y java-11-openjdk-devel maven 2>&1 | tail -3
Installed:
  java-11-openjdk-11.0.13.0.8-1.el8_4.x86_64                          java-11-openjdk-devel-11.0.13.0.8-1.el8_4.x86_64
  java-11-openjdk-headless-11.0.13.0.8-1.el8_4.x86_64                 maven-3.5.4-6.el8.noarch

el8 关键事项:安装后系统默认 java 仍指向 JDK 8。 实测 java-11-openjdk 会把 java-1.8.0-openjdk 一并装入(作为依赖),且 alternatives 默认指针指向 1.8,/usr/bin/java 是 1.8.0_312,Maven 在未显式指定 JAVA_HOME 时也绑定 1.8:

java -version
mvn -v 2>/dev/null | grep -E "Apache Maven|Java version"
openjdk version "1.8.0_312"
Apache Maven 3.5.4 (Red Hat 3.5.4-5)
Java version: 1.8.0_312, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.312.b07-1.el8_4.x86_64/jre

这就是 el8 环境必须显式设置 JAVA_HOME 的原因。先确认 JDK 11 的实际安装路径,再在 shell 配置中固定(实时回显):

ls -d /usr/lib/jvm/java-11-openjdk-*
/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-1.el8_4.x86_64
cat >> /root/.bashrc <<'EOF'
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-1.el8_4.x86_64
export PATH=$JAVA_HOME/bin:$PATH
EOF
source /root/.bashrc
java -version
mvn -v 2>/dev/null | grep -E "Apache Maven|Java version"
openjdk version "11.0.13" 2026-10-19 LTS
OpenJDK Runtime Environment (build 11.0.13+8-LTS)
Apache Maven 3.5.4 (Red Hat 3.5.4-5)
Java version: 11.0.13, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-11-openjdk-11.0.13.0.8-1.el8_4.x86_64

验证点:mvn -v 的 Java version 从 1.8.0_312 变为 11.0.13,说明 Maven 已通过 JAVA_HOME 正确绑定 JDK 11。若希望系统级切换默认 java(对所有登录会话生效,含 ssh),可另行执行 alternatives --set java /usr/lib/jvm/java-11-openjdk-11.0.13.0.8-1.el8_4.x86_64/bin/java,两种方式选其一即可,本文采用 JAVA_HOME 方式(对 Maven/Gradle 等构建工具最可靠)。

4.4 创建工程与 schema

建立工程目录与数据库 schema 定义。Torque 的 schema 是一份手写 XML,描述表、列、主键与外键,是整个生成流程的唯一源头:

mkdir -p /root/torque-demo/src/main/schema
mkdir -p /root/torque-demo/src/main/java/com/example/torque
mkdir -p /root/torque-demo/src/main/resources

/root/torque-demo/src/main/schema/project-schema.xml 全文(bookstore 三表示例,直接照抄):

<?xml version="1.0" encoding="UTF-8"?>
<database name="bookstore" defaultIdMethod="native">
  <table name="publisher" description="Publisher table">
    <column name="publisher_id" primaryKey="true" required="true" type="INTEGER" description="Primary Key"/>
    <column name="name" type="VARCHAR" size="128" required="true" description="Publisher Name"/>
  </table>
  <table name="author" description="Author table">
    <column name="author_id" primaryKey="true" required="true" type="INTEGER" description="Primary Key"/>
    <column name="first_name" type="VARCHAR" size="128" required="true" description="First Name"/>
    <column name="last_name" type="VARCHAR" size="128" required="true" description="Last Name"/>
  </table>
  <table name="book" description="Book table">
    <column name="book_id" primaryKey="true" required="true" type="INTEGER" description="Primary Key"/>
    <column name="isbn" required="true" type="VARCHAR" size="24" description="ISBN"/>
    <column name="title" required="true" type="VARCHAR" size="255" description="Book Title"/>
    <column name="author_id" required="true" type="INTEGER" description="Foreign Key Author"/>
    <column name="publisher_id" required="true" type="INTEGER" description="Foreign Key Publisher"/>
    <foreign-key foreignTable="author" name="book_fk_author" onDelete="cascade">
      <reference local="author_id" foreign="author_id"/>
    </foreign-key>
    <foreign-key foreignTable="publisher" name="book_fk_publisher" onDelete="cascade">
      <reference local="publisher_id" foreign="publisher_id"/>
    </foreign-key>
  </table>
</database>

逐项说明关键配置:

  • database name="bookstore":数据库逻辑名,后续 torque.properties 与生成配置都要引用它。
  • defaultIdMethod="native":主键交给数据库自增机制(Derby 下生成 GENERATED BY DEFAULT AS IDENTITY 列),插入时无须手工赋主键。
  • type="INTEGER"、type="VARCHAR"、size="128":Torque 的逻辑类型,由 SQL 模板按目标数据库方言翻译成物理类型。
  • foreign-key + reference:声明 book 到 author、publisher 的外键;onDelete="cascade" 生成级联删除约束。

4.5 编写 pom.xml

/root/torque-demo/pom.xml 全文(直接照抄;该 pom 同时兼容 el8 自带的 Maven 3.5.4 与更新版本):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.torque</groupId>
  <artifactId>torque-demo</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.apache.torque</groupId>
      <artifactId>torque-runtime</artifactId>
      <version>4.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.derby</groupId>
      <artifactId>derby</artifactId>
      <version>10.14.2.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.derby</groupId>
      <artifactId>derbytools</artifactId>
      <version>10.14.2.0</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.torque</groupId>
        <artifactId>torque-maven-plugin</artifactId>
        <version>4.0</version>
        <dependencies>
          <dependency>
            <groupId>org.apache.torque</groupId>
            <artifactId>torque-templates</artifactId>
            <version>4.0</version>
          </dependency>
        </dependencies>
        <configuration>
          <packaging>classpath</packaging>
          <configPackage>org.apache.torque.templates.om</configPackage>
          <sourceDir>src/main/schema</sourceDir>
          <options>
            <torque.om.package>com.example.torque.om</torque.om.package>
          </options>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>3.2.0</version>
        <executions>
          <execution>
            <id>add-torque-sources</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>add-source</goal>
            </goals>
            <configuration>
              <sources>
                <source>target/generated-sources</source>
                <source>src/main/generated-java</source>
              </sources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

  <profiles>
    <profile>
      <id>sql</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.torque</groupId>
            <artifactId>torque-maven-plugin</artifactId>
            <version>4.0</version>
            <dependencies>
              <dependency>
                <groupId>org.apache.torque</groupId>
                <artifactId>torque-templates</artifactId>
                <version>4.0</version>
              </dependency>
            </dependencies>
            <configuration>
              <packaging>classpath</packaging>
              <configPackage>org.apache.torque.templates.sql</configPackage>
              <sourceDir>src/main/schema</sourceDir>
              <options>
                <torque.database>derby</torque.database>
                <torque.sql.generate.drops>true</torque.sql.generate.drops>
              </options>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>

逐项说明关键配置:

  • torque-runtime:4.0:运行期唯一 Torque 依赖,Maven 自动解析其传递依赖(commons-configuration 1.6、commons-dbcp 1.3、jcs 1.3、avalon-framework-api 4.3.1 等,共 11 个)。
  • derby:10.14.2.0 + derbytools:10.14.2.0:嵌入式数据库驱动(版本选型理由见第三章)。
  • 插件 packaging=classpath + configPackage=org.apache.torque.templates.om:直接以 classpath 上的模板包为生成配置(OM 生成模板自带 control 文件与全部模板),无须在工程里手写任何 control.xml 或模板;这是 torque-maven-plugin 4.0 最省事的用法。
  • sourceDir=src/main/schema:schema 源文件目录。不设置时插件默认找 src/main/torque-gen/src(实测报 Could not list files in the following Directory ... torque-gen/src),必须显式指向 schema 目录。
  • torque.om.package:生成类的 Java 包名,模板包强制要求该选项,缺失时实测报 Option torque.om.package must be set。
  • maven.compiler.source/target=8:4.0 生成代码与运行时的字节码基线,JDK 11 按此目标编译,Maven 3.5.4 默认绑定的 compiler 插件完全支持。
  • build-helper-maven-plugin:torque-maven-plugin 不会把生成目录注册为编译源目录(实测 mvn compile 直接报 No sources to compile),必须用该插件把 target/generated-sources(基类)与 src/main/generated-java(可编辑类)加入编译范围。
  • sql profile:同一个插件换用 org.apache.torque.templates.sql 模板包生成建表 DDL;torque.database=derby 指定方言(该选项同样强制,缺失时报 Option torque.database must be set)。

4.6 生成 OM 类与建表 SQL

生成 OM 类(实时回显):

cd /root/torque-demo && mvn -B torque:generate
[INFO] --- torque-maven-plugin:4.0:generate (default-cli) @ torque-demo ---
[INFO] Generation successful
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] Total time:  2.914 s

查看生成结果(实测共 24 个 Java 文件:target/generated-sources 下 12 个 Base* 基类 + src/main/generated-java 下 12 个可编辑业务类):

find target/generated-sources src/main/generated-java -name "*.java" | wc -l
ls src/main/generated-java/com/example/torque/om/
24
Author.java  AuthorPeer.java  AuthorPeerImpl.java  AuthorRecordMapper.java
Book.java    BookPeer.java    BookPeerImpl.java    BookRecordMapper.java
Publisher.java  PublisherPeer.java  PublisherPeerImpl.java  PublisherRecordMapper.java

Torque 4.0 的生成物按「两层目录」组织:target/generated-sources 下的 Base* 类每次生成重新覆盖,承载全部标准逻辑;src/main/generated-java 下的无前缀业务类仅首次生成,之后模板以 skip 策略跳过,专门留给用户改写定制。重新执行 mvn torque:generate 不会覆盖用户对业务类的修改,这是 Torque 生成式 ORM 的核心定制机制。

生成建表 SQL 并复制到资源目录(实时回显):

cd /root/torque-demo && mvn -B -q torque:generate -Psql 2>&1 | grep -E "Start generation" | head -2
cp target/generated-sources/project-schema.sql src/main/resources/schema.sql
INFO  org.apache.torque.generator.control.Controller - Processing output torque.sql.ddl
INFO  org.apache.torque.generator.control.Controller - Start generation of File /root/torque-demo/target/generated-sources/project-schema.sql

生成的 schema.sql 核心内容(实测):

drop table publisher;
drop table author;
drop table book;

CREATE TABLE publisher
(
    publisher_id INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    name VARCHAR(128) NOT NULL,
    PRIMARY KEY(publisher_id));

CREATE TABLE author
(
    author_id INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    first_name VARCHAR(128) NOT NULL,
    last_name VARCHAR(128) NOT NULL,
    PRIMARY KEY(author_id));

CREATE TABLE book
(
    book_id INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    isbn VARCHAR(24) NOT NULL,
    title VARCHAR(255) NOT NULL,
    author_id INTEGER NOT NULL,
    publisher_id INTEGER NOT NULL,
    PRIMARY KEY(book_id));

ALTER TABLE book
    ADD CONSTRAINT book_fk_author
    FOREIGN KEY (author_id)
    REFERENCES author (author_id)
    ON DELETE CASCADE;
ALTER TABLE book
    ADD CONSTRAINT book_fk_publisher
    FOREIGN KEY (publisher_id)
    REFERENCES publisher (publisher_id)
    ON DELETE CASCADE;

验证点:defaultIdMethod="native" 如约生成 GENERATED BY DEFAULT AS IDENTITY 自增列;两条 ADD CONSTRAINT 外键带 ON DELETE CASCADE 级联删除。

4.7 编写验证程序并编译运行

验证程序与运行时配置与平台无关:Main.java 与 torque.properties 的全文见《Ubuntu 22.04 安装 Apache Torque 指南》4.7 节,文件路径为 /root/torque-demo/src/main/java/com/example/torque/Main.java 与 /root/torque-demo/src/main/resources/torque.properties,内容一字不差照抄即可。其中两处与本平台直接相关的要点:其一,Class.forName("org.apache.derby.jdbc.EmbeddedDriver") 显式注册驱动的语句在本平台(JDK 11)必须保留,实测 Derby 10.14.2.0 的 JDBC SPI 声明在 JDK 11 不会被自动加载(JDK 17 会),不注册则报 No suitable driver found;其二,torque.properties 的数据源工厂键名为 4.0 新式的 torque.dsfactory.bookstore.factory(写 3.x 的 .factory.class 实测报 No DataSourceFactory definition for default DB found),连接口令示例为 q1w2e3r4。

在 CentOS 上编译并运行(注意最后一行的 -Dfile.encoding=UTF-8 为本平台必需项,原因见本节末尾实测对比):

cd /root/torque-demo && mvn -B -q compile && echo "EXIT=$?"
mvn -B -q dependency:build-classpath -Dmdep.outputFile=/tmp/cp.txt
java -Dfile.encoding=UTF-8 -cp "target/classes:$(cat /tmp/cp.txt)" com.example.torque.Main
---- [1] Torque.init ----
Torque.init 完成, 默认数据库=bookstore, 数据库注册表键=[bookstore, default]
---- [2] 执行生成的 DDL 建表 ----
执行 CREATE/ALTER 语句数=5 (3 张表 + 2 个外键)
---- [3] 新增 (save / 主键自动生成) ----
Publisher 落库: name=人民文学出版社 主键=1
Author 落库: 罗贯中 主键=1
Book 落库: 三国演义 主键=1 author_id=1 publisher_id=1
---- [4] 查询 (Criteria + Peer.doSelect) ----
doSelect 命中: id=1 姓名=罗贯中
doSelectJoinAuthor: 《三国演义》 作者=罗贯中
---- [5] 更新 (save / retrieveByPK) ----
retrieveByPK(1) 标题=三国演义(校注本) ISBN=9787020008728
---- [6] 删除 (doDelete) ----
删除 book_id=1 后, 剩余 Book 行数=0, Author 行数=1 (外键只级联删 book, 作者保留)
---- 全部步骤通过 ----

结果解读:六组演示全部按预期输出——Torque.init 识别 bookstore 数据源;生成的 DDL 成功建出 3 张表与 2 个外键;三次 save() 主键由 IDENTITY 自动分配(均为 1);条件查询与联表查询正确命中;更新后 retrieveByPK 回读一致;删除 book 后 Author 保留(级联只作用于 book 的外键)。这表示 Torque 4.0 生成器与运行时已在 CentOS 8 的 JDK 11 上完整可用。

-Dfile.encoding=UTF-8 在 el8 默认 locale(POSIX,即 ANSI_X3.4-1968)下是硬需求。本平台的实测对比——不加参数时:

doSelectJoinAuthor: ?????? ??=???
---- [5] ?? (save / retrieveByPK) ----
retrieveByPK(1) ??=????(???) ISBN=9787020008728

加上参数后(见上面完整回显)中文全部正常。除了运行时参数,也可以一次性设置系统 locale(export LANG=C.UTF-8)后省略该参数。

五、方案 B:官方 jar 直用(离线友好)

本节面向没有 Maven/构建体系的场景,从 Maven Central 直接下载 torque-runtime 与其全部依赖 jar,用 javac + java 完成编译运行,不依赖任何构建工具。

5.1 方案说明

链路是:下载 14 个运行期 jar 并校验 sha1 → 复用方案 A 已生成的 24 个 OM 源文件(生成物与构建工具无关,任何方式产出的源码都能编译)→ javac -cp 编译 → java -cp 运行。适用于离线环境、脚本化部署或纯粹想「拿到 jar 就能用」的读者。

5.2 下载依赖 jar 与完整性校验

torque-runtime 4.0 的完整运行期依赖经 mvn dependency:list 实测为 14 个 jar(含 Derby 驱动)。逐一下载(命令较长,分两条列出,全部实测):

mkdir -p /root/jar-run/lib && cd /root/jar-run/lib
R=https://repo1.maven.org/maven2
curl -sfO $R/org/apache/torque/torque-runtime/4.0/torque-runtime-4.0.jar
curl -sfO $R/commons-beanutils/commons-beanutils-core/1.8.0/commons-beanutils-core-1.8.0.jar
curl -sfO $R/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar
curl -sfO $R/commons-configuration/commons-configuration/1.6/commons-configuration-1.6.jar
curl -sfO $R/commons-dbcp/commons-dbcp/1.3/commons-dbcp-1.3.jar
curl -sfO $R/commons-digester/commons-digester/1.8/commons-digester-1.8.jar
curl -sfO $R/commons-lang/commons-lang/2.6/commons-lang-2.6.jar
curl -sfO $R/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar
curl -sfO $R/commons-pool/commons-pool/1.5.6/commons-pool-1.5.6.jar
curl -sfO $R/concurrent/concurrent/1.0/concurrent-1.0.jar
curl -sfO $R/org/apache/avalon/framework/avalon-framework-api/4.3.1/avalon-framework-api-4.3.1.jar
curl -sfO $R/org/apache/jcs/jcs/1.3/jcs-1.3.jar
curl -sfO $R/org/apache/derby/derby/10.14.2.0/derby-10.14.2.0.jar
curl -sfO $R/org/apache/derby/derbytools/10.14.2.0/derbytools-10.14.2.0.jar
ls -1 | wc -l
14

校验两个核心 jar 的 sha1(期望值取自仓库同名 .sha1 文件,与实测值必须逐字一致):

cd /root/jar-run/lib
echo "runtime 期望: $(curl -s $R/org/apache/torque/torque-runtime/4.0/torque-runtime-4.0.jar.sha1)"
echo "runtime 实测: $(sha1sum torque-runtime-4.0.jar | cut -d' ' -f1)"
echo "derby    期望: $(curl -s $R/org/apache/derby/derby/10.14.2.0/derby-10.14.2.0.jar.sha1)"
echo "derby    实测: $(sha1sum derby-10.14.2.0.jar | cut -d' ' -f1)"
runtime 期望: 88a2be8e73374586c480516fc085b2f8fea12968
runtime 实测: 88a2be8e73374586c480516fc085b2f8fea12968
derby    期望: 7efad40ef52fbb1f08142f07a83b42d29e47d8ce
derby    实测: 7efad40ef52fbb1f08142f07a83b42d29e47d8ce

两个核心 jar 的实测大小:torque-runtime-4.0.jar 为 228845 字节,derby-10.14.2.0.jar 为 3232770 字节,14 个 jar 合计约 6.4 MB。

⚠️ 注意:jar 清单必须与 pom 解析结果一致。缺 jar 运行时报 NoClassDefFoundError;多 jar 无害。若不放心清单完整性,可在方案 A 的工程上执行 mvn dependency:list 逐一比对。

5.3 javac 编译与 java 运行

准备源码与资源(OM 生成物 + 验证程序 + 配置):

cd /root/jar-run
mkdir -p src-om src-om-mod res out
cp -r /root/torque-demo/target/generated-sources/com src-om/
cp -r /root/torque-demo/src/main/generated-java/com src-om-mod/
cp /root/torque-demo/src/main/resources/torque.properties /root/torque-demo/src/main/resources/schema.sql res/

编译(24 个 OM 类 + Main,共 25 个编译单元):

javac -encoding UTF-8 -cp "lib/*" -d out \
  src-om/com/example/torque/om/*.java \
  src-om-mod/com/example/torque/om/*.java \
  /root/torque-demo/src/main/java/com/example/torque/Main.java
# 输出节选(实测)
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
15 warnings

验证点:编译成功产出 25 个 class;15 个警告全部是 new Integer(int) 构造器在 JDK 9+ 标记 deprecation 所致(2013 年生成代码的正常现象),不影响运行。

运行(注意 classpath 必须包含 res 目录,否则读不到 torque.properties 实测报 NullPointerException: inStream parameter is null;-Dfile.encoding=UTF-8 的原因见 4.7 节实测对比):

java -Dfile.encoding=UTF-8 -cp "out:res:lib/*" com.example.torque.Main
---- [1] Torque.init ----
Torque.init 完成, 默认数据库=bookstore, 数据库注册表键=[bookstore, default]
---- [2] 执行生成的 DDL 建表 ----
执行 CREATE/ALTER 语句数=5 (3 张表 + 2 个外键)
---- [3] 新增 (save / 主键自动生成) ----
Publisher 落库: name=人民文学出版社 主键=1
Author 落库: 罗贯中 主键=1
Book 落库: 三国演义 主键=1 author_id=1 publisher_id=1
---- [4] 查询 (Criteria + Peer.doSelect) ----
doSelect 命中: id=1 姓名=罗贯中
doSelectJoinAuthor: 《三国演义》 作者=罗贯中
---- [5] 更新 (save / retrieveByPK) ----
retrieveByPK(1) 标题=三国演义(校注本) ISBN=9787020008728
---- [6] 删除 (doDelete) ----
删除 book_id=1 后, 剩余 Book 行数=0, Author 行数=1 (外键只级联删 book, 作者保留)
---- 全部步骤通过 ----

验证点:java -cp 一行成功跑完六组结果,且无 NoClassDefFoundError,说明手工 classpath 可用;结果与方案 A 完全一致。

5.4 torque-generator 独立分发包的定位说明

Maven Central 的 org.apache.torque:torque-generator:4.0 另有 bin 分发包(torque-generator-4.0-bin.tar.gz,实测 4822484 字节),解压后为 torque-generator 主 jar 与 8 个依赖 jar。需要说明的是,4.0 版该包内没有命令行启动脚本,主 jar 的 MANIFEST 也没有 Main-Class(实测 jar tf 与 MANIFEST 核验),它面向 Ant 任务或自定义程序内嵌调用。想在无 Maven 环境做 OM 生成,本文 5.3 节的「预生成源码 + javac」方式即为可落地的替代路径;需要纯命令行生成的读者可评估 5.x 及以上版本的 generator 分发包。

六、方案对比与选择建议

本节汇总两种方案的差异,给出选型建议。两种方案运行的是同一份 Torque 4.0 代码与同一批生成类,差别仅在获取与装配方式。

维度方案 A:Maven 插件方案 B:jar 直用
OM 类生成mvn torque:generate 一键生成依赖方案 A 产出的源码(generator 4.0 无 CLI)
运行期依赖Maven 自动解析 14 个 jar手工下载 14 个 jar 并拼 classpath
是否联网首次构建需联网仅下载时需要联网
依赖版本管控pom 统一声明,可锁版本无,靠文件命名区分
完整性校验Maven 自动校验需手工比对 sha1
适用场景常规工程开发离线脚本、临时验证、无构建体系

选型建议:只要工程有构建体系,一律选方案 A——OM 生成是 Torque 的核心工作流,离开 Maven 插件(或 Ant 任务)无法完成;方案 B 的价值在于运行期部署:用方案 A 生成并提交源码后,运行环境完全可以无构建工具。两者也可共存——用方案 A 开发生成,用方案 B 分发运行。CentOS 平台的额外提示:方案 B 对 JDK 版本不敏感(只要能跑 torque-runtime 4.0 的 JDK 1.6+ 基线),比方案 A 更适合随应用分发的部署包。

七、配置说明

本节汇总 Torque 4.0 与 el8 平台实际需要设置的「配置」,分平台环境配置、生成期配置与运行期配置三组,全部实测核验。

7.1 平台环境配置(JAVA_HOME 与 locale)

  • JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-1.el8_4.x86_64:el8 的系统默认 java 是 1.8.0_312(实测 4.3 节),Maven、javac 等工具链全部依赖该变量选对 JDK,必须写入 /root/.bashrc 或等价的会话配置。
  • LANG=C.UTF-8(可选):一次性解决中文编码问题;不设置则所有 java 命令都要带 -Dfile.encoding=UTF-8(实测 4.7 节对比)。

7.2 Maven 插件(生成期)配置

  • packaging=classpath:生成配置的来源模式。classpath 模式从 classpath 上的模板包读取全部配置;默认值 directory 模式则要求工程提供 src/main/torque-gen/conf/control.xml(实测缺文件报 control file file /root/torque-demo/src/main/torque-gen/conf/control.xml not found)。快速上手选 classpath 模式。
  • configPackage=org.apache.torque.templates.om:OM 生成模板包。换 org.apache.torque.templates.sql 即生成 DDL(本文 sql profile)。
  • sourceDir=src/main/schema:schema 文件目录,默认值 src/main/torque-gen/src(实测目录不存在时直接报错)。
  • options.torque.om.package:生成类包名,必填。
  • 生成输出目录:基类固定写 target/generated-sources,可编辑类固定写 src/main/generated-java,两者均由插件默认值决定,一般无需调整。

7.3 torque.properties(运行期)配置

torque.database.default=bookstore
torque.database.bookstore.adapter=derby
torque.dsfactory.bookstore.factory=org.apache.torque.dsfactory.SharedPoolDataSourceFactory
torque.dsfactory.bookstore.connection.url=jdbc:derby:memory:bookstore;create=true
torque.dsfactory.bookstore.connection.user=sa
torque.dsfactory.bookstore.connection.password=q1w2e3r4

逐项说明:

  • torque.database.default:默认数据库逻辑名,Torque.getDefaultDB() 返回它,多库场景下每个库各有一组同名键。
  • adapter:数据库适配器,决定 ID 生成、SQL 方言等行为,可选值实测核验为 mssql/hsqldb/mysql/derby/oracle/postgres/none。
  • dsfactory.<库名>.factory:数据源工厂实现,SharedPoolDataSourceFactory 提供 DBCP 连接池。注意 4.0 的键名到此为止,没有 3.x 时代的 .class 后缀。
  • connection.url/user/password:直通连接池的 JDBC 三要素。connection.* 下其他属性(如 driver)会被 DBCP 拒绝(实测报 Property: driver ... is not supported by DataSource: DriverAdapterCPDS),驱动注册改在代码里显式 Class.forName 完成。
  • torque.dsfactory.bookstore.pool.*:连接池参数(如最大连接数),本文未配置时使用默认值,日常开发够用。

八、多版本管理

Torque 各大版本 artifact 坐标相同、JDK 基线不同,多版本共存靠「隔离依赖坐标 + 隔离 jar 文件名」实现。

Maven 本地仓库中不同版本的构件并列存放,互不覆盖(实时回显):

ls -1 $HOME/.m2/repository/org/apache/torque/torque-runtime/
4.0
5.1
7.0

要点:工程要用哪个版本,只改 pom.xml 的 <dependency><version> 即可,其余版本留在本地仓库供其他工程复用。但注意跨大版本切换不是改数字那么简单:5.x 起运行时拆分为多模块、6.0/7.0 抬高 JDK 基线、部分配置键有变化,切换前应查阅对应版本官网。jar 直跑场景,把不同版本 jar 分目录存放(如 /root/jar-run-7/lib),运行时按需拼 classpath。

切换工程依赖版本并验证生效(实时回显):

cd /root/torque-demo && mvn -B dependency:tree 2>&1 | grep torque | head -5
[INFO] +- org.apache.torque:torque-runtime:jar:4.0:compile
[INFO] |  +- commons-collections:commons-collections:jar:3.2.1:compile
[INFO] |  +- commons-configuration:commons-configuration:jar:1.6:compile
[INFO] |  +- commons-dbcp:commons-dbcp:jar:1.3:compile
[INFO] |  +- commons-lang:commons-lang:jar:2.6:compile

验证点:依赖树顶层是 torque-runtime:4.0,其下为核心传递依赖,与手工下载清单一致。

九、常见问题(FAQ)

Q1:dnf makecache 报 Status code: 403 for https://vault.centos.org/.../repomd.xml 怎么办? CentOS 8 EOL 后官方归档域名对多数网络环境返回 403(实测复现)。解决办法是把 repo 的 baseurl 指向可用的归档镜像(本文使用 mirrors.aliyun.com/centos-vault/8.4.2105/,见 4.2 节),注意 URL 中的小版本号必须与本机 /etc/os-release 对应的版本一致。

Q2:装完 java-11-openjdk-devel 后 java -version 还是显示 1.8.0_312? el8 会把 java-1.8.0-openjdk 作为依赖一并装入,且 alternatives 默认指针指向 1.8(实测 4.3 节回显)。解决:在 shell 配置中显式 export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-<版本号>.x86_64 并把 $JAVA_HOME/bin 加到 PATH 前面;需要全系统生效可另用 alternatives --set java ...。未显式设置时 Maven 也绑定 1.8(实测 mvn -v 显示 Java version: 1.8.0_312)。

Q3:程序中文输出全变成 ?????? el8 默认 locale 为 POSIX(ANSI_X3.4-1968),JVM 以 ASCII 输出字符串。解决:运行时加 -Dfile.encoding=UTF-8,或 export LANG=C.UTF-8(4.7 节有加与不加的实测对比回显)。

Q4:mvn torque:generate 报 control file file .../src/main/torque-gen/conf/control.xml not found? 插件默认 packaging=directory,要求工程自备 control.xml。快速上手直接在插件配置里写 <packaging>classpath</packaging> 与 <configPackage>org.apache.torque.templates.om</configPackage>,用官方模板包自带的生成配置(见 4.5 节),无需手写任何 control 文件。

Q5:报 Option torque.om.package must be set 或 Could not list files in the following Directory ... torque-gen/src? 前者:OM 模板包要求显式指定生成类包名,在插件 <configuration> 里加 <options><torque.om.package>你的包名</torque.om.package></options>。后者:classpath 模式下插件不会自动用 src/main/schema,必须显式 <sourceDir>src/main/schema</sourceDir>(均见 4.5 节)。

Q6:运行报 No suitable driver found for jdbc:derby:...? Torque 4.0 + commons-dbcp 1.3 的组合无法从 torque.properties 注入驱动类名(connection.driver/connection.driverClassName 均被拒绝),Derby 驱动又未必被 JDBC SPI 自动加载(实测 JDK 11 不会、JDK 17 会)。通用解法:在 Torque.init() 之前执行 Class.forName("org.apache.derby.jdbc.EmbeddedDriver")。

Q7:报 UnsupportedClassVersionError: org/apache/derby/jdbc/EmbeddedDriver has been compiled by a more recent version (class file version 61.0)? 用了 Derby 10.16.1.1——它是 Java 17 字节码,JDK 11 及以下无法加载(本文第三章实测踩坑)。把 Derby 降到 10.14.2.0(Java 8 字节码,JDK 8/11/17 全兼容)即可。

Q8:mvn compile 显示 BUILD SUCCESS 但类都编译不到,或运行报 ClassNotFoundException? torque-maven-plugin 不会把生成目录注册为编译源目录。确认 pom 已配置 build-helper-maven-plugin 并把 target/generated-sources 与 src/main/generated-java 加入 <sources>(见 4.5 节);只注册 target/generated-sources 时,Base* 类能编过而 Author 等业务类报 cannot find symbol。

十、卸载与清理

Torque 本身不产生系统级安装,卸载即移除依赖与本地文件。

移除工程与本地 jar(清理本文全部产物):

rm -rf /root/torque-demo /root/jar-run
ls /root/torque-demo 2>&1
ls: cannot access '/root/torque-demo': No such file or directory

移除 Maven 本地仓库中的 Torque 构件(影响所有工程,慎用):

rm -rf $HOME/.m2/repository/org/apache/torque

卸载 JDK 与 Maven(仅当不再需要)。先以 -s 预演确认将删除的包,无误后去掉 -s 真正执行:

dnf -s remove java-11-openjdk-devel maven
# 输出节选(实测)
Dependencies resolved.
=============================================================================================================================
 Package                             Architecture          Version                        Repository                   Size
=============================================================================================================================
Removing:
 java-11-openjdk-devel               x86_64                1:11.0.13.0.8-1.el8_4          @appstream                  49 M
 maven                               noarch                3.5.4-6.el8                    @appstream                  9.3 M

Transaction Summary
=============================================================================================================================
Remove  2 Packages

确认无误后真正卸载:

dnf remove -y java-11-openjdk-devel maven

恢复软件源(如需退回 EOL 前状态已不可能,保留阿里云 vault 源即可;若机器其他软件依赖 java 8,无需任何动作,alternatives 默认仍指向 1.8)。

十一、参考链接

  1. Apache Torque 官方主页:https://db.apache.org/torque/
  2. Torque 版本与 JDK 基线官方说明(官网首页):https://db.apache.org/torque/
  3. Maven 中央仓库 torque-runtime 坐标页:https://repo1.maven.org/maven2/org/apache/torque/torque-runtime/
  4. Maven 中央仓库 torque-maven-plugin 坐标页:https://repo1.maven.org/maven2/org/apache/torque/torque-maven-plugin/
  5. Maven 中央仓库 torque-generator 坐标页(含 4.0 bin 分发包):https://repo1.maven.org/maven2/org/apache/torque/torque-generator/
  6. 阿里云 CentOS 归档源(centos-vault):https://mirrors.aliyun.com/centos-vault/
  7. Apache Derby 官方站点:https://db.apache.org/derby/