导入本体到Jena TDB数据库

本体的存储方法或称本体持久化,大致分为基于内存的方式、基于文件的方式、基于数据库的方式和专门的管理工具方式4种(傅柱等, 2013)。其中,基于数据库的方式又有基于关系数据库、基于面向对象数据库、基于Native XML数据库和基于NoSQL的三元组数据库(Triple Store)4种主要方式。基于数据库的本体持久化方式充分利用了数据库的安全可靠(数据保密、数据完整性、并发控制、故障恢复等)、高效、易于管理并易于与应用系统集成等优点,是主要的本体持久化方式。

在本体中,数据被表示为一系列由主语(subject)、谓词(predicate)和宾语(object)组成的陈述(statement),即三元组(triple)的集合。基于关系数据库的本体持久化使用二维表对本体的三元组进行处理,不可避免地需要对本体中的复杂关系进行不自然的分解,而查询时又需要将基于图的查询转换为关系查询(傅柱等, 2013) ,需要进行大量的关联、连接操作,因而,现有基于关系数据库的本体存储方法都存在大规模存储、更新、修改和查询效率低、数据库操作代价大等问题(李勇和李跃龙, 2008)。因此,效率、性能更优越的专门或扩展了RDF存储、查询甚至推理能力的非关系型三元组数据库(Triple Store,或称图数据库),如GraphDB (OWLIM) [1]、Virtuoso Universal Server[2]、AllegroGraph[3]、Jena TDB(Triple DB)等(Rohloff et al., 2007)目前已逐渐成为本体存储主流工具。本文采用基于Jena TDB的方式。

  TDB存储的本体数据集由node表、Triple和Quad索引、prefixes表组成,存放在指定的文件系统目录下。TDB采用B+树维护三种基本形式的Triple索引:SPO、POS和OSP(S、P、O分别代表Subject、Predicate和Object)。若存在命名图(Named Graph),则同时维护相应的Quad索引(G表示Graph):GOSP、SPOG、GSPO、OSPG、GPOS和POSG。

如上图所示,本体应用程序首先通过URI(Uniform Resource Identifier)地址映射文件实现本体URI与其对应的本体模块文件存放的文件系统地址的映射,然后使用自定义的Java类TDBPortal通过程序或配置文件读取各本体模块文件持久化到TDB。TDB中数据可通过TDBPortal实现增删改查操作,和进一步应用于本体查询与推理等操作;或作为SPARQL(SPARQL Protocol and RDF Query Language)服务器Jena Fuseki的数据源,对外提供基于HTTP的SPARQL查询服务。

