本文的学习资料主要来自semantic web programming 一书。
最近的项目中,有关于数据整合的问题。语义web的一个比较重要的作用就是数据共享,共享的前提是数据要整合成统一的表示形式,如利用本体语言OWL或资源描述框架RDF。这里介绍常见的一种数据模型——关系数据库中数据到资源描述框架RDF的转换方法,为实现数据共享提供便利。
关系数据库(RDB)是语义web最大的数据来源之一,大多数网站都习惯于使用关系数据库来存储数据。幸运的是,RDF和OWL 都适用于对实体--关系(ER)模型(大多数关系数据库都使用ER模型来进行建模)中所表达的信息进行建模。目前已经有多种工具可以用于将关系数据库中的数据公开为虚拟RDF图,从而作为一个SPARQL(RDF查询语言,在下一章介绍)端点被用户浏览和访问。
一些常用的工具有:
D2RQ(http://www4.wiwiss.fu-berlin.de/bizer/d2rq/);
SquirrelRDF(http://jena.sourceforge.net/SquirrelRDF);
OpenLink Virtuoso(http://virtuoso.openlinksw.com/)。
本文中使用的是D2RQ工具,这样的工具使得将关系数据库公开为RDF变得简单,因为它们提供了通用的机制,可以将关系数据库的表和列映射到本体的类和属性上。
使用D2RQ将关系数据库公开为RDF有两个步骤。第一步是生成一个映射文件,该映射文件说明了数据库的表和列具体是如何与输出本体中的类和属性进行映射的。该工具本身并不生成输出本体,但是它隐式生成了一个本体,因为它在一个一致的命名空间上定义了一个类和属性的集合,而D2RQ处理程序在将RDB转换为RDF时会用到该命名空间。
第二步是建立一个由第一阶段生成的映射文件设定的D2RQ实例,并且将该实例包装为一个Jena模型。一旦这些工作完成之后,就可以像使用一般RDF模型那样使用该模型了。下面详细介绍D2RQ的用法和在系统中的使用方案。
D2RQ中附带了一个工具,它可以通过处理关系数据库的模式而自动生成映射。可以按下面的方式执行Java类d2rq.generate_mapping来调用该工具:
d2rq.generate_mapping
-u userName
-p password
-d driverClass
-o outputFile.n3
jdbcConnectUrl
举例如下:
d2rq.generate_mapping
-u root
-p 1234567
-d com.mysql.jdbc.Driver
-o outputFile.n3
jdbc:mysql://localhost:3306/testDB
上面例子意思是生成将位于localhost:3306的关系数据库testDB转换成RDF格式所必须的映射文件outputFile.n3,数据库登录的用户名和密码分别是root和1234567,mysql数据库驱动程序为com.mysql.jdbc.Driver。
由于上述工具是一个命令行工具,在具体系统实现时,为了实现转换的自动化,在转换模块的java类中使用一个进程调用这个工具。转换模块的实现中的几个关键函数实现如下:
public class RDBConvertion {
public RDBConvertion(String dbName)
{//初始化私有变量}
public Model convert() {
this.GenerateMapping();
return this.execute();
}
//自动生成RDB-RDF映射文件
private void GenerateMapping() throws IOException
{
Process process = null;
//命令格式:d2rq.generate_mapping -u u -p p -d d -o o connecturl
File dir = new File(ConstData.D2RQ_DIR);
String cmd = ConstData.D2RQ_DIR + "//generate-mapping.bat -u "+this.user+" -p "+this.pass+" -d "+this.driver+" -o "+this.output+" "+this.connect;
process = Runtime.getRuntime().exec(cmd,null,dir);
}
}
private Model execute()
{
Model d2rqModel = new ModelD2RQ("file:///"+this.output);
Model result = ChangeToOWLModel(d2rqModel);
return result;
}
}
核心函数是convert,它首先通过this.GenerateMapping();语句调用D2RQ工具生成映射文件,然后在返回时调用execute方法执行转换,并得到相应的RDF模型对象。
生成的映射文件内容摘要如下:
@prefix map: <file:/d:/DesignTest/ConvertResult/mappingfile.n3#> .
@prefix vocab: <http://localhost:2020/vocab/resource/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix d2rq: <http://www.wiwiss.fu-berlin.de/suhl/bizer/D2RQ/0.1#> .
@prefix jdbc: <http://d2rq.org/terms/jdbc/> .
…
…
这部分是一些必要的前缀,其中一些是关于语义web和xml规范,其他值得注意的是vocab前缀,它表示输出本体的命名空间,也就是说,所有来自D2RQ的RDF都必须使用具有vocab前缀的命名空间的类和属性描述。这样做的目的是为了使它们是唯一的,在需要读取某个类或属性时可以直接操作,而不必先动态获得命名空间了。
map:equipment a d2rq:ClassMap;
d2rq:dataStorage map:database;
d2rq:uriPattern "equipment/@@equipment.RID@@";
d2rq:class vocab:equipment;
d2rq:classDefinitionLabel "equipment";
…
…
map:equipment_RName a d2rq:PropertyBridge;
d2rq:belongsToClassMap map:equipment;
d2rq:property vocab:equipment_RName;
d2rq:propertyDefinitionLabel "equipment RName";
d2rq:column "equipment.RName";
这段代码含有d2rq:ClassMap类的一个实例和d2rq:PropertyBridge类的一个实例。D2RQ使用URI为map:equipment的d2rq:ClassMap实例将数据库中的而一个表映射到本体中的一个类;D2RQ通过每个含有属性值的d2rq:PropertyBridge实例将指定表的列映射到输出本体的属性。通过这种方式,关系数据库中表就转化成RDF格式了,其结果在一个RDF模型中,通过下面的方式访问:
RDBConvertion convert = new RDBConvertion(dbName);
Model RDFModel = convert.convert();
上面的RDFModel就可以用来执行正常的Jena模型操作了。至此,就已经完成了从RDB到RDF的数据转换。
文中的方法可以将一些有用的数据库转换成RDF虚拟图,并作为一个查询端点供用户访问,而不需要直接开放数据库本身。可以基于此开发一些语义web应用。
转自http://blog.csdn.net/jaytalent/article/details/6451847
参考http://www.oracle.com/ocom/groups/public/@otn/documents/webcontent/228999_zhs.htm