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 PreparedStateme
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:
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:
query.prefix(foaf).select(name)
.where(x.has(foaf.iri("name"), name))
.orderBy(name)
.limit(5)
.offset(10);
The recent versions of Jena have added a StringBuilder
style API for building query/update strings and parameterizing them if desired.
This class is called ParameterizedSparqlString, here's an example of using it to create a query:
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
See What's the best way to parametize SPARQL queries? for more discussion on doing this across various APIs.
I have just released a beta project to do just this, called Spanqit.
I strove for readability and an intuitive interface, for example, here is some example Spanqit syntax for creating a query:
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!
You can build queries programmatically in Jena using two methods: syntax or algebra. 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)
It's not CriteriaBuilder
(nor was it intended to be), but is some of the way there. 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.
You can use the Jena Semantic Framework (SPARQL documentation). Also take a look at this related question. Sadly, its syntax is closer to a SQL PreparedStatement than to the JPA.
I recently started to use Sesame query builder. 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. isLiteral
stands for new IsLiteral(new Var("..."))
for example where the latter one create URI with my heavily used prefix.
You might be then also interested in SPARQLQueryRenderer
which can turn ParsedQuery
into String
which may be convenient for further usage.
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.