简体   繁体   English

使用JENA进行参数化SPARQL查询

[英]Parameterized SPARQL query with JENA

I'm trying to build a small semantic web application using Jena framework, JSP and JAVA. 我正在尝试使用Jena框架,JSP和JAVA构建一个小型语义Web应用程序。 I have a remote SPARQL endpoint and I've already written a simple query which works fine but now I need to use some parameters. 我有一个远程SPARQL端点,我已经写了一个简单的查询工作正常,但现在我需要使用一些参数。 Here is my code so far: 到目前为止,这是我的代码:

final static String serviceEndpoint = "http://fishdelish.cs.man.ac.uk/sparql/";

String comNameQuery = 
        "PREFIX fd: <http://fishdelish.cs.man.ac.uk/rdf/vocab/resource/> " +
        "SELECT ?name ?language ?type" +
        "WHERE { ?nameID fd:comnames_ComName ?name ;" +
        "fd:comnames_Language ?language ;" +
        "fd:comnames_NameType ?type ." +
        "}";

Query query = QueryFactory.create(comNameQuery);  
QueryExecution qe = QueryExecutionFactory.sparqlService(serviceEndpoint,query);

try {
    ResultSet rs = qe.execSelect();
    if ( rs.hasNext() ) {
        System.out.println(ResultSetFormatter.asText(rs));
    }
} 
catch(Exception e) { 
    System.out.println(e.getMessage());
}
finally {
    qe.close();
}

What I want to do is to parameterized ?name. 我想要做的是参数化?name。 I'm new to Jena and I'm not really sure how to use parameters in a SPARQL query. 我是Jena的新手,我不确定如何在SPARQL查询中使用参数。 I would appreciate it if someone could help me with this. 如果有人能帮助我,我将不胜感激。

If you just want to restrict a variable to have a certain value for local queries you can do so with an overload of the QueryFactory.create() method which takes a QuerySolutionMap to set value restrictions. 如果您只想将变量限制为具有本地查询的特定值,则可以使用QueryFactory.create()方法的重载来执行此操作,该方法使QuerySolutionMap设置值限制。 Note this doesn't alter your query just restricts the final results so this is not really parameterization. 请注意,这不会改变您的查询只会限制最终结果,因此这不是真正的参数化。

If you want to actually have true parameterized queries (ie substitute variables for constants) then there are a couple of ways to do this depending on your version of ARQ. 如果你想真正拥有真正的参数化查询(即常量的替换变量),那么有几种方法可以做到这一点,具体取决于你的ARQ版本。

Using any current release (up to 2.9.0) the only way to do it is string concatenation ie instead of having ?name in your query you would just insert the value you want eg "Bob" 使用任何当前版本(最高2.9.0),唯一的方法是进行字符串连接,即在查询中不使用?name,只需插入所需的值,例如“Bob”

Using the latest trunk (2.9.1-SNAPSHOT onwards) there is a new ParameterizedSparqlString class which makes this much more user friendly eg 使用最新的主干(从2.9.1-SNAPSHOT开始)有一个新的ParameterizedSparqlString类,这使得用户更友好,例如

ParameterizedSparqlString queryStr = new ParameterizedSparqlString(comNameQuery);
queryStr.setLiteral("name", "Bob");

Query query = QueryFactory.create(queryStr.toString());

And in fact you can simplify your code further since ParameterizedSparqlString has a StringBuffer style interface and can be used to build your query bit by bit and includes useful functionality like prepending prefixes to your query. 事实上,您可以进一步简化代码,因为ParameterizedSparqlString具有StringBuffer样式接口,可用于逐位构建查询,并包含有用的功能,例如在查询中添加前缀。

The advantage of this new method is that it provides a more generic way of doing parameterized queries that can also be used with updates and is usable for preparing remote queries which the existing methods do not cover. 这种新方法的优点在于它提供了一种更通用的方式来进行参数化查询,这些查询也可以与更新一起使用,并且可用于准备现有方法未涵盖的远程查询。

You could try looking into Twinkql . 您可以尝试查看Twinkql It is a SPARQL-to-Java mapping framework. 它是一个SPARQL到Java的映射框架。 It uses Jena in the back end, but tries to simplify SPARQL queries and Java binding of the results. 它在后端使用Jena,但尝试简化SPARQL查询和结果的Java绑定。

It allows you to define SPARQL queries in xml: 它允许您在xml中定义SPARQL查询:

<select id="getNovel" resultMap="novelResultMap">
<![CDATA[
    SELECT ?novel ?author
    WHERE {
        ?novel a <http://dbpedia.org/class/yago/EnglishNovels> ;
            <http://dbpedia.org/property/name> "#{novelName}"@en ;
            <http://dbpedia.org/property/author> ?author .
    }
]]>
</select>

Note the #{novelName} placeholder -- this is where parameters can be passed in at query time. 注意#{novelName}占位符 - 这是参数可以在查询时传递的位置。

Also, results can be bound to Java Beans: 此外,结果可以绑定到Java Bean:

<resultMap id="novelResultMap" resultClass="org.twinkql.example.Novel">
    <uniqueResult>novel</uniqueResult>
    <rowMap  var="novel" varType="localName" beanProperty="name" />
    <rowMap var="author" varType="localName" beanProperty="author"/>
</resultMap>

There is an API to call these queries, to pass in parameters, etc. It is much like MyBatis , but for SPARQL instead of SQL. 有一个API来调用这些查询,传入参数等。它很像MyBatis ,但对于SPARQL而不是SQL。

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

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