使用JENA进行参数化SPARQL查询

san*_*dra 7 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();
}
Run Code Online (Sandbox Code Playgroud)

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

Rob*_*obV 6

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

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

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

使用最新的主干(从2.9.1-SNAPSHOT开始)有一个新的ParameterizedSparqlString类,这使得用户更友好,例如

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

Query query = QueryFactory.create(queryStr.toString());
Run Code Online (Sandbox Code Playgroud)

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

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