下面介绍TDBPortal

  1  package cn.geodata.ont.tdb;
  2
  3  import java.util.ArrayList;
  4  import java.util.Iterator;
  5  import java.util.List;
  6
  7  import org.apache.commons.lang3.StringUtils;
  8  import org.apache.jena.riot.RDFDataMgr;
  9  import org.slf4j.Logger;
 10  import org.slf4j.LoggerFactory;
 11
 12  import cn.geodata.ont.file.OntFile;
 13
 14  import com.hp.hpl.jena.ontology.OntModel;
 15  import com.hp.hpl.jena.query.Dataset;
 16  import com.hp.hpl.jena.query.ReadWrite;
 17  import com.hp.hpl.jena.rdf.model.Model;
 18  import com.hp.hpl.jena.rdf.model.ModelFactory;
 19  import com.hp.hpl.jena.tdb.TDBFactory;
 20  import com.hp.hpl.jena.tdb.base.file.Location;
 21
 22  /**
 23   * @TODO TDB CRUD操作,包含事务
 24   * @author Zhiwei HOU
 25   * @date 2015年12月2日
 26   */
 27  public class TDBPortal
 28  {
 29      final static Logger logger = LoggerFactory.getLogger(TDBPortal.class);
 30
 31      // 必须close
 32      Dataset ds = null;
 33
 34      /**
 35       * 连接TDB
 36       *
 37       * @param tdbPath TDB目录或配置文件tdb-assembler.ttl路径. tdbPath可以通过配置文件进行设置
 38       * @param useAssemblerFile 是否使用配置文件连接
 39       */
 40      public TDBPortal(String tdbPath, boolean useAssemblerFile)
 41      {
 42          if (!useAssemblerFile)
 43          {
 44              Location location = Location.create(tdbPath);
 45              ds = TDBFactory.createDataset(location);
 46          }
 47          else
 48              ds = TDBFactory.assembleDataset(tdbPath);
 49      }
 50
 51      public TDBPortal(String tdbPath)
 52      {
 53          Location location = Location.create(tdbPath);
 54          ds = TDBFactory.createDataset(location);
 55      }
 56
 57      /**
 58      * 往模型中添加内容。不载入引用本体
 59      *
 60      * @param modelUri 本体的uri
 61      * @param sourcePath  本体文件实际地址
 62      * @param override 是否覆盖
 63      * @return
 64      * @Houzw at 2016年4月1日下午11:36:13
 65      */
 66      public int loadModel(String modelUri, String sourcePath, Boolean isOverride)
 67      {
 68          Model model = null;
 69          ds.begin(ReadWrite.WRITE);
 70          try
 71          {
 72              if (ds.containsNamedModel(modelUri))
 73              {
 74                  if (isOverride)// 覆盖
 75                  {
 76                      removeModel(modelUri);//只是移除地址,实际数据不会移除
 77                      loadModel(modelUri, sourcePath, false);
 78                  }
 79              }
 80              else
 81              {
 82                  model = ds.getNamedModel(modelUri);// 没有则创建一个,model不会为null
 83                  model.begin();
 84                  RDFDataMgr.read(model, sourcePath);
 85                  model.commit();
 86              }
 87              // 已有,但是不覆盖,则直接返回
 88              ds.commit();
 89              logger.info("本体模型数据已经导入");
 90              return 1;
 91          }
 92          catch (Exception e)
 93          {
 94              return 0;
 95          }
 96          finally
 97          {
 98              if (model != null)
 99                  model.close();
100              ds.end();
101          }
102      }
103
104      /**
105      * 导入本体。OntModel不支持事务。同时载入引用本体
106      *
107      * @param modelUri 模型uri
108      * @param sourcePath 本体文件(集成文件)地址
109      * @param override 是否覆盖
110      * @return
111      * @Houzw at 2016年4月1日下午11:36:09
112      */
113      public int loadOntModel(String modelUri, String sourcePath, Boolean isOverride)
114      {
115          OntModel model = ModelFactory.createOntologyModel();// 不支持事务
116          ds.begin(ReadWrite.WRITE);
117          try
118          {
119              if (ds.containsNamedModel(modelUri))
120              {
121                  if (isOverride)// 覆盖
122                  {
123                      removeModel(modelUri);
124                      loadOntModel(modelUri, sourcePath, false);
125                  }
126              }
127              else
128              {
129                  model = OntFile.loadOntModelWithLocMapper(sourcePath);//导入本体文件
130                  ds.addNamedModel(modelUri, model);
131
132              }
133              // 已有,但是不覆盖,则直接返回
134              ds.commit();
135              System.out.println(modelUri + " 已导入");
136              logger.info(modelUri + " 已导入");
137              return 1;
138          }
139          catch (Exception e)
140          {
141              System.out.println(e.getLocalizedMessage());
142              logger.error(e.getLocalizedMessage());
143              return 0;
144          }
145          finally
146          {
147              ds.end();
148          }
149      }
150
151
152      public Model getDefaultModel()
153      {
154          ds.begin(ReadWrite.READ);
155          Model model;
156          try
157          {
158              model = ds.getDefaultModel();
159              ds.commit();
160          }
161          finally
162          {
163              ds.end();
164          }
165          return model;
166      }
167
168      /**
169       * 获取指定模型
170       */
171      public Model getModel(String modelUri)
172      {
173          Model model = null;
174          ds.begin(ReadWrite.READ);
175          try
176          {
177              model = ds.getNamedModel(modelUri);
178          }
179          finally
180          {
181              ds.end();
182          }
183          return model;
184      }
185
186
187      public void loadDefaultModel(String sourcePath)
188      {
189          Model model = null;
190          ds.begin(ReadWrite.WRITE);
191          try
192          {
193              model = ds.getDefaultModel();
194              model.begin();
195              if (!StringUtils.isBlank(sourcePath))
196                  RDFDataMgr.read(model, sourcePath);
197              model.commit();
198              ds.commit();
199          }
200          finally
201          {
202              if (model != null)
203                  model.close();
204              ds.end();
205          }
206      }
207
208
209      public void removeModel(String modelUri)
210      {
211          if (!ds.isInTransaction())
212              ds.begin(ReadWrite.WRITE);
213          try
214          {
215              ds.removeNamedModel(modelUri);
216              ds.commit();
217              System.out.println(modelUri + " 已被移除");
218              logger.info(modelUri + " 已被移除");
219          }
220          finally
221          {
222              ds.end();
223          }
224      }
225
226      /**
227       * 列出所有模型的uri
228       */
229      public List<String> listModels()
230      {
231          ds.begin(ReadWrite.READ);
232          List<String> uriList = new ArrayList<>();
233          try
234          {
235              Iterator<String> names = ds.listNames();// DefaultModel没有name
236              String name = null;
237              while (names.hasNext())
238              {
239                  name = names.next();
240                  uriList.add(name);
241              }
242          }
243          finally
244          {
245              ds.end();
246          }
247          return uriList;
248      }
249
250      /**
251       * 必须关闭TDB连接
252       */
253
254      public void close()
255      {
256          ds.close();
257      }
258  }

