如何在java中构建SPARQL查询?

是否有一个库,它能够以编程方式构建SPARQL查询,如JPA中的CriteriaBuilder ,或构建类似于PreparedStatement for SQL的查询?

类似(对于SQL): 在Java中构建SQL字符串的最简洁方法

您可以使用两种方法在Jena中以编程方式构建查询:语法或代数。 在jena wiki中有一个介绍 。

使用代数你会做类似的事情:

 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 

(摘自维基页面)

它不是CriteriaBuilder (也不是它的目的),而是它的一些方式。 当你想要OR时, OpJoin而不是AND, OpUnion等等。痛点是我的经验中的表达:你可能想要从字符串中解析它们。

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

这个类叫做ParameterizedSparqlString ,这里有一个用它来创建查询的例子:

 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贡献此function的开发人员

请参阅参数化SPARQL查询的最佳方法是什么? 有关在各种API中执行此操作的更多讨论。

我实现了SPARQL Java – 一种用于在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(); 

我最近开始使用Sesame查询构建器 。 它看起来很有希望,除了它没有提供太多的文档,我努力寻找例子。 这是一个简单的示例,可以帮助您入门:

 ParsedTupleQuery query = QueryBuilderFactory .select("pubProperty", "pubPropertyValue") .group() .atom(cmResource(resourceId), LinkPublicationsTransformation.REFERENCE_URI, "pubUri") .atom("pubUri", "pubProperty", "pubPropertyValue") .filter(isLiteral("pubPropertyValue")) .closeGroup() .query(); 

请注意, isLiteralcmResource是我自己的小静态助手类。 isLiteral代表new IsLiteral(new Var("...")) ,例如后者用我大量使用的前缀创建URI。

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

如果您最终使用String(Builder)方法,我不鼓励您至少看一下来自sesame-queryrendered ,它具有在URI周围添加< > ,转义特殊字符等所有方便的方法。

Sesame框架提供了一个与JDBC类似的Repository API – 它允许您在执行之前创建一个准备好的Query对象并注入变量绑定:

 String query = "SELECT * WHERE {?X ?P ?Y }"; TupleQuery preparedQuery = conn.prepareQuery(QuerLanguage.SPARQL, query); preparedQuery.setBinding("X", someValue); ... TupleQueryResult result = preparedQuery.evaluate(); 

Jena在Extras包中提供了QueryBuilder。

https://jena.apache.org/documentation/extras/querybuilder/index.html

它做你想要的。

您可以使用Jena语义框架 ( SPARQL文档 )。 另请看一下这个相关问题 。 可悲的是,它的语法更接近SQL PreparedStatement而不是JPA。

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

我努力寻求可读性和直观的界面,例如,这里有一些用于创建查询的Spanqit语法示例:

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

检查出来,随时评论并提出改进建议!