jena

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的命名,

posted @ 2009-03-23 11:31  xiaomiao  阅读(610)  评论(1编辑  收藏  举报