Code
//1、创建模型[Model](rdf模型)
//无怪乎是用一堆三元组表示
Model model = createModel() ;
//2、创建查询[Query]
Query query = QueryFactory.make() ;
//2-1、设置查询类型 为select型
query.setQueryType(Query.QueryTypeSelect) ;
//3、创建模式[Pattern]
//3-1、创建元素组[ElementGroup](组中每一个元素都是一个三元组模式[ElementTriplePattern])
ElementGroup elg = new ElementGroup() ;
//3-2、创建变量(Node类型)
Node varTitle = Node.createVariable("title") ;
Node varX = Node.createVariable("x") ;
//3-3、创建三元组(基于变量和谓词(或者叫属性))
Triple t1 = new Triple(varX, DC.title.asNode(), varTitle) ;
//3-4、创建三元组模式(基于三元组)
ElementTriplePattern tp1 = new ElementTriplePattern(t1) ;
//3-5、将三元组模式加入元素组中
elg.addElementTriplePattern(tp1) ;
//(3-2 --〉 3-5)可以重复多次,最终得到一个元素组[ElementGroup]
Triple t2 = new Triple(varX, DC.description.asNode(), Node.createVariable("desc")) ;
elg.addElementTriplePattern(new ElementTriplePattern(t2)) ;
//4、将元素组[ElementGroup]设置到查询[Query],
//这个元素组[ElementGroup]相当于SPARQL中的查询条件
query.setQueryPattern(elg) ;
//5、设置查询的选择结果,
//相当于SPARQL中的查询结果条目,就是select后面跟的部分
query.addResultVar(varTitle) ;
//下句可对序列化造成影响:
//如果有这一句,查询将序列化为引入PREFIX的文档,文档中的谓词(属性)将以前缀:名称形式出现;
//否则,将序列化为无PREFIX引入的文档,文档中的的谓词(属性)将以全名称形式出现。
//该句有无对查询结果无影响。
query.getPrefixMapping().setNsPrefix("dc" , DC.getURI()) ;
query.serialize(new IndentedWriter(System.out,true)) ;
System.out.println() ;
//6、将模型、查询一并交给查询引擎,执行查询
//查询的过程是一个模式匹配的过程,和prolog的机制应该一样,都和描述逻辑有关
QueryExecution qexec = QueryExecutionFactory.create(query, model) ;
//7、结果的显示。。。(现在还没仔细研究,再说)
//.
//8、最后别忘了吧查询引擎关掉,释放资源
//下面这一句话,就把查询引擎、模型、查询以及查询中由三元组模式构成的元素组全释放了
qexec.close() ;
QueryExecutionFactory.create()到底干了什么?QueryExecution如何被实例化?
实际上这是一个问题。从调用上来看,QueryExecution qexec = QueryExecutionFactory.create(query, model) ;就得到了一个实现QueryExecution接口的实例。仔细看了一下create方法,发现里面包含了很多层级,先将调用关系和类与接口层次关系描述出来,再看设计者为何要设置如此的层级。
QueryExecutionFactory.create(query, model)
-->QueryExecutionFactory.make(query, model)
-->QueryEngineFactory f = QueryEngineRegistry.get().find(query, dataset);
//QueryEngineRegistry.get() 返回该类的单例,该类构造为单例模式。该单例模式在构造的时候,不仅构造了一个QueryEngineRegistry的实例,另外还调用 DefaultEngineFactory.register()方法。先记着这么回事儿,继续。
//然后该单例通过find返回一个[实现QueryEngineFactory接口的实例]。
//如何返回这个[QueryEngineFactory接口的实例]成为注意的焦点
//QueryEngineRegistry该类实际上封装了一个以[实现QueryExecutionFactory接口实例]为元素的ArrayList
//该类通过find方法返回特定的[实现QueryEngineFactory接口的实例]
//通过addFactory()调用add()方法,向ArrayList添加实例。所以先找找在何处调用了该方法。
//经过查找project中,有QueryEngine2.register()和QueryEngine2_StagePlan.register()调用了该方法
//以QueryEngine2.register()为例,
<--QueryEngine2.register()
//该方法在调用 QueryEngineRegistry.addFactory()的时候,在实际参数的位置声明并实例化了QueryEngineFactory接口,
//实现了QueryEngineFactory接口的accept()与create()方法。
//这个create()方法的实现就是下面调用(f.create(query, dataset);)的实现。
//---------------------------------------------------------------------
//先告一段落,再回都看看上面记着的那回事儿:
-->DefaultEngineFactory.register(QueryEngineRegistry registry);
//这个方法new了一个DefaultEngineFactory实例
-->registry.add(new DefaultEngineFactory()) ; //给QueryEngineRegistry单例的ArrayList中添加了一个DefaultEngineFactory类的实例。我认为可以用 registry.add(new DefaultEngineFactory()) ;这句话代替。而DefaultEngineFactory类的实现了QueryEngineFactory接口,实现了accept();和 create()接口方法。
-->f.create(query, dataset);
//实现QueryEngineFactory接口的实例f用create()方法返回实现QueryExecution接口的实例。
//具体地,new QueryEngine实例qe.并调用qe.setDataSet方法设置qe的DataSet类型的dataset成员变量。
//qe的构造是以Query实例为参数的,构造的时候,将设置qe的Query类型的query成员变量,并设置qe的Context类型的成员变量context
//-----------------------------------------------------------------------------------
以下是上面涉及类与接口的继承关系
[I]QueryExecution
| |
| |
[C]QueryEngine |
| |
| |
[C]QueryEngine2 [C]QueryEngine2_StagePlan
[I]QueryEngineFactory
|
|
[C]DefaultEngineFactory
//-----------------------------------------------------------------------------------
//到此为止,就创建出了实例为QueryEngine类实例,或者为QueryEngine2或QueryEngine2_StagePlan类实例
//而看着几个类的构造的顺序
//QueryEngine2-->QueryEngine
//QueryEngine2_StagePlan-->QueryEngine2-->QueryEngine
//归根结底,这几个类实例的初始化都归结到了QueryEngine上
//看一下QueryEngine的构造函数,经过构造,QueryEngine会设置两个成员变量非别是Query类型和Context类型
//一个一个来
//Query == sparql语句
--从前面第一篇关于arq编程调用模式看,Query就是sparql语句在arq中的对象形式。
比如一个select sparql语句,经过编程调用,形成一个QueryTypeSelect 的Query实例,该实例会包含where条件等。
另外包含了序列化方法,以及深层拷贝的clone方法
//1.Query如何初始化?--这个没价值了,看看调用就清楚了,就是把sparql化为Query中属性的值的过程
//1+另外研究一下Query结构和sparql语法的对应关系还是比较有意义的,sparql语法参见:http://www.w3.org/TR/rdf-sparql-query/
//2.Query在执行过程中如何运作
//3.Query中涉及的几个重要对象
--int queryType:查询类型
--Syntax syntax:语法对象,继承自Symbol类,里面有用的实际是一个表示语法的url字符串
--List orderBy:顾名思义。。。
--List resultVars:调用者想返回的变量的名称们
--Element queryPattern:where语句,条件(们),这个对象的继承和集合比较有意思,无论是单体还是集合还有单体的各种类型都继承自抽象类Element类
--List resultNodes:查询返回的结果集合,还没来得及看组成成员细节
--PrefixMapping prefixMap:前缀url的命名,
//1、创建模型[Model](rdf模型)
//无怪乎是用一堆三元组表示
Model model = createModel() ;
//2、创建查询[Query]
Query query = QueryFactory.make() ;
//2-1、设置查询类型 为select型
query.setQueryType(Query.QueryTypeSelect) ;
//3、创建模式[Pattern]
//3-1、创建元素组[ElementGroup](组中每一个元素都是一个三元组模式[ElementTriplePattern])
ElementGroup elg = new ElementGroup() ;
//3-2、创建变量(Node类型)
Node varTitle = Node.createVariable("title") ;
Node varX = Node.createVariable("x") ;
//3-3、创建三元组(基于变量和谓词(或者叫属性))
Triple t1 = new Triple(varX, DC.title.asNode(), varTitle) ;
//3-4、创建三元组模式(基于三元组)
ElementTriplePattern tp1 = new ElementTriplePattern(t1) ;
//3-5、将三元组模式加入元素组中
elg.addElementTriplePattern(tp1) ;
//(3-2 --〉 3-5)可以重复多次,最终得到一个元素组[ElementGroup]
Triple t2 = new Triple(varX, DC.description.asNode(), Node.createVariable("desc")) ;
elg.addElementTriplePattern(new ElementTriplePattern(t2)) ;
//4、将元素组[ElementGroup]设置到查询[Query],
//这个元素组[ElementGroup]相当于SPARQL中的查询条件
query.setQueryPattern(elg) ;
//5、设置查询的选择结果,
//相当于SPARQL中的查询结果条目,就是select后面跟的部分
query.addResultVar(varTitle) ;
//下句可对序列化造成影响:
//如果有这一句,查询将序列化为引入PREFIX的文档,文档中的谓词(属性)将以前缀:名称形式出现;
//否则,将序列化为无PREFIX引入的文档,文档中的的谓词(属性)将以全名称形式出现。
//该句有无对查询结果无影响。
query.getPrefixMapping().setNsPrefix("dc" , DC.getURI()) ;
query.serialize(new IndentedWriter(System.out,true)) ;
System.out.println() ;
//6、将模型、查询一并交给查询引擎,执行查询
//查询的过程是一个模式匹配的过程,和prolog的机制应该一样,都和描述逻辑有关
QueryExecution qexec = QueryExecutionFactory.create(query, model) ;
//7、结果的显示。。。(现在还没仔细研究,再说)
//.
//8、最后别忘了吧查询引擎关掉,释放资源
//下面这一句话,就把查询引擎、模型、查询以及查询中由三元组模式构成的元素组全释放了
qexec.close() ;
QueryExecutionFactory.create()到底干了什么?QueryExecution如何被实例化?
实际上这是一个问题。从调用上来看,QueryExecution qexec = QueryExecutionFactory.create(query, model) ;就得到了一个实现QueryExecution接口的实例。仔细看了一下create方法,发现里面包含了很多层级,先将调用关系和类与接口层次关系描述出来,再看设计者为何要设置如此的层级。
QueryExecutionFactory.create(query, model)
-->QueryExecutionFactory.make(query, model)
-->QueryEngineFactory f = QueryEngineRegistry.get().find(query, dataset);
//QueryEngineRegistry.get() 返回该类的单例,该类构造为单例模式。该单例模式在构造的时候,不仅构造了一个QueryEngineRegistry的实例,另外还调用 DefaultEngineFactory.register()方法。先记着这么回事儿,继续。
//然后该单例通过find返回一个[实现QueryEngineFactory接口的实例]。
//如何返回这个[QueryEngineFactory接口的实例]成为注意的焦点
//QueryEngineRegistry该类实际上封装了一个以[实现QueryExecutionFactory接口实例]为元素的ArrayList
//该类通过find方法返回特定的[实现QueryEngineFactory接口的实例]
//通过addFactory()调用add()方法,向ArrayList添加实例。所以先找找在何处调用了该方法。
//经过查找project中,有QueryEngine2.register()和QueryEngine2_StagePlan.register()调用了该方法
//以QueryEngine2.register()为例,
<--QueryEngine2.register()
//该方法在调用 QueryEngineRegistry.addFactory()的时候,在实际参数的位置声明并实例化了QueryEngineFactory接口,
//实现了QueryEngineFactory接口的accept()与create()方法。
//这个create()方法的实现就是下面调用(f.create(query, dataset);)的实现。
//---------------------------------------------------------------------
//先告一段落,再回都看看上面记着的那回事儿:
-->DefaultEngineFactory.register(QueryEngineRegistry registry);
//这个方法new了一个DefaultEngineFactory实例
-->registry.add(new DefaultEngineFactory()) ; //给QueryEngineRegistry单例的ArrayList中添加了一个DefaultEngineFactory类的实例。我认为可以用 registry.add(new DefaultEngineFactory()) ;这句话代替。而DefaultEngineFactory类的实现了QueryEngineFactory接口,实现了accept();和 create()接口方法。
-->f.create(query, dataset);
//实现QueryEngineFactory接口的实例f用create()方法返回实现QueryExecution接口的实例。
//具体地,new QueryEngine实例qe.并调用qe.setDataSet方法设置qe的DataSet类型的dataset成员变量。
//qe的构造是以Query实例为参数的,构造的时候,将设置qe的Query类型的query成员变量,并设置qe的Context类型的成员变量context
//-----------------------------------------------------------------------------------
以下是上面涉及类与接口的继承关系
[I]QueryExecution
| |
| |
[C]QueryEngine |
| |
| |
[C]QueryEngine2 [C]QueryEngine2_StagePlan
[I]QueryEngineFactory
|
|
[C]DefaultEngineFactory
//-----------------------------------------------------------------------------------
//到此为止,就创建出了实例为QueryEngine类实例,或者为QueryEngine2或QueryEngine2_StagePlan类实例
//而看着几个类的构造的顺序
//QueryEngine2-->QueryEngine
//QueryEngine2_StagePlan-->QueryEngine2-->QueryEngine
//归根结底,这几个类实例的初始化都归结到了QueryEngine上
//看一下QueryEngine的构造函数,经过构造,QueryEngine会设置两个成员变量非别是Query类型和Context类型
//一个一个来
//Query == sparql语句
--从前面第一篇关于arq编程调用模式看,Query就是sparql语句在arq中的对象形式。
比如一个select sparql语句,经过编程调用,形成一个QueryTypeSelect 的Query实例,该实例会包含where条件等。
另外包含了序列化方法,以及深层拷贝的clone方法
//1.Query如何初始化?--这个没价值了,看看调用就清楚了,就是把sparql化为Query中属性的值的过程
//1+另外研究一下Query结构和sparql语法的对应关系还是比较有意义的,sparql语法参见:http://www.w3.org/TR/rdf-sparql-query/
//2.Query在执行过程中如何运作
//3.Query中涉及的几个重要对象
--int queryType:查询类型
--Syntax syntax:语法对象,继承自Symbol类,里面有用的实际是一个表示语法的url字符串
--List orderBy:顾名思义。。。
--List resultVars:调用者想返回的变量的名称们
--Element queryPattern:where语句,条件(们),这个对象的继承和集合比较有意思,无论是单体还是集合还有单体的各种类型都继承自抽象类Element类
--List resultNodes:查询返回的结果集合,还没来得及看组成成员细节
--PrefixMapping prefixMap:前缀url的命名,