Skip to content

2. :一个案例研究

2.1. 问题

让我们回到我们要构建的应用程序。我们将从一个具有以下架构的现有应用程序开始:

对于希望进一步了解以下内容的人士:

  • NHibernate:NHibernate ORM 入门 [http://tahe.developpez.com/dotnet/nhibernate/];
  • 基于 NHibernate 和 Spring 的 ASP.NET (WebForms) 应用程序:使用 ASP.NET、Spring.NET 和 NHibernate 构建三层 Web 应用程序 [http://tahe.developpez.com/dotnet/pam-aspnet/]。

我们希望将之前的应用程序改造为如下所示:

其中 EF5 已取代 NHibernate。该应用程序作为探索 EF5 的起点。由于 Spring.NET 允许我们在不破坏现有功能的情况下轻松切换层,因此应用程序 2 将与应用程序 1 使用相同的 [ASP.NET] 层。由于本文重点在于 EF5,我们将不解释如何实现该层。我们将将其集成到应用程序 2 中以验证其是否正常工作。 我们将仅说明 Spring.NET 配置文件中需要进行的修改。

案例研究如下。我们希望为医生提供一项基于以下原则运行的预约安排服务:

  • 由一名行政人员负责为多名医生处理预约安排。该服务可能仅由一人承担,其薪资由所有使用预约服务的医生共同分摊;
  • 行政办公室和所有医生都连接到互联网;
  • 预约信息记录在集中式数据库中,行政办公室和医生均可通过互联网访问该数据库;
  • 预约通常由行政人员安排。医生也可以自行安排预约。尤其是在诊疗结束时,医生为患者安排下次预约的情况下。

预约安排服务的架构如下:

如果医生不再需要管理预约,工作效率将得到提升。只要医生数量足够多,他们对行政办公室运营成本的贡献将微乎其微。我们将该应用程序命名为 [RdvMedecins]。以下是其工作原理的截图。

该应用程序的主页如下:

Image

用户(秘书、医生)可在此首页执行多项操作。我们将在下文进行介绍。左侧视图展示了用户发起请求的界面;右侧视图展示了服务器返回的响应

2.2. 数据库

NHibernate 应用程序使用的数据库是一个 MySQL5 数据库,其中包含四个表:

Image

我们将以此作为参考来构建所有数据库。

2.2.1. [DOCTORS] 表

该表包含由 [RdvMedecins] 应用程序管理的医生信息。

  • ID:医生的ID号——该表的主键
  • VERSION:一个标识表中该行版本的数字。每次对该行进行修改时,该数字都会增加 1。
  • LAST_NAME:医生的姓
  • FIRST_NAME:医生的名字
  • TITLE:称谓(Ms.、Mrs.、Mr.)

2.2.2. [CLIENTS] 表

各医生的患者信息存储在 [CLIENTS] 表中:

  • ID:客户的ID号——该表的主键
  • VERSION:标识该表中该行版本的编号。每次对该行进行修改时,该编号会递增 1。
  • LAST_NAME:客户的姓氏
  • 名字:客户的名字
  • 称谓:客户的称谓(Ms.、Mrs.、Mr.)

2.2.3. [SLOTS] 表

该表列出了可预约的时间段:

 
  • ID:时间段的ID号——该表的主键
  • VERSION:标识表中该行版本的编号。每次对该行进行修改时,该编号会递增1。
  • DOCTOR_ID:标识该时段所属医生的ID号——作为DOCTORS表中ID列的外键。
  • START_TIME:时间段的开始时间
  • MSTART:时间段的开始分钟
  • HFIN:时段结束时间
  • MFIN:该时段的结束分钟

例如,[SLOTS] 表(参见上文 [1])的第二行表明,第 2 号时段于上午 8:20 开始,上午 8:40 结束,属于第 1 号医生(Marie PELISSIER 女士)。

2.2.4. [RV] 表

该表列出了每位医生已预约的就诊时间:

  • ID:预约的唯一标识符——主键
  • DAY:预约日期
  • SLOT_ID:预约时段——作为外键关联至 [SLOTS] 表的 [ID] 列——同时确定时段及负责的医生。
  • CLIENT_ID:预约对象的客户ID——作为[CLIENTS]表中[ID]列的外键

该表对关联列(DAY、SLOT_ID)的值设置了唯一性约束:

ALTER TABLE RV ADD CONSTRAINT UNQ1_RV UNIQUE (JOUR, ID_CRENEAU);

如果 [RV] 表中某行 (DAY, SLOT_ID) 列的值为 (DAY1, SLOT_ID1),则该值不能出现在其他任何地方。否则,这意味着同一医生在同一时间被预约了两次。从 Java 编程的角度来看,当这种情况发生时,数据库的 JDBC 驱动程序会抛出一个 SQLException

ID 为 7 行(参见上文 [1])表示,2006 年 9 月 10 日为客户 #2 预订了第 10 个时段。根据 [SLOTS] 表,第 10 个时段对应上午 11:00 至 11:20,且属于医生 #1(Marie PELISSIER 女士)。 [CLIENTS] 表显示,客户 #2 是 Christine GERMAN 女士。

本案例研究曾作为一篇Java文章[http://tahe.developpez.com/java/primefaces]的主题,该文使用了Java版的Hibernate ORM。