如何在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();
请注意, isLiteral
和cmResource
是我自己的小静态助手类。 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);
检查出来,随时评论并提出改进建议!