以上简单介绍了基于Jena TDB的本体存储。目前我对AssemblerFile配置文件的配置还没有深入的研究,了解的朋友可以告诉我,O(∩_∩)O谢谢

水平有限,错误难免,多指教。TDB 的具体内容可查阅其官方文档


[1] http://ontotext.com/products/graphdb/

[2] http://www.openlinksw.com/

[3] http://franz.com/

时间: 2024-11-01 21:50:29

导入本体到Jena TDB数据库的相关文章

【exp/imp】将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中

[exp/imp]将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中 1.1  BLOG文档结构图 1.2  前言部分 1.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 如何将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中(重点,2种方法)? ② 从dmp文件可以获取到哪些信息?如何从dmp文件获取到dmp文件的字符集(重点,N种方法)? ③ 如何从dmp

paip.导入数据英文音标到数据库mysql为空的问题之道解决原理

#---原因:mysql 导入工具的bug #---解决:使用双引号不个音标括起来. 作者 老哇的爪子 Attilax 艾龙,  EMAIL:[email protected] 转载请注明来源: http://blog.csdn.net/attilax from log import * iniLog (r"c:\enWzPhonetic.log") n=0 for line in lines: if(n>100000 ):break; if( not isContain(lin

采用struts2+hibernate实现保存文件到Oracle数据库&amp;&amp;并附下载代码【导入即可用】;数据库中保存blob类型的二进制文件

原文:采用struts2+hibernate实现保存文件到Oracle数据库&&并附下载代码[导入即可用]:数据库中保存blob类型的二进制文件 源代码下载地址:http://www.zuidaima.com/share/1550463402478592.htm

一、导入、导出远程Oracle数据库

一.导入.导出远程Oracle数据库  其语法实示例如下:    imp/exp [username[/password[@service]]]   其中service是服务实例名,关于如何创建服务实例名或者数据库SID在http://blog.sina.com.cn/s/blog_7ffb8dd501013e5v.html有记录 或者: imp/exp [username[/password[@hostIp:1521/DBsid]]]  DBsid是数据库sid   如:exp admin/[

windows命令行下导入excel数据到SQLite数据库

1.转换文件格式,防止中文乱码:将excel保存成"CSV(逗号分隔)(*.csv)"格式,关闭文件,用记事本打开刚才保存的.csv文件,然后另存为UTF-8格式文本.需要注意的是,经过这样的转换,数字也全变成文本了. 2.通过adb shell(adb.exe存放在android开发软件安装文件夹中,如 F:\Develope\Tools\adt-bundle-windows-x86\sdk\platform-tools\)更改sqlite数据库的使用权限.运行adb之前要先打开AV

sqoop往hive中导入数据报找不到数据库错误

sqoop版本为1.4.4,hadoop版本为2.2.0,hive版本为0.11.0,hive元数据存放位置为mysql,当使用sqoop 从mysql往hive中导入数据时,总是提示找不到所指定的hive数据库,事实上hive中已存在该数据库,sqoop中也设置了hive路 径,/etc/profile文件中也已经设置好hive路径. mysql往hive中导数据命令: 1 ${SQOOP_HOME}/bin/sqoop import --connect jdbc:mysql://${host

EXCEL导入GridView,然后再汇入数据库.

原文:EXCEL导入GridView,然后再汇入数据库. 近日项目中有一个多笔料号要输入,我做了一个用javascript复制输入框的功能,可以输入多笔料号. 但是使用者反馈,料号太多,可能几百个料号在EXCEL文件里,这样输入很慢,需要增加功能.于是想到了SQLSERVER导入EXCEL的功能. declare @strExcelName varchar(50) set @strExcelName='c:\sl.xls' exec('select * into ##tmp from openr

转-【exp/imp】将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中

原帖地址:http://blog.csdn.net/lihuarongaini/article/details/71512116 1.2  前言部分 1.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 如何将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中(重点,2种方法)? ② 从dmp文件可以获取到哪些信息?如何从dmp文件获取到dmp文件的字符集(重点,N种方法)? ③ 如何从

PHP批量导入excell表格到mysql数据库

PHP批量导入excell表格到mysql数据库,本人通过亲自测试,在这里分享给大家 1,下载 php  excell类库 网上搜索可以下载,这里不写地址 2,建html文件 <form method="post" action="http://www.96net.com.cn/index.php?c=good&a=index" name="theForm" onsubmit="return validate()"