Apache Jena 常用 CLI 命令与工具详解
Apache Jena 6.2.0 常用 CLI 命令行工具详解,包含 sparql、rsparql、riot、tdb2.tdbloader/tdbquery/tdbupdate/tdbstats/tdbdump/tdbbackup 等工具的帮助参数与真实实测回显、常用操作示例。
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.tdbloader | TDB2 | 批量把 RDF 数据载入 TDB2 数据库 |
tdb2.tdbquery | TDB2 | 对 TDB2 数据库执行 SPARQL 查询 |
tdb2.tdbupdate | TDB2 | 对 TDB2 数据库执行 SPARQL Update(增删数据) |
tdb2.tdbstats | TDB2 | 统计 TDB2 数据库谓词分布 |
tdb2.tdbdump | TDB2 | 把 TDB2 数据库导出为 RDF |
tdb2.tdbbackup | TDB2 | 备份 TDB 数据集 |
rdfcat | RDF | RDF 集合/文件拼接转换 |
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。
七、参考链接
- Apache Jena 命令行工具文档:https://jena.apache.org/documentation/tools/
- Jena ARQ SPARQL 查询:https://jena.apache.org/documentation/query/commandline.html
- Jena TDB 存储:https://jena.apache.org/documentation/tdb/
- RDF 框架 RIOT 解析:https://jena.apache.org/documentation/io/