程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Spring.NET企業架構實踐(三)

Spring.NET企業架構實踐(三)

編輯:關於.NET

Nhibernate + WCF + ASP.NET MVC + NVelocity 對PetShop4.0重構(三)——持久層

什麼是持久層?先解釋什麼是持久,英文persistence,將內存中的數據固化,保持在物理儲存設備中。然而在企業應用中,往往通過 關系型數據庫來完成這一過程。那麼持久層的定義是:相對於三層架構中的表示層、業務層而言,專門負責持久化數據的獨立領域。設 計模式中的“單一職責”原則確定了分層的目的,說白了,持久層就是專門與數據庫打交道的。如圖1所示

圖1

在PetShop4.0中的DAL(數據庫訪問層)就是操作數據庫的。在其DAL中,通過SQL語句返回DataReader,然後給Model對象賦值;在添加、 修改、刪除操作中,通過Model對象的數據生成SQL語句,然後寫入數據庫。此時,我們能夠看出每張表都用同樣的操作。雖然PetShop4.0 使用SqlHelper封裝數據庫操作,但是卻沒有一個通用的CRUD封裝。目前PetShop4.0每個表都對應各種的CRUD,這樣就會出現大量重復的代 碼。

對於PetShop4.0的使用多鐘數據庫來言。對於每種數據庫都要寫一種DAL。這樣數據庫的可移植性就不強了。

針對上述問題,我使用ORM框架NHibernate作為持久層框架,來取代PetShop4.0的DAL。

什麼是ORM?對象關系映射,英文Object Relational Mapping。是解決“阻抗不匹配”的一種技術。“阻抗不匹配”是指,關系型數據 庫中數據與編程語言中的對象存在差異。使用面向對象的語言編程的同時又要為“面向關系”而犯愁。在企業級的系統開發中,程序員有 30%的時間用來解決“阻抗不匹配”的問題,花大量時間去編寫SQL語句。而ORM框架的出現就能很好的解決這樣的問題,從而做到快速開發 。在一個項目的編碼過程中,業務層是比較重要的,則編寫表示層和持久層代碼所用的時間不應該過長。所以使用好一個ORM框架尤為重要 。至於為什麼要使用ORM框架,有一個重要的原因:提高開發速度,減少開發和維護成本。然而這一點對於一個商業公司來說相當看重。

ORM的O是對象的意思,代表高級語言中的實體(Entity)模型;R是關系的意思,代表關系型數據庫;M是映射的意思,表示通過某種方式 實現對象和關系型數據庫的映射。如圖2所示

 

圖2

本系列文章,使用NHibernate作為ORM框架。這樣操作對象就相當於操作數據庫,開發人員不需要關心SQL語句怎麼寫,一門心思的專注 面向對象的開發,從而使得應用程序更OO(面向對象)。作為NHibernate的實體對象,完全是POJO(上篇文章提到過)。在持久層中, NHibernate框架借助映射文件和實體所承載的數據自動生成SQL語句,實現自動持久化。但是NHibernate仍然存在一些缺點:如,批量刪除 和修改。至於復雜的查詢報表來說,java開發人員往往放棄Hibernate,而使用ibatis或jdbc的方式實現。但是.NET在這一點做的很好,通 過NHibernate集成Linq的方式,使我們能夠通過Linq的語法查詢出想要得到的數據。巧妙的把C#語法(更且卻的說是.NET)和java中最流行 的框架之一的.NET版NHibernate完美結合起來。可以這麼說,HQL(Hibernate Query Language)不是完全的面向對象,但是Linq to NHibernate是覺對的面向對象。

在調用NHibernate的API操作數據庫時,每個對象都需要寫一個DAO。這裡,我們使用基於泛型的Repository(資源庫)模式將相同的代碼 內聚起來。

IRepository

 public interface IRepository<T> where T : class
     {
         /// <summary>
         /// 獲取實體
         /// </summary>
         /// <param name="id">主鍵</param>
         /// <returns></returns>
         T Get(object id);
         /// <summary>
         /// 插入實體
         /// </summary>
         /// <param name="entity">實體</param>
         /// <returns></returns>
         object Save(T entity);
         /// <summary>
         /// 修改實體
         /// </summary>
         /// <param name="entity">實體</param>
         /// <returns></returns>
         void Update(T entity);
         /// <summary>
         /// 保存實體
         /// </summary>
         /// <param name="entity">實體</param>
         /// <returns></returns>
         void SaveOrUpdate(T entity);
         /// <summary>
         /// 刪除實體
         /// </summary>
         /// <param name="entity">實體</param>
         /// <returns></returns>
         void Delete(T entity);
         /// <summary>
         /// 獲取全部集合
         /// </summary>
         /// <returns></returns>
         IQueryable<T> LoadAll();
         }

RepositoryBase

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using Spring.Data.NHibernate.Generic.Support;
using NHibernate.Linq;

     public abstract class RepositoryBase<T> : HibernateDaoSupport, IRepository<T> where T :  class
     {
         public virtual object Save(T entity)
         {
             return this.HibernateTemplate.Save(entity);
         }
         public virtual T Get(object id)
         {
             return this.HibernateTemplate.Get<T>(id);
         }
         public virtual IQueryable<T> LoadAll()
         {
             return this.Session.Linq<T>();
         }
         public virtual void Update(T entity)
         {
             this.HibernateTemplate.Update(entity);
         }
         public void Delete(T entity)
         {
             this.HibernateTemplate.Delete(entity);
         }
         public virtual void SaveOrUpdate(T entity)
         {
             this.HibernateTemplate.SaveOrUpdate(entity);
         }
     } 

這樣,同為增、刪、改、查的代碼,我只需要寫一遍就可以了。對於數據庫的遷移,可以通過配置數據庫方言來實現其目的。在使用 Spring.NET作為IoC框架中,我們不用關心和有意去編寫數據庫事務,並且NHibernate的Session管理也交給Spring.NET來處理。重構後的 代碼與PetShop4.0的DAL代碼比較起來,代碼行數減少了很多,但代碼的可維護性和靈活性卻有明顯的提升。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved