Apache Jena 常用 CLI 命令与工具详解

Apache Jena 6.2.0 常用 CLI 命令行工具详解,包含 sparql、rsparql、riot、tdb2.tdbloader/tdbquery/tdbupdate/tdbstats/tdbdump/tdbbackup 等工具的帮助参数与真实实测回显、常用操作示例。

Apache JenaApache JenaJavaApache运维2026/10/11

Apache Jena 常用 CLI 命令与工具详解

目标:详解 Apache Jena 6.2.0 命令行工具的使用方法。所有工具均位于 $JENA_HOME/bin(/usr/local/apache-jena-6.2.0/bin),文中每条命令的在本次 Ubuntu 22.04 实测环境中真实跑通并照抄回显。配好环境(JDK 21 + source /etc/profile.d/jena.sh)即可独立执行。

一、环境信息

  • Jena 版本:6.2.0,目录 /usr/local/apache-jena-6.2.0
  • 工具目录:/usr/local/apache-jena-6.2.0/bin
  • JDK:OpenJDK 21,JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
  • 示例数据:/opt/data/jena/hello.ttl;示例 TDB 库:/opt/data/jena/db/hello
  • 查询文件:/opt/data/jena/q1.rq
  • SPARQL 服务地址:http://127.0.0.1:3030/hello

二、工具概览

工具类别作用
sparql查询对本地文件/数据集执行 SPARQL 查询
rsparql查询对远程 SPARQL 服务(HTTP 端点)执行查询
riot解析解析并输出 RDF(支持 turtle、N-Triples、RDF/XML 等)
tdb2.tdbloaderTDB2批量把 RDF 数据载入 TDB2 数据库
tdb2.tdbqueryTDB2对 TDB2 数据库执行 SPARQL 查询
tdb2.tdbupdateTDB2对 TDB2 数据库执行 SPARQL Update(增删数据)
tdb2.tdbstatsTDB2统计 TDB2 数据库谓词分布
tdb2.tdbdumpTDB2把 TDB2 数据库导出为 RDF
tdb2.tdbbackupTDB2备份 TDB 数据集
rdfcatRDFRDF 集合/文件拼接转换
update更新执行 SPARQL Update 请求文件

三、前置条件

  • 已完成《Ubuntu 22.04 安装 Apache Jena 6.2.0 指南》的解压与环境变量配置,即 JENA_HOME 与 PATH 已配好;
  • JDK 21 可用(Jena 6.2.0 需要);
  • 需要远程查询的朋友需先启动 Fuseki(端口 3030)。

验证工具可用:

source /etc/profile.d/jena.sh
sparql --version

回显:

Apache Jena version 6.2.0

四、工具详解

4.1 riot:RDF 解析与格式转换

riot 用于解析 RDF 文件并输出为标准 RDF 序列化形式。

riot --version

回显:

Apache Jena RIOT version 6.2.0

解析示例文件 /opt/data/jena/hello.ttl:

riot /opt/data/jena/hello.ttl

回显(输出为 N-Quads 风格标准形式):

<http://example.org/alice> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
<http://example.org/alice> <http://xmlns.com/foaf/0.1/name> "Alice" .
<http://example.org/alice> <http://xmlns.com/foaf/0.1/mbox> <mailto:alice@example.org> .
<http://example.org/alice> <http://purl.org/dc/elements/1.1/title> "Software Engineer" .
<http://example.org/bob> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
<http://example.org/bob> <http://xmlns.com/foaf/0.1/name> "Bob" .
<http://example.org/bob> <http://xmlns.com/foaf/0.1/mbox> <mailto:bob@example.org> .
<http://example.org/bob> <http://xmlns.com/foaf/0.1/knows> <http://example.org/alice> .

4.2 sparql:对本地 TDB 数据/文件执行查询

sparql --help 关键参数(实测回显):

sparql --data=<file> --query=<query>
  Query
      --query, --file        File containing a query
      --syntax, --in         Syntax of the query
      --base                 Base URI for the query
  Results
      --results=             Results format (Result set: text, XML, JSON, CSV, TSV; Graph: RDF serialization)
  Dataset
      --data=FILE            Data for the dataset - triple or quad formats.

对 TDB2 数据库查询需用 tdb2.tdbquery --loc=/opt/data/jena/db/hello(见 4.3),其参数与 sparql 一致。

4.3 tdb2.tdbquery:对 TDB2 数据库执行 SPARQL 查询

tdb2.tdbquery --help 关键参数(实测回显):

tdbquery --loc=<path> --query=<query>
  Location
      --loc=DIR              Location (a directory)
      --tdb=                 Assembler description file
  Query
      --query, --file        File containing a query
  Results
      --results=             Results format (Result set: text, XML, JSON, CSV, TSV; Graph: RDF serialization)

准备查询文件:

cat > /opt/data/jena/q1.rq <<'EOF'
SELECT ?s ?n WHERE { ?s <http://xmlns.com/foaf/0.1/name> ?n }
EOF

执行查询:

tdb2.tdbquery --loc=/opt/data/jena/db/hello --query=/opt/data/jena/q1.rq

回显:

----------------------------------------
| s                          | n       |
========================================
| <http://example.org/alice> | "Alice" |
| <http://example.org/bob>   | "Bob"   |
----------------------------------------

⚠️ 说明:--query= 后接的是查询文件路径,不是内联查询字符串。若把语句直接放在 = 后,会报 Failed to load Query: Not found: SELECT ?s ?n WHERE { ?s <http://xmlns.com/foaf/0.1/name> ?n }(整条语句被当作文件名)。本文统一用文件形式。

4.4 tdb2.tdbloader:批量加载数据到 TDB2

tdb2.tdbloader --help 关键参数(实测回显,--loader 默认 phased):

tdbloader --loader= [--desc DATASET | --loc DIR] FILE ...
  Location
      --loc=DIR              Location (a directory)
      --graph=IRI            Act on a named graph
      --loader=              Loader to use: 'basic', 'phased' (default), 'sequential', 'parallel' or 'light'

创建 TDB2 库并载入数据:

mkdir -p /opt/data/jena/db/hello
tdb2.tdbloader --loc=/opt/data/jena/db/hello /opt/data/jena/hello.ttl

回显:

11:11:28 INFO  loader          :: Loader = LoaderPhased
11:11:28 INFO  loader          :: Start: /opt/data/jena/hello.ttl
11:11:28 INFO  loader          :: Finished: /opt/data/jena/hello.ttl: 8 tuples in 0.16s (Avg: 51)
11:11:28 INFO  loader          :: Finish - index SPO
11:11:28 INFO  loader          :: Index set:  SPO => SPO->POS, SPO->OSP
11:11:28 INFO  loader          :: Index set:  SPO => SPO->POS, SPO->OSP [8 items, 0.0 seconds]
11:11:28 INFO  loader          :: Finish - index POS
11:11:28 INFO  loader          :: Finish - index OSP

载入后目录结构:

/opt/data/jena/db/hello/
├── Data-0001/
└── tdb.lock

4.5 tdb2.tdbstats:统计数据集谓词分布

tdb2.tdbstats --loc=/opt/data/jena/db/hello

回显(统计每个谓词出现的三元组数):

(stats
  (meta
    (timestamp "2026-10-11T11:11:38.994+00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime>)
    (run@ "2026/10/11 11:11:38 GMT")
    (count 8))
  ((VAR <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person>)
   2)
  (<http://xmlns.com/foaf/0.1/mbox> 2)
  (<http://xmlns.com/foaf/0.1/name> 2)
  (<http://xmlns.com/foaf/0.1/knows> 1)
  (<http://purl.org/dc/elements/1.1/title> 1)
  (<http://www.w3.org/1999/02/22-rdf-syntax-ns#type> 2)
  (other 0))

4.6 tdb2.tdbdump:导出数据集为 RDF

tdb2.tdbdump --help 关键参数:

tdbdump : Write a dataset to stdout (defaults to N-Quads)
  Output control
      --formatted=FMT        Output, using pretty printing (consumes memory)
      --stream=FMT           Output, using a streaming format
      --compress             Compress the output with gzip
  Location
      --loc=DIR              Location (a directory)

导出默认图:

tdb2.tdbdump --loc=/opt/data/jena/db/hello

回显(节选):

<http://example.org/alice> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
<http://example.org/alice> <http://xmlns.com/foaf/0.1/name> "Alice" .
<http://example.org/alice> <http://xmlns.com/foaf/0.1/mbox> <mailto:alice@example.org> .
<http://example.org/alice> <http://purl.org/dc/elements/1.1/title> "Software Engineer" .
<http://example.org/bob> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .

4.7 tdb2.tdbupdate:执行 SPARQL Update 写入数据

tdb2.tdbupdate --help 关键参数:

tdbupdate --desc=assembler [--dump] --update=<request file>
  Location
      --loc=DIR              Location (a directory)
      --update=FILE          Update commands to execute
      --dump                 Dump the resulting graph store

准备更新文件并执行:

cat > /opt/data/jena/u1.ru <<'EOF'
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
INSERT DATA { <http://example.org/dave> foaf:name "Dave" }
EOF
tdb2.tdbupdate --loc=/opt/data/jena/db/hello --update=/opt/data/jena/u1.ru

⚠️ 说明:若该数据集正被 Fuseki 占用,执行会报 Failed to get a lock: file=/opt/data/jena/db/hello/tdb.lock: held by process 6514。需先停止 Fuseki,见「六、注意事项」。

4.8 tdb2.tdbbackup:备份 TDB 数据集

tdb2.tdbbackup --help 关键参数:

tdbbackup : Backup a TDB dataset
  Output control
      --compress             Compress the output with gzip
  Location
      --loc=DIR              Location (a directory)

备份到 hello.nq.gz:

tdb2.tdbbackup --loc=/opt/data/jena/db/hello --output=/opt/data/jena/backup.nq.gz

4.9 rsparql:查询远程 Fuseki SPARQL 端点

rsparql 用于向 HTTP SPARQL 服务器发送查询(需先启动 Fuseki,见安装指南 5.3 节):

rsparql --service=http://127.0.0.1:3030/hello --query=/opt/data/jena/q1.rq

回显(实时命中 Fuseki 上的 /hello 数据集):

----------------------------------------
| s                          | n       |
========================================
| <http://example.org/alice> | "Alice" |
| <http://example.org/bob>   | "Bob"   |
| <http://example.org/carol> | "Carol" |
----------------------------------------

⚠️ 说明:远程查询请用 rsparql 而不是 sparql --service——Jena 6.2.0 的 sparql 命令会报 Unknown argument: service。rsparql 的 --service= 参数指 SPARQL 服务 URL。

4.10 rdfcat:RDF 拼接 / 转换

rdfcat /opt/data/jena/hello.ttl

输出为 RDF 标准形式(同上 4.1,故此处不重复列出完整回显)。可用 --out 指定输出格式。

五、注意事项

  • Jena 6.2.0 必须 JDK 21,否则各工具启动报 UnsupportedClassVersionError。
  • --query= / --update= 接的是文件,内联语句需改用文件或标准输入。
  • 同一数据集不可同时被命令线与 Fuseki 打开:Fuseki 持锁时 tdb2.* 工具报 Failed to get a lock。用 --loc 指向尚未被占用的副本目录即可离线操作。
  • 远程查询用 rsparql,本地用 sparql / tdb2.tdbquery。
  • 删除/清空数据集前先备份(tdb2.tdbbackup)。

六、常见问题(FAQ)

Q1:sparql --service=http://127.0.0.1:3030/hello 报 Unknown argument: service? 答:Jena 6.2.0 的 sparql 不支持内联 --service。远程查询请用 rsparql --service=。

Q2:tdb2.tdbquery 报 Failed to load Query: Not found: SELECT ?s ?n WHERE { ?s <http://xmlns.com/foaf/0.1/name> ?n }? 答:--query= 参数需要查询文件路径;把整句 SPARQL 直接写在 = 后会被当成文件名。先将查询写入 .rq 文件,再传文件路径。

Q3:tdb2.tdbupdate 报 Failed to get a lock: file=/opt/data/jena/db/hello/tdb.lock: held by process 6514? 答:数据集正被其他进程(通常是 Fuseki)占用。停止占用进程或改用另一副本目录:

pkill -f fuseki-server
tdb2.tdbupdate --loc=/opt/data/jena/db/hello --update=/opt/data/jena/u1.ru

Q4:命令报 LinkageError / UnsupportedClassVersionError? 答:JVM 版本过旧。确认使用 JDK 21:readlink -f $(which java) 应指向 java-21-openjdk-amd64。

七、参考链接