简体   繁体   English

如何在Java中建立SPARQL查询?

[英]How to build SPARQL queries in java?

Is there a library, which is able to build SPARQL queries programmatically like the CriteriaBuilder in JPA or to build the queries like with a PreparedStatement for SQL? 是否有一个库,可以像JPA中的CriteriaBuilder一样以编程方式构建SPARQL查询,或者可以像使用PreparedStatement for SQL一样构建查询?

Similar (for SQL): Cleanest way to build an SQL string in Java 相似(对于SQL): 用Java构建SQL字符串的最简洁方法

The recent versions of Jena have added a StringBuilder style API for building query/update strings and parameterizing them if desired. Jena的最新版本添加了StringBuilder样式的API,用于构建查询/更新字符串并根据需要对其进行参数化。

This class is called ParameterizedSparqlString , here's an example of using it to create a query: 此类称为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();

Disclaimer - I'm the developer who contributed this functionality to Jena 免责声明 -我是为Jena贡献此功能的开发人员

See What's the best way to parametize SPARQL queries? 请参见参数化SPARQL查询的最佳方法是什么? for more discussion on doing this across various APIs. 有关跨各种API进行此操作的更多讨论。

You can build queries programmatically in Jena using two methods: syntax or algebra. 您可以使用两种方法在Jena中以编程方式构建查询:语法或代数。 There's an introduction in the jena wiki. 耶拿维基上有一个介绍

Using the algebra you'd do something like: 使用代数,您将执行以下操作:

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

(taken from the wiki page) (摘自Wiki页面)

It's not CriteriaBuilder (nor was it intended to be), but is some of the way there. 它不是CriteriaBuilder (也不是它的原意),而是其中的一些方式。 You OpJoin rather than AND, OpUnion when you want to OR, etc. The pain points are expressions in my experience: you probably want to parse them from a string. 您需要使用OpJoin而不是AND,需要进行OR时使用OpUnion等。痛点是我的经验表达:您可能想从字符串中解析它们。

I implemented SPARQL Java - a kind of DSL for writing SPARQL queries in Java. 我实现了SPARQL Java-一种用Java编写SPARQL查询的DSL。

It solves the problem with IDE's auto formatting of concatenated SPARQL query strings and things like that. 它解决了IDE对连接的SPARQL查询字符串等自动格式化的问题。

As for example: 例如:

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

I recently started to use Sesame query builder . 我最近开始使用Sesame查询构建器 It looks promising except it doesn't provide much documentation and I struggled to find examples. 它看起来很有希望,只是它没有提供太多文档,而且我很难找到示例。 Here is simple sample which may help you to get started: 这是一个简单的示例,可以帮助您入门:

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

Just note that isLiteral and cmResource are my own little static helper classes. 只需注意isLiteralcmResource是我自己的小静态帮助器类。 isLiteral stands for new IsLiteral(new Var("...")) for example where the latter one create URI with my heavily used prefix. isLiteral代表new IsLiteral(new Var("...")) ,例如,后者使用我经常使用的前缀创建URI。

You might be then also interested in SPARQLQueryRenderer which can turn ParsedQuery into String which may be convenient for further usage. 然后,您可能还对SPARQLQueryRenderer感兴趣,该SPARQLQueryRenderer可以将ParsedQuery转换为String ,这可能便于进一步使用。

If you end up using String(Builder) approach what I discourage you to do have at least a look on RenderUtils from sesame-queryrendered which has all the convenient methods to add < > around URIs, escape special characters etc. 如果你最终使用String(Builder)的方法是什么我不鼓励你这样做至少有一看RenderUtilssesame-queryrendered它具有所有方便的方法来添加< >周围的URI,转义特殊字符等。

The Eclipse RDF4J framework (the successor of Sesame) offers a Repository API which is somewhat similar to JDBC - it allows you to create a prepared Query object and inject variable bindings before executing it: Eclipse RDF4J框架 (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();

In addition, RDF4J has a SparqlBuilder (originally known as spanqit) - a Java DSL for SPARQL which allows you to create SPARQL queries in code like this: 另外,RDF4J具有一个SparqlBuilder (最初称为spanqit)-一种用于SPARQL的Java DSL,它允许您使用以下代码创建SPARQL查询:

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

I have just released a beta project to do just this, called Spanqit . 我刚刚发布了一个名为Spanqit的Beta版项目来执行此操作

I strove for readability and an intuitive interface, for example, here is some example Spanqit syntax for creating a query: 我力求可读性和直观的界面,例如,下面是一些用于创建查询的Spanqit语法示例:

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

Check it out, and feel free to comment and suggest improvements! 检查一下,随时发表评论并提出改进建议!

Jena provides a QueryBuilder in the Extras package. Jena在Extras包中提供了一个QueryBuilder。

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

It does what you want. 它可以满足您的需求。

You can use the Jena Semantic Framework ( SPARQL documentation ). 您可以使用Jena语义框架SPARQL文档 )。 Also take a look at this related question . 还要看看这个相关的问题 Sadly, its syntax is closer to a SQL PreparedStatement than to the JPA. 可悲的是,它的语法比JPA更接近SQL PreparedStatement。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM