當時的前端,我們開發了基於Net一組結構sprint.NET+NHibernate+MVC+WCF+EasyUI等中小型企業級系統開發平臺,如今把整個開發過程中的步步進展整理出來和大家分享,這個系列可能有點長。多多指導學習。
我們的底層開發平臺是sprint.NET+NHibernate+MVC+WCF+EasyUI方式開發,順便加點Spring.net注入的部分,當然我們最基本的關於許可權設計、業務設計,而架構。我們們沒有學過太複雜的架構。我們還是以最經常使用的MVC架構開始擴充
參考材料:
<<重構,改善既有程式碼的設計>>
<<.net應用架構設計原則,模式與實踐>>
<<.net設計正規化>>
<<程式碼整潔之道>>
首先我們要解說一下關於專案的搭建部分,我們的專案主要分6部分,業務邏輯層。資料訪問層,頁面層,資料模型層以及一個公共類的部分,每層我們在這個基礎上抽象了相應的介面,這樣上一層僅僅須要對下一層,面向介面程式設計。同一時候有Spring.NET來管理層之間的關係。達到解耦的目的。
這裡主要是:
業務邏輯層:
ICMSBLL:業務邏輯層介面
CMSBLL:業務邏輯層實現
抽象的資料底層封裝(泛型)
ICommonSupportDAL:對公共的方法的抽象
CommonSupportDAL:公共方法的實現
資料訪問層:
ICMSDAL:資料訪問層介面
CMSDAL:資料訪問層實現
領域模型層:
Entity:這是EF建立的模型
集合類層:
Collections:封裝了分頁,對於集合類內部的增刪改查,對集合類內部類的增刪改查。
介面層:
ComplaintManageSystem:基本的MVC和LigerUI實現的介面部分
TZHSWEET.UI:關於MVC公共UI定義的部分
公共類庫部分:
我們的目標是“0”增刪改查的資料訪問層實現,主要是靠Nhibernate的定義通用的增刪改從,然後其它類繼承增刪改查介面和對應的自己定義的子類的介面,實現擴充
首先,我們從曾經的寫程式碼經驗知道,我們的Dao主要是做增刪改查等方面,我們就先定義一個公共方法的介面叫做ICommonSupportDAL,這個介面定義泛型增刪改查
<span style="font-family:FangSong_GB2312;font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Entity;
namespace ICommonSupportDAL
{
public interface IRepository<T, TCollection> where T : class
{
#region 即時查詢,通過ID查詢
/// <summary>
/// 獲取實體
/// </summary>
/// <param name="id">主鍵</param>
/// <returns>實體</returns>
T Get(object id);
#endregion
#region 延遲載入,通過ID查詢
/// <summary>
/// 獲取實體
/// </summary>
/// <param name="id">主鍵</param>
/// <returns>實體</returns>
T Load(T entity);
#endregion
#region 將資料持久化到資料庫
/// <summary>
/// 插入實體
/// </summary>
/// <param name="entity">實體</param>
/// <returns>ID</returns>
object Save(T entity);
#endregion
#region 更新資料資訊
/// <summary>
/// 改動實體
/// </summary>
/// <param name="entity">實體</param>
void Update(T entity);
#endregion
#region 若資料存在則改動資訊,若不存在則插入
/// <summary>
/// 若資料存在則改動資訊,若不存在則插入
/// </summary>
/// <param name="entity">實體</param>
void SaveOrUpdate(T entity);
#endregion
#region 刪除實體
/// <summary>
/// 刪除實體
/// </summary>
/// <param name="id">ID</param>
void Delete(T entity);
#endregion
#region 依據ID批量刪除實體
//刪除實體
//void Delete(T entity);
/// <summary>
/// 依據ID批量刪除實體
/// </summary>
/// <param name="idList">ID集合</param>
void Delete(IList<T> idList);
#endregion
/// <summary>
/// 獲取所有集合
/// </summary>
/// <returns>集合</returns>
//IQueryable<T> LoadAll();
/// <summary>
/// 分頁獲取所有集合
/// </summary>
/// <param name="count">記錄總數</param>
/// <param name="pageIndex">頁碼</param>
/// <param name="pageSize">每頁大小</param>
/// <returns>集合</returns>
//IQueryable<T> LoadAllWithPage(out long count, int pageIndex, int pageSize);
#region 無條件查詢所有實體(單表查詢)
/// <summary>
/// 無條件查詢所有實體(單表查詢)
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
TCollection LoadAll();
#endregion
#region 通過自己寫where條件查詢實體
/// <summary>
/// 通過自己寫where條件查詢實體
/// </summary>
/// <param name="whereSql"></param>
/// <returns></returns>
TCollection LoadAllByWhereSql(object whereSql);
#endregion
#region 依據某一條件欄位刪除
/// <summary>
/// 按條件刪除
/// </summary>
/// <param name="columName">欄位名</param>
/// <param name="columValue">欄位值</param>
void DeleteAfterQuery(object columName, object columValue);
#endregion
#region 按一個條件查詢(單表查詢)
/// <summary>
/// 按一個條件查詢
/// </summary>
/// <param name="columnName"></param>
/// <param name="columValue"></param>
/// <returns></returns>
TCollection getByCondition(object columnName, object columValue);
#endregion
#region 通過原生sql語句進行增刪改查操作
/// <summary>
/// 通過原生sql語句進行增刪改查操作
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
TCollection ExecuteOrQueryBySql(object sql);
#endregion
#region 多條件查詢
/// <summary>
/// 多條件查詢
/// </summary>
/// <returns></returns>
TCollection FindVer(QueryHelper<T> qh);
#endregion
#region 依據SQL語句查詢
/// <summary>
/// 依據SQL語句查詢
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
TCollection LoadAllBySql(string sql);
#endregion
#region 依據某一欄位查詢(多表查詢)
/// <summary>
/// 依據某一欄位查詢(多表查詢)
/// </summary>
/// <param name="columnName"></param>
/// <param name="columValue"></param>
/// <returns></returns>
TCollection LoadByCondition(object columnName, object columValue);
#endregion
}
}
</span>
這層介面,大家可能覺得沒什麼必要,可是,這個介面很重要,這個介面保證了我們用Nhibernate一個抽象類實現增刪改查的同一時候又新增了子類的自身擴充套件性.
接下來,就是Dao部分,我們須要非常謹慎的去設計,
首先我們要設計一個用Nhibernate實現的公共父類的CommonSupportDAL類,用它來實現增刪改查,
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="color:#000000;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spring.Data.NHibernate.Generic.Support;
using NHibernate;
using System.Linq.Expressions;
using System.Collections;
using ICommonSupportDAL;
using Entity;
using MCS.Library.Data.DataObjects;
using System.Reflection;
using Collections;
namespace CommonSupportDAL
{
/// <summary>
/// 資料訪問層公共介面實現
/// </summary>
/// <typeparam name="T">實體泛型</typeparam>
public class RepositoryBase<T, TCollection> : HibernateDaoSupport, IRepository<T, TCollection>
where T : class
where TCollection : Collection<T, TCollection> ,new()
{
public String TEntityName;
public RepositoryBase()
{
String name = typeof(T).ToString();
this.TEntityName = name.Substring(name.LastIndexOf('.') + 1);
}
#region 將實體持久化到資料庫
/// <summary>
/// 將實體持久化到資料庫
/// </summary>
/// <param name="entity">泛型實體</param>
/// <returns></returns>
public virtual object Save(T entity)
{
// this.HibernateTemplate.Find<T>("from UserInfo ");
try
{
this.HibernateTemplate.SessionFactory.GetCurrentSession().FlushMode = FlushMode.Auto;
}catch(Exception ex)
{
}
Object TEntity = this.HibernateTemplate.Save(entity);
this.HibernateTemplate.Flush();
return TEntity;
}
#endregion
#region 依據ID查詢
/// <summary>
/// 依據ID查詢
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual T Get(object id)
{
return this.HibernateTemplate.Get<T>(id);
}
#endregion
#region 依據ID查詢
/// <summary>
/// 依據ID查詢
/// </summary>
/// <param name="id">實體ID</param>
/// <returns></returns>
public virtual T Load(T entity)
{
Object fild=null;
try
{
fild = entity.GetType().GetProperty("ID").GetValue(entity, null);
}
catch (Exception ex)
{
string typename = entity.GetType().ToString();
throw new Exception("請檢查" + typename + "中是否存在主鍵ID!");
}
return this.HibernateTemplate.Load<T>(fild);
}
#endregion
#region 查詢全部實體資訊
/// <summary>
/// 查詢全部實體資訊
/// </summary>
/// <returns></returns>
public virtual TCollection LoadAll()
{
TCollection tcollecton = new TCollection();
IList<T> list = this.HibernateTemplate.LoadAll<T>();
tcollecton.CopyFrom(list);
return tcollecton;
}
#endregion
#region 依據條件查詢實體集合資訊(hql)
/// <summary>
/// 依據條件查詢實體集合資訊(hql)
/// </summary>
/// <returns></returns>
public virtual TCollection LoadAllByWhereSql(object whereSql)
{
TCollection tcollecton = new TCollection();
IList<T> list = this.HibernateTemplate.Find<T>("from " + TEntityName + " where " + whereSql);
tcollecton.CopyFrom(list);
return tcollecton;
}
#endregion
#region 依據條件查詢實體集合資訊(sql)
/// <summary>
/// 依據條件查詢實體集合資訊(sql)
/// </summary>
/// <returns></returns>
public virtual TCollection LoadAllBySql(string sql)
{
TCollection tcollecton = new TCollection();
IList<T> list = this.HibernateTemplate.Find<T>(sql);
tcollecton.CopyFrom(list);
return tcollecton;
}
#endregion
#region 更新實體資訊
/// <summary>
/// 更新實體資訊
/// </summary>
/// <param name="entity"></param>
public virtual void Update(T entity)
{
this.HibernateTemplate.SessionFactory.GetCurrentSession().FlushMode = FlushMode.Auto;
this.HibernateTemplate.Update(entity);
this.HibernateTemplate.Flush();
}
#endregion
#region 依據ID刪除資訊
/// <summary>
/// 依據ID刪除資訊
/// </summary>
/// <param name="id"></param>
public void Delete(T entity)
{
this.HibernateTemplate.SessionFactory.GetCurrentSession().FlushMode = FlushMode.Auto;
this.HibernateTemplate.Delete(entity);
this.HibernateTemplate.Flush();
}
#endregion
#region 批量刪除
/// <summary>
/// 批量刪除
/// </summary>
/// <param name="idList"></param>
public virtual void Delete(IList<T> idList)
{
foreach (object item in idList)
{
this.HibernateTemplate.SessionFactory.GetCurrentSession().FlushMode = FlushMode.Auto;
this.HibernateTemplate.Delete(item);
this.HibernateTemplate.Flush();
}
}
#endregion
#region 按條件刪除
/// <summary>
///按條件刪除
/// </summary>
/// <param name="columName"></param>
/// <param name="columValue"></param>
public virtual void DeleteAfterQuery(object columName, object columValue)
{
IList<T> list = this.HibernateTemplate.Find<T>("from " + TEntityName + " u where u." + columName + " =?", new object[] { columValue });
//在執行刪除
foreach (object t in list)
{
this.HibernateTemplate.SessionFactory.GetCurrentSession().FlushMode = FlushMode.Auto;
this.HibernateTemplate.Delete(t);
this.HibernateTemplate.Flush();
}
}
#endregion
#region 儲存後更新
/// <summary>
/// 儲存後更新
/// </summary>
/// <param name="entity"></param>
public virtual void SaveOrUpdate(T entity)
{
this.HibernateTemplate.SessionFactory.GetCurrentSession().FlushMode = FlushMode.Auto;
this.HibernateTemplate.SaveOrUpdate(entity);
this.HibernateTemplate.Flush();
}
#endregion
//#region
///// <summary>
///// 依據條件查詢實體集合資訊--sql語句,不推薦使用,會產生sql注入
///// </summary>
///// <returns></returns>
//public virtual IList<T> getBywhereSql(string wheresql)
//{
// IList<T> list = this.HibernateTemplate.Find<T>("from " + TName + " where " + wheresql);
// return list;
//}
//#endregion
//#region
//#endregion
///// <summary>
///// 依據條件查詢實體集合資訊--sql語句,不推薦使用。會產生sql注入
///// </summary>
///// <returns></returns>
//public virtual IList<T> getBySql(string sql)
//{
// IList<T> list = this.HibernateTemplate.Find<T>(sql);
// return list;
//}
#region 通過一個條件查詢(單表查詢)
/// <summary>
/// 通過一個條件查詢(單表查詢)
/// </summary>
/// <param name="columName">屬性名</param>
/// <param name="columValue">屬性值</param>
/// <returns></returns>
public virtual TCollection getByCondition(object columnName, object columValue)
{
TCollection tcoll = new TCollection();
//比方驗證username。僅僅須要傳入Name屬性的名稱和值就可以;
//這個Name是相應的實體的屬性名稱,非資料庫欄位名。例getByCondition("Name","11");
IList<T> list = this.HibernateTemplate.Find<T>("from " + TEntityName + " u where u." + columnName + " =?
", new object[] { columValue }); tcoll.CopyFrom(list); return tcoll; } #endregion #region 通過一個條件查詢(多表查詢) /// <summary> /// 通過一個條件查詢(單表查詢) /// </summary> /// <param name="columName">屬性名</param> /// <param name="columValue">屬性值</param> /// <returns></returns> public virtual TCollection LoadByCondition(object columnName, object columValue) { TCollection tcoll = new TCollection(); //比方驗證username,僅僅須要傳入Name屬性的名稱和值就可以; //這個Name是相應的實體的屬性名稱。非資料庫欄位名。例getByCondition("Name","11"); IList<T> list = this.HibernateTemplate.Find<T>("from " + TEntityName + " u where u." + columnName + " =?", new object[] { columValue }); tcoll=this.LoadById(list); return tcoll; } #endregion #region 通過原生sql語句進行增刪改查操作 /// <summary> /// 通過原生sql語句進行增刪改查操作 /// </summary> /// <param name="sql"></param> /// <returns></returns> public TCollection ExecuteOrQueryBySql(object sql) { TCollection tcollecton = new TCollection(); ISQLQuery sqlQuery = this.HibernateTemplate.SessionFactory.GetCurrentSession().CreateSQLQuery(sql.ToString()).AddEntity(typeof(T)); tcollecton.CopyFrom(sqlQuery.List<T>()); return tcollecton; } #endregion #region 多條件查詢 /// <summary> /// 多條件查詢 /// </summary> /// <returns></returns> public TCollection FindVer(QueryHelper<T> qh) { // QueryHelper<T> qh = new QueryHelper<T>("u"); //return qh; // 引數列表 IList<Object> parameters = qh.getParameters(); // 查詢本頁的資料列表 IQuery listQuery = this.HibernateTemplate.SessionFactory.GetCurrentSession().CreateQuery(qh.getListQueryHql()); // 建立查詢物件 if (parameters != null) { // 設定引數 for (int i = 0; i < parameters.Count; i++) { listQuery.SetParameter(i, parameters[i]); } } listQuery.List(); TCollection tcollection = new TCollection(); IList<T> list = listQuery.List<T>(); tcollection.CopyFrom(list); return tcollection; } #endregion #region 分頁查詢 /// <summary> /// 分頁查詢 /// </summary> /// <param name="tcollection"></param> /// <returns></returns> public TCollection LoadAllByPage(TCollection tcollection) { IQuery query = this.HibernateTemplate.SessionFactory.OpenSession().CreateQuery("from "+typeof(T).ToString()); query.SetFirstResult((tcollection.PageNum - 1) * tcollection.PageSize); query.SetMaxResults(tcollection.PageSize); IList list = query.List(); TCollection tcoll = new TCollection(); tcoll.TotalRecords=this.LoadAll().Count(); IEnumerator en = list.GetEnumerator(); while (en.MoveNext()) { tcoll.Add((T)en.Current); } //tcoll.CopyFrom(list); return tcoll; } #endregion #region 通過多個ID查詢 /// <summary> /// 通過多個ID查詢 /// </summary> /// <param name="entity">包括ID資訊的實體集合</param> /// <returns>集合資訊</returns> public TCollection LoadById(IList<T> entity) { IEnumerator en = entity.GetEnumerator(); IList<object> IDlist = new List<object>(); while (en.MoveNext()) { Object fild = null; try { fild = en.Current.GetType().GetProperty("ID").GetValue(en.Current, null); } catch (Exception ex) { string typename = en.Current.GetType().ToString(); throw new Exception("請檢查" + typename + "中是否存在主鍵ID!"); } IDlist.Add("'"+fild+"'"); } IQuery query = this.HibernateTemplate.SessionFactory.OpenSession().CreateQuery("from " + TEntityName + " u where u.ID in (" +string.Join(",",IDlist.ToArray())+")"); // IQuery query = this.HibernateTemplate.SessionFactory.OpenSession().CreateQuery("from " + TEntityName + " u where u.ID in ('05221ff5-b491-4590-86bb-f5e275c6fd83','10df07ac-98ae-41f8-bcde-c4f48ec931f4','14c33f83-3be7-4162-8ace-8ef2e3677402','29780cc4-d7d8-4982-b8b7-ee63320da1d8','299ad880-06e3-48a3-80ca-570b8a557c42','7662b072-42a7-45fc-b11b-93efc844e5cd','87c26a14-56f2-4a57-9c99-e55f55ba6cdd','87c73291-591b-431f-b0fe-e73e15a490cf','917f9354-29e2-44b0-ad58-e2d8a0dd7670','9de57d2d-b4f8-4c56-9ce6-66673f42413d','a0e0cb9a-e8e4-4164-a021-cbcb61a8ea30','c6c239bf-6089-4c7c-983c-8ca479c360d5','c996d768-c9f9-4575-9268-4cfcf92fd038','ca09c55e-0a8d-4241-a364-74f1bdb60c32','da34ebae-11a7-4cfc-9772-b5e049768fe7','e5ee288e-8c5d-46bc-8c77-34b8c45750c1')"); IList list= query.List(); TCollection tc= new TCollection(); IEnumerator enumer=list.GetEnumerator(); while(enumer.MoveNext()) { tc.Add((T)enumer.Current); } return tc; } #endregion } }</span> </span>
接下來我們的工作量就小了,我們能夠看到成果了,我們接下來的實現,僅僅須要繼承上面這個RepositoryBase和IRepository的部分就能夠非常輕鬆的實現,子類的增刪改查以及子類的擴充套件了.
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="color:#000000;"> public interface ICaseAssignEntityRepository:IRepository<CaseAssignEntity,CaseAssignEntityCollection>
{
}</span></span>
<span style="font-family:FangSong_GB2312;font-size:18px;">namespace CMSDAL.AnJianLuRu
{
public class CaseAssignEntityRepository : RepositoryBase<CaseAssignEntity, CaseAssignEntityCollection>, ICaseAssignEntityRepository
{
}
}</span>
大家看到繼承了兩個一個是RepositoryBase父類。一個是ICaseAssignEntityRepository自己的業務邏輯介面(實現了子類的擴充,比方在某個類中想要加入這個類特有的方法。僅僅須要在自己的介面中填寫就可以)。通過這個繼承體系保證了我們在實現增刪改查的同一時候外放一個介面保證擴充套件性.
繼承系列圖:
總結
這樣我們的資料訪問層,非常輕鬆的實現了,基本上程式碼量非常少,增刪改查部分差點兒"0"程式碼,都是泛型的父類實現了.抽象、繼承、泛型、託付、容器等等大大提高了程式碼的複用性。
-----一切來源於抽象。
今天就解講到這裡,接下來給大家解說Collection的封裝與抽象。期待!
版權宣告:本文部落格原創文章,部落格,未經同意,不得轉載。