我是从Java转过来的,对于Java中的很多东西都非常关心,每每Java中有什么好东西就想是不是能够在Coldfusion中也能有这样的实现,当然Coldfusion有天然的优势,其核心就是Java,所以看到Hibernate、ibatis这样优秀的Java ORM框架,都非常期望能在Coldfusion中有类似的框架出现,我本人甚至在去年的一个项目中自己还实现了一个,今天我们就来说说当前Coldfusion世界中引起了巨大的波澜的Reactor。
要了解Reactor,我们需要先了解以下什么是ORM,对象关系映射(Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。本质上,ORM是将数据从一种表示(双向)转换为另一种。
当然ORM提供的不只是描述不同对象间关系的一个简单而直接的方式。ORM还提供了灵活性。使用ORM创建的模型比使用其它方法创建的模型更有能力适应系统的变化。另外,ORM允许非技术企业专家按样本数据谈论模型,因此他们可以使用真实世界的数据验证模型。因为ORM允许重用对象,数据模型能自动映射到正确标准化的数据库结构。ORM模型的简单性简化了数据库查询过程。使用ORM查询工具,用户可以访问期望数据,而不必理解数据库的底层结构。从编码来说,我们再也不用将sql直接编码,而是能够像操作对象一样从数据库获取数据,而至于如何获取,ORM框架会帮你实现。关于ORM的更深入了解可以查看这里。
Reactor是一项正在展开的工作,它致力于为ColdFusion应用软件创建一套对象关系映射API(Object-Relational Mapping API)。这是一项极具挑战的事业,但它的有效性和能量已经在CF的世界中引起了巨大的波澜。Reactor从数据库中读取元数据,然后自动生成组件,该组件可以对数据库进行抽象,并提供验证逻辑。Reactor创建的组件遵循很多已经确立的设计模式,比如动态记录(Active Record)、数据访问对象( Data Access Object)和表格数据网关(Table Data Gateway)。也许最强大的特色就是它可以与很多数据库协同工作,包括SQL Server、Oracle、MySQL、DB2和Postgre,这意味着一个应用软件可以以一种实质上透明的方式从SQL Server转换到Oracle。
咱们先不考虑这样一个简单的例子,我们有这么一个MySQL Address表,表结构如下:
CREATE TABLE if NOT EXISTS Address( addressId INT AUTO_INCREMENT UNIQUE, street1 VARCHAR(50), street2 VARCHAR(50) NULL, city VARCHAR(50), state VARCHAR(50), zip VARCHAR(10), PRIMARY KEY (addressId) );
在传统的Coldfusion程序中我们一般如下访问Address表中的所有数据:
name="addressQuery" database="reacotr_dns"> select * from Address var="#addressQuery#" />
先不管Reactor如何配置,如何使用,我们先看看在Reactor中类似的功能如何实现:
reactor = CreateObject("Component", "reactor.reactorFactory").init(expandPath("/config/reactor.xml")) /> addressGateway = reactor.createGateway("Address") /> addressQuery=addressGetway.getAll() /> var="#addressQuery#" />
上面的示例,没有了SQL语句的硬编码,完全面向对象式的访问对象,而不在是数据,是不是很吸引人?!那好现在我们开始深入Reactor!
首先,我们来安装Reactor,目前Doug Hughes是 Reactor的唯一开发者。他的blog是http://www.doughughes.net,所以目前关于Reactor最权威详细的信息都可以在Doug的网站得到,当前Reactor的最高版本为Beta Candidate 2 (BC2),可以从这里下载,详细的版本信息请查看这里。当然你也可以通过svn(地址:http://svn.reactorframework.com/reactor/trunk/)获取每日开发版本。
下载后的Zip文件中会含有3个文件夹:
首先设置Mappings,将Reactor目录复制到你的web服务器根目录下,重命名为reactor,Linux下可以直接使用ln -s Reactor reactor直接连接就可以了。这样Reactor框架就安装好了。
下面我们开始创建一个简单的Reactor应用。要在你的程序中使用Reactor ,你首先需要创建一个ColdFusion的数据源( data source)比如说reactor_ds,同时需要map一个目录(在web服务器根目录下,如wwwroot/下)如:/reactor_prac/data,让Reactor写入可能需要自动创建的组件,首先,设置我们应用的Reactor配置。Reactor通过一个Reactor XML配置文件来配置Reactor应用,其简化结构如下:
value ="reactor_prac" />value ="reactor_ds" />value ="mysql" />value ="/reactor_prac/data" />value ="development" /> </config> </reactor>
其中的project表示Reactor应用名,dns为我们在coldfusion中为该应用添加的datasource名称,Reactor目前支持Microsoft SQL Server、MySQL 4.x、MySQL 5.x、DB2、Oracle(9i/10i,8i不支持)、Oracle RDB、PostgreSQL 8,type表示我们所使用的数据库类型,mapping为我们用来存放Reactor自动生成对象文件的目录,最后,mode用来控制Reator如何生成对象文件,这里设置的是开发模式,更多的Reactor XML配置文件信息请查看这里
中途总结下,我们首先将下载的Reactor ZIP包中的Reactor复制或链接为web服务器的/reactor目录,然后在Coldfusion管理中,添加了一个名称为reactor_dns的到MySQL 5.0数据库reactor_test的dataSource,最后将上面的reactor.xml文件存放在我们的应用目录/reactor_prac目录下。
首先请使用一下SQL脚本,创建Address表,并在其中插入2行数据:
CREATE TABLE IF NOT EXISTS User( userID INT UNIQUE, username VARCHAR(50), PRIMARY KEY (userId) ); INSERT INTO User VALUES(1,'feiy'); INSERT INTO User VALUES(2,'eshangrao.com');
现在开始实际抄刀访问数据,首先我们要获取所有的User数据,代码如下:
Reactor = CreateObject("Component", "reactor.reactorFactory").init(expandPath("reactor.xml")) /> userGateway = Reactor.createGateway("User") /> qUsers = userGateway.getAll() /> var="#qUsers#" />
以上返回了我们前面Insert的两条记录,实际的SQL代码如下:
[mysql]SELECT * FROM User
执行的结果如下:
当然正常的需求可能是需要访问特定的一条记录,下面我们将从数据库中取出用户名为feiy的用户记录,我们先创建一个Record对象,Reactor中Reactor代表单条记录,该Reactor可以使用主键查询直接向数据库提交查询:
[cfm]查询前:
getUserId(): "#UserRecord.getUserId()#"
getUsername(): "#UserRecord.getUsername()#"查询后:
getUserId(): "#UserRecord.getUserId()#"
getUsername(): "#UserRecord.getUsername()#"
以上实际上执行的类似如下的一条SQL语句:
[mysql]SELECT * FROM User WHERE id=1
执行的结果如下:
查询完后,我们现在来向User表插入一条记录,代码如下:
[cfm]
以上实际的SQL代码如下:
[mysql]INSERT INTO User (id,name) VALUES (3,'pa99.cn')
执行的结果如下:
添加记录后,我们继续修改该记录,将其用户名改为:blog.pa99.cn,Reactor中对记录的修改与增加记录的方法一样,区分到底是增加还是修改的方法是,如果对于主键的记录不存在则向数据库写入新的记录,如果存在,则修改当前记录:
[cfm]
以上实际的SQL代码如下:
[mysql]UPDATE User SET name='blog.pa99.cn' WHERE id=3
执行的结果如下:
最后我们将pa99.cn这条记录删除,代码如下:
[cfm]
以上实际的SQL代码如下:
[mysql]DELETE FROM User WHERE id=3
执行的结果如下:
总结一下,以上我们简单的演示了怎样使用Reactor进行基本的数据库操作,Reactor使用Gateway.getAll()方法返回对于表的所有记录,使用Record对象对表中的单条记录进行操作,其中Record.save()方法用来更新或添加记录,而Record.delete()方法用来删除表中的某一条记录。当然这只是我们对数据访问操作中最基本的应用,实际的例子会更加的复杂,Reactor也可以用来进行更加复杂的应用,以上并未对Reactor的原理进行深入的说明,实际上,当我们使用OO的方法访问数据时,在后台,Reactor为我们进行了一系列精致而准确的O-SQL的翻译,为我们生成了一系列的对象类,这些我们都会在后续的文章中详细为您阐述。更多的Reactor信息请查看官方文档
Reactor是一个正在成长中的项目,一切都既有可能,设想一下,前台基于Flex2,使用Cairngorm框架,然后通过RMI直接访问后台的Coldfusion对象,而该对象有是使用的Reactor直接从数据库隐射的,也就是说我们可以在Flex2中直接像操作AS对象一样访问数据库对象,这是多么写意的事情啊!
要了解Reactor,最好的方法是马上动手下载一个源代码下来,一切都在您的眼前,其中喜乐您自个去领会吧!