XML 是当今 Web 最常用的数据交换格式之一。DB2® 对 pureXML™ 的支持以及与 parsing and generating XML API(REXML)的结合,为 Web 应用程序开发提供了强大的技术组合。DB2 数据服务器中的本地 XML 支持引入了极大的灵活性,通过使用 DB2 的混合型数据库引擎编译器和解析器(可同时使用 SQL 和 XQuery),能够混合存储半结构化的具有层次结构的 XML 文档和关系数据。在 Ruby on Rails 系列 的第二篇文章中,我们将演示如何在第一篇文章的 Team Room 示例中利用 pureXML 特性。
简介
在 Ruby on Rails 系列的第 1 部分中,我们使用 Ruby on Rails 和 DB2 构建了一个 Team Room 示例,这个应用程序允许注册的成员共享各种文本文档、图像文件和 XML 文档。为了管理不断增加的共享文档集合,您学习了如何按类别对文档分组。然后,学习了如何添加订阅特性,这样当用户订阅的文档类别中添加了新文档时,我们就可以通过电子邮件通知他们。在第一篇文章的末尾,成员能够将不同类型的文件上载到 Team Room,文件被存储在后端 DB2 数据服务器中。现在,我们进一步增强 Team Room,提供更高级的用户特性和更好的资源访问。
步骤 1. 添加用户管理特性
首先,在用户模型和它的底层表持久存储中增加一些必要的东西,从而支持正确的身份验证:一个惟一的用户 id 字符串和一个散列的密码(使用 SHA 算法和一个伪随机种子)。可以添加其他用户属性(比如有效性、等级等等)来进一步改进这个用户模型,并对控制器和视图做几处修改来支持新用户的注册和安全登录。我们的 Rails 项目放在 D:\rails\teamroom 目录中,所以下面引用的所有路径都是 D:\rails\teamroom 目录中的相对路径。
a) 执行 ruby script/generate migration add_user_credentials_columns 启动迁移进程,在 USERS 表中添加必要的列。
b) 编辑 db/migrate/008_add_user_credentials_columns.rb 文件,添加必要的列(见清单 1):
清单 1. 编辑 008_add_user_credentials_columns.rb
| class AddUserCredentialsColumns < ActiveRecord::Migration def self.up add_column :users, :userid, :string, :limit => 8 add_column :users, :hash_passwd, :string add_column :users, :salt, :string end def self.down remove_column :users, :userid remove_column :users, :hash_passwd remove_column :users, :salt end end |
c) 运行 rake db:migrate,在 USERS 表中添加这些新列。
步骤 2. 让主题可供多个用户订阅
在第一篇文章描述的 Team Room 中,每个主题只能属于一个订阅。每个订阅是一个用户已经订阅的主题集合,这让我们的 Team Room 相当不真实,因为一个用户选择了某个主题之后,Team Room 中的其他用户就不能再订阅这个主题了。
随着 Team Room 的流行,许多成员希望订阅同一个主题。成员的这种要求是正常的,应该允许对同一主题进行多次订阅。在更新的 Team Room 中,一个用户可以通过一个订阅订阅许多主题。为了实现这一修改,需要执行以下步骤:
注 1:参阅 IBM DB2 Database for Linux, UNIX, and Windows Information Center 中的 “Normalization” 部分。
SUBJECTS_SUBSCRIPTIONS 表包含以下列:
表 1. SUBJECTS_SUBSCRIPTIONS 表列和描述
| 列名 | 数据类型 | 描述 |
|---|---|---|
| SUBSCRIPTION_ID | Integer | SUBSCRIPTIONS 表的外部 ID |
| SUBJECT_ID | Integer | SUBJECTS 表的外部 ID |
在迁移过程中,执行以下步骤:
a) 执行 ruby script/generate migration create_subjects_subscriptions_table。
b) 编辑 db/migrate/009_create_subjects_subscriptions_table.rb 文件:
清单 2. 编辑 009_create_subjects_subscriptions_table.rb
| class CreateSubjectsSubscriptions < ActiveRecord::Migration def self.up create_table :subjects_subscriptions, :id => false do |t| t.column :subscription_id, :integer, :null => false t.column :subject_id, :integer, :null => false end remove_column :subjects, :subscription_id add_index :subjects_subscriptions, :subject_id end def self.down drop_table :subjects_subscriptions add_column :subjects, :subscription_id, :integer end end |
c) 运行 rake db:migrate 创建 SUBJECTS_SUBSCRIPTIONS 表。
e) 将 /app/models/subject.rb 文件中现有的关联 belongs_to :subscription 替换为新关联 has_and_belongs_to_many :subscriptions。
f) 将 /app/models/subscription.rb 文件中现有的关联 has_many: subject 替换为 has_and_belongs_to_many :subjects。
注:在往回迁移时,必须确保相应地修改并恢复每个模型中数据库对象的关联。
步骤 3. XML 数据:客户信息
我们的市场营销部门用 XML 格式收集了匿名的客户信息,用来分析客户的购物习惯。下面是零售商为市场研究收集的数据示例。
清单 3. XML 文档示例
| <marketinfo xmlns="http://www.ibm.com/developerworks"> <sales> <customer> <address> <city>Nashville</city> <state>TN</state> <zip>46808</zip> </address> <categories> <category type='Toys'> <item> <SKU>2434901</SKU> </item> <item> <SKU>9043272</SKU> </item> </category> <category type='Video Games'> <item> <SKU>1915216</SKU> </item> </category> </categories> <last_purchase>2007-05-12</last_purchase> </customer> </sales> </marketinfo> |
后面一节演示如何使用 Team Room 应用程序对这个 XML 数据执行查询操作。