YYW'S BLOG

知识的分享就是知识的获得
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

NHibernate 实战 -- 挑战传统无限级分类

Posted on 2006-11-05 22:01  阿武  阅读(5189)  评论(30编辑  收藏  举报


      在某一天忽然觉得用 NHibernate 来实现无限级将会是多么简单,简单到你做梦都无法想到,似乎它天生就具备了处理这种情况的超能力。就连数据表的设计也被简化到了极致。

      下面我会简单说明一下实现的步骤并给出源码下载,同时它也是 ASP.NET 2.0 + Spring.Net + Nhibernate + MYSQL 的一个实例,之所以使用了几个框架组合和 MYSQL 做为数据库,完全是出于自娱自乐,但我还是更希望大家把重点放在 NHibernate 实现无限级分类上。

      第一步:创建数据库

-- 创建数据库
CREATE DATABASE hibernatedemo;

-- 添加表 tb_Classes
DROP TABLE IF EXISTS `hibernatedemo`.`tb_classes`;
CREATE TABLE  `hibernatedemo`.`tb_classes` (
  `Id` 
int(10) unsigned NOT NULL DEFAULT '1',
  `Name` 
varchar(45NOT NULL,
  `ParentId` 
int(10) unsigned DEFAULT NULL,
  `SortOrder` 
int(10) unsigned NOT NULL DEFAULT '0',
  
PRIMARY KEY (`Id`),
  
KEY `tb_classes_ibfk_1` (`ParentId`),
  
CONSTRAINT `tb_classes_ibfk_1` FOREIGN KEY (`ParentId`) REFERENCES `tb_classes` (`Id`)
) ENGINE
=InnoDB DEFAULT CHARSET=utf8;


      第二步: 创建实体关系映射(实体层)
      新建解决方案 NhibernateDemo,添加 ModelObject 项目用于存放实体类和映射文件。
      创建 ClassesInfo.hbm.xml 文件 (CodeSmith 生成,需做修改)


      创建实体类 ClassesInfo.cs (CodeSmith 生成,需做修改)


      为自定义主键添加生成器 ClassesIdGenerator.cs


         第二步: 新建 IDAL 、NHibernateDAL、DBUtilety、ClassFactory、IBLL、BLL 
         项目 IDAL 、NHibernateDAL、DBUtilety 项目的内容可参考 移植 Castle 的 ActiveRecord 直接为 NHibernate 所用
ClassFactory 项目对 Spring.Net 进行封装,主要负责对象创建工作,至于 Spring.Net IoC 的使用不是本文的重点(而且本文也将略去部分项目的讲解),如果您有兴趣的话可以参考 Spring.Net AOP 学习之旅: 使用 Throws Advice 处理异常
本文例子中也会采用此方式来记录异常。

      接下来我们在 IDL 中创建一个基接口 IDalBase

 
     然后添加继承自它的接口 IClasses

  
    同样我们也在 IBLL 中创建接口 IClasses ,当然 namespace 为 Yyw.IBLL


      接下来要做的就是对接口的实现工作了,此部分看代码自然就能明白。至此我们所有底层的工作都已经完成,剩下要做的就是表示层上的处理了,通过 NHibernate 的 many-to-one 级联操作我们可以不需要书写任何代码即可得到结点的父结点和子结点集合,表示层仅需要几个递归方法便可实现我们的无限级分类。

      演示地址:http://www.openopen.cn/nhibernatedemo/Default.aspx

需要注意:
1、需要将 MySql.Data.dll 文件拷贝到 /Web/bin 目录下
2、通过父结点查询子结点时不能使用 ICriterion 查询,
因为 ICriterion criterion = Expression.Eq("Parent", null); 生成的 SQL 条件语句为 parent.Id = '' 而并非 parent.Id is null,
所以我们需要通过 HQL 语句来完成。

      完整程序下载

      虽然通过 NH 实现无限级分类从性能上并非最好的选择,但它毕竟是简单的,而且数据表中也没更多的数据冗余。为了撰写这个例子花费了我一个礼拜天的休息时间(腹搞都打了好几天),没有功劳也有苦劳,大家多多支持哈 :)