使用JENA进行参数化SPARQL查询

时间:2012-03-15 23:21:02

标签: java parameters sparql jena

我正在尝试使用Jena框架,JSP和JAVA构建一个小型语义Web应用程序。我有一个远程SPARQL端点,我已经写了一个简单的查询工作正常,但现在我需要使用一些参数。到目前为止,这是我的代码:

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();
}

我想要做的是参数化?name。我是Jena的新手,我不确定如何在SPARQL查询中使用参数。如果有人能帮助我,我将不胜感激。

2 个答案:

答案 0 :(得分:6)

如果您只想将变量限制为具有本地查询的特定值,则可以使用QueryFactory.create()方法的重载来执行此操作,该方法需要QuerySolutionMap来设置值限制。请注意,这不会改变您的查询只会限制最终结果,因此这不是真正的参数化。

如果你想真正拥有真正的参数化查询(即替换常量变量),那么根据你的ARQ版本,有几种方法可以做到这一点。

使用任何当前版本(最多2.9.0),唯一的方法是进行字符串连接,即在查询中不要使用?name,而只需插入所需的值,例如: “鲍勃”

使用最新的trunk(从2.​​9.1-SNAPSHOT开始)有一个新的ParameterizedSparqlString类,这使得用户更加友好,例如。

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

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

事实上,您可以进一步简化代码,因为ParameterizedSparqlString具有StringBuffer样式接口,可用于逐位构建查询,并包含有用的功能,例如在查询中添加前缀。

这种新方法的优点在于它提供了一种更通用的方式来执行参数化查询,这些查询也可以与更新一起使用,并且可用于准备现有方法未涵盖的远程查询。

答案 1 :(得分:2)

您可以尝试查看Twinkql。它是一个SPARQL到Java的映射框架。它在后端使用Jena,但尝试简化SPARQL查询和结果的Java绑定。

它允许您在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>

请注意#{novelName}占位符 - 这是参数可以在查询时传递的位置。

此外,结果可以绑定到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>

有一个API可以调用这些查询,传入参数等。它很像MyBatis,但对于SPARQL而不是SQL。