如何在java中构建SPARQL查询?

如何在java中构建SPARQL查询?,java,string,sparql,Java,String,Sparql,是否有一个库能够像JPA中的CriteriaBuilder那样以编程方式构建SPARQL查询,或者像SQL中的PreparedStatement那样构建查询 类似(对于SQL):您可以使用()。也来看看。遗憾的是,它的语法更接近SQL PreparedStatement,而不是JPA。您可以使用两种方法在Jena中以编程方式构建查询:语法或代数。耶拿维基上有一个 使用代数,您可以执行以下操作: Op op; BasicPattern pat = new BasicPattern();

是否有一个库能够像JPA中的
CriteriaBuilder
那样以编程方式构建SPARQL查询,或者像SQL中的
PreparedStatement
那样构建查询


类似(对于SQL):

您可以使用()。也来看看。遗憾的是,它的语法更接近SQL PreparedStatement,而不是JPA。

您可以使用两种方法在Jena中以编程方式构建查询:语法或代数。耶拿维基上有一个

使用代数,您可以执行以下操作:

Op op;
BasicPattern pat = new BasicPattern();                 // Make a pattern
pat.add(pattern);                                      // Add our pattern match
op = new OpBGP(pat);                                   // Make a BGP from this pattern
op = OpFilter.filter(e, op);                           // Filter that pattern with our expression
op = new OpProject(op, Arrays.asList(Var.alloc("s"))); // Reduce to just ?s
Query q = OpAsQuery.asQuery(op);                       // Convert to a query
q.setQuerySelectType();                                // Make is a select query
(摘自wiki页面)

它不是
CriteriaBuilder
(也不是有意的),而是某种方式。当你想或等的时候,你可以
OpJoin
而不是AND,
OpUnion
。我的经验中的痛点是表达式:你可能想从字符串中解析它们。

The(Sesame的继承者)提供了一个类似于JDBC的存储库API—它允许您创建一个准备好的查询对象,并在执行之前插入变量绑定:

String query = "SELECT * WHERE {?X ?P ?Y }";
TupleQuery preparedQuery = conn.prepareQuery(QuerLanguage.SPARQL, query);
preparedQuery.setBinding("X", someValue);
...
TupleQueryResult result = preparedQuery.evaluate();
此外,RDF4J还有一个(最初称为spanqit)用于SPARQL的Java DSL,它允许您在如下代码中创建SPARQL查询:

query.prefix(foaf).select(name)
    .where(x.has(foaf.iri("name"), name))
    .orderBy(name)
    .limit(5)
    .offset(10);

Jena的最新版本添加了一个
StringBuilder
风格的API,用于构建查询/更新字符串,并根据需要对其进行参数化

这个类被调用,下面是一个使用它创建查询的示例:

ParameterizedSparqlString queryStr = new ParameterizedSparqlString();
queryStr.setNSPrefix("sw", "http://skunkworks.example.com/redacted#");
queryStr.append("SELECT ?a ?b ?c ?d");
queryStr.append("{");
queryStr.append("   ?rawHit sw:key");
queryStr.appendNode(someKey);
queryStr.append(".");
queryStr.append("  ?rawHit sw:a ?a .");
queryStr.append("  ?rawHit sw:b ?b .");
queryStr.append("  ?rawHit sw:c ?c . ");
queryStr.append("  ?rawHit sw:d ?d .");
queryStr.append("} ORDER BY DESC(d)");

Query q = queryStr.asQuery();
免责声明-我是将此功能贡献给Jena的开发人员

有关跨各种API执行此操作的更多讨论,请参阅。

我实现了—一种用Java编写SPARQL查询的DSL

它解决了IDE自动格式化串联SPARQL查询字符串之类的问题

例如:

String shortQuery = Q.prefix("books", "http://example.org/books#")
            .select("?book ?authorName", new where() {
                {
                    $("?book books:author ?author");
                    $("?author books:authorName ?authorName");
                }
            }).get();

我刚刚发布了一个测试版项目,名为

我力求可读性和直观的界面,例如,下面是创建查询的一些示例Spanqit语法:

query.prefix(foaf)。选择(名称)
.其中(x.has(foaf.iri(“名称”),名称))
.orderBy(姓名)
.限额(5)
.抵销(10);

请查看,并随时发表评论和提出改进建议

Jena在Extras包中提供了一个QueryBuilder

它可以满足您的需要。

我最近开始使用它。它看起来很有希望,只是它没有提供太多的文档,我很难找到例子。下面是一个简单的示例,可以帮助您入门:

ParsedTupleQuery query = QueryBuilderFactory
            .select("pubProperty", "pubPropertyValue")
                .group()
                    .atom(cmResource(resourceId), LinkPublicationsTransformation.REFERENCE_URI, "pubUri")
                    .atom("pubUri", "pubProperty", "pubPropertyValue")
                    .filter(isLiteral("pubPropertyValue"))
                .closeGroup()
            .query();
请注意,
isLiteral
cmResource
是我自己的小静态助手类
isLiteral
代表
newisliteral(newvar(“…”)
例如,后者使用我频繁使用的前缀创建URI

您可能还对
SPARQLQueryRenderer
感兴趣,它可以将
ParsedQuery
转换为
String
,以便进一步使用


如果您最终使用了
String(Builder)
方法(我不鼓励您这么做),请至少查看
sesame queryrendered
中的
RenderUtils
,它提供了在URI周围添加
的所有方便方法,转义特殊字符等。

但是链接问题上使用的语法是我要避免的。我误解了你的问题。我还发现了其他一些关于一个名为“Empire”的库的链接,它是一个类似JPA的接口,在幕后使用SPARQL(),但我在github上找不到源代码。我终于在上找到了它,但我以前从未使用过它。我希望它能满足你的需要,尽管开始使用它似乎很困难:运气好吗?我想要一些反馈!直到现在,谢谢你的提醒。我将测试这个项目已经被Eclipse基金会项目RDF4J采纳,在这里查看文档:这个答案有点过时了:这个QueryBuilder现在已经过时了,已经被RDF4J SPARQLBu建器取代了——参见