在本節我想與你們與分享一下,我所將要作的權限系統的架構和數據庫的表的設計。請各位大神們對我項目中設計的不足之處進行指導,讓我得以更好的寫完它,留給須要它的人。sql
個人項目架構以下圖所示:數據庫
如上圖所示,在數據訪問層,我採用了抽象工廠的方式,來對數據訪問層和業務邏輯層解耦,固然若是你想更高大上一些,能夠用第三方的框架,好比Spring.Net ,Autofac來實現。解耦的好處在於能夠方便的切換數據庫,當數據庫變動時,只需換一下對應的數據訪問DAL就行,本系列中,我所採用的是SQLServer。寫到這我想在以下這個大數據時代,MongoDB其實也是不錯的。後面有機會,能夠開一個MongoDB的專題和你們一塊兒來使用一下MongoDB學習一下它。對於抽象工廠來實現業務邏輯層與數據訪問層的解耦實現代碼以下,主要用到了反射,面向接口編程。編程
配置:緩存
<appSettings> <add key="DAL" value="MCFramework.SQLDAL"/> <!--頁容量--> <add key="PageSize" value="20"/> </appSettings>
抽象工廠:架構
namespace MCFramework.RepositoryFactory { public class RepositoryFactory { public RepositoryFactory() { } private static readonly string AssemblyPath =ConfigurationSettings.AppSettings["DAL"]; #region CreateObject //不使用緩存 private static object CreateObjectNoCache(string AssemblyPath, string classNamespace) { try { object objType = Assembly.Load(AssemblyPath).CreateInstance(classNamespace); return objType; } catch(System.Exception ex) { string str=ex.StackTrace;// 記錄錯誤日誌 return null; } } //使用緩存 //private static object CreateObject(string AssemblyPath, string classNamespace) //{ // object objType = DataCache.GetCache(classNamespace); // if (objType == null) // { // try // { // objType = Assembly.Load(AssemblyPath).CreateInstance(classNamespace); // DataCache.SetCache(classNamespace, objType);// 寫入緩存 // } // catch//(System.Exception ex) // { // //string str=ex.Message;// 記錄錯誤日誌 // } // } // return objType; //} #endregion /// <summary> /// 用戶倉儲 /// </summary> public static ISystem_EmployeeRepository System_EmployeeRepository { get { return (ISystem_EmployeeRepository)CreateObjectNoCache(AssemblyPath, AssemblyPath + ".System_EmployeeRepository"); } } /// <summary> ///菜單倉儲 /// </summary> public static ISystem_MenuRepository System_MenuRepository { get { return (ISystem_MenuRepository)CreateObjectNoCache(AssemblyPath, AssemblyPath + ".System_MenuRepository"); } } /// <summary> ///角色倉儲 /// </summary> public static ISystem_RoleRepository System_RoleRepository { get { return (ISystem_RoleRepository)CreateObjectNoCache(AssemblyPath, AssemblyPath + ".System_RoleRepository"); } } /// <summary> ///按鈕倉儲 /// </summary> public static ISystem_ButtonRepository System_ButtonRepository { get { return (ISystem_ButtonRepository)CreateObjectNoCache(AssemblyPath, AssemblyPath + ".System_ButtonRepository"); } } } }
全部的訪問數據庫的操做都用接口來約束:app
namespace MCFramework.IDAL { public interface IBaseRepository<T> where T:class { int Add(T model); int UpdateDel(string ids, bool isDel); int Del(string ids); int Update(T model); DataSet GetListByProc(string procName, System.Data.SqlClient.SqlParameter[] paras); DataSet GetModel(string Id); DataSet GetList(string strWhere); } }
namespace MCFramework.IDAL { public interface ISystem_ButtonRepository:IBaseRepository<System_ButtonModel> { bool IsExit(string ButtonCode); } }
接口的實現:框架
namespace MCFramework.SQLDAL { /// <summary> /// Author: MaChun /// Description: DALTier -- the DAL class of System_Button. /// Datetime:2015/6/8 13:00:35 /// </summary> public class BaseSystem_ButtonRepository: IBaseRepository<System_ButtonModel> { //建立企業庫鏈接 public SqlDataAccess db = SqlDataAccess.CreateDataAccess(); #region 新增一條記錄 Add(System_ButtonModel model) /// <summary> /// 新增一條記錄 /// </summary> public int Add(System_ButtonModel model) { int result = 0; try { StringBuilder strSql = new StringBuilder(); strSql.Append("insert into System_Button("); strSql.Append("SBT_Guid,SBT_ButtonCode,SBT_ButtonName,SBT_IconUrl,SBT_IconCss,SBT_CreateBy,SBT_CreatedDate)"); strSql.Append(" values ("); strSql.Append("@SBT_Guid,@SBT_ButtonCode,@SBT_ButtonName,@SBT_IconUrl,@SBT_IconCss,@SBT_CreateBy,@SBT_CreatedDate)"); strSql.Append(";select @@IDENTITY"); SqlParameter[] parameters = { new SqlParameter("@SBT_Guid", SqlDbType.VarChar,36), new SqlParameter("@SBT_ButtonCode", SqlDbType.VarChar,200), new SqlParameter("@SBT_ButtonName", SqlDbType.VarChar,100), new SqlParameter("@SBT_IconUrl", SqlDbType.VarChar,100), new SqlParameter("@SBT_IconCss", SqlDbType.VarChar,100), new SqlParameter("@SBT_CreateBy", SqlDbType.VarChar,100), new SqlParameter("@SBT_CreatedDate", SqlDbType.DateTime,8)}; parameters[0].Value = model.SBTGuid; parameters[1].Value = model.SBTButtonCode; parameters[2].Value = model.SBTButtonName; parameters[3].Value = model.SBTIconUrl; parameters[4].Value = model.SBTIconCss; parameters[5].Value = model.SBTCreateBy; parameters[6].Value = model.SBTCreatedDate; result = db.ExecuteNonQuery(strSql.ToString(), parameters); } catch (Exception ex) { throw ex; } return result; } #endregion #region 邏輯刪除 UpdateDel(string ids, bool isDel) /// <summary> /// 邏輯刪除 /// </summary> public int UpdateDel(string ids, bool isDel) { StringBuilder strSql = new StringBuilder(); strSql.Append("update System_Button set noDelKey='" + isDel.ToString() + "' where SBT_Guid in (" + ids + ")"); return db.ExecuteNonQuery(strSql.ToString()); } #endregion #region 物理刪除 Del(string id) /// <summary> /// 物理刪除 /// </summary> public int Del(string id) { StringBuilder strSql = new StringBuilder(); strSql.Append("delete System_Button where SBT_Guid ='"+id+"' "); return db.ExecuteNonQuery(strSql.ToString()); } #endregion #region 修改記錄 Update(System_ButtonModel model) /// <summary> /// 修改記錄 /// </summary> public int Update(System_ButtonModel model) { int res = -2; StringBuilder strSql = new StringBuilder(); strSql.Append("update System_Button set "); strSql.Append("SBT_ButtonCode=@SBT_ButtonCode,"); strSql.Append("SBT_ButtonName=@SBT_ButtonName,"); strSql.Append("SBT_IconUrl=@SBT_IconUrl,"); strSql.Append("SBT_IconCss=@SBT_IconCss,"); strSql.Append("SBT_CreateBy=@SBT_CreateBy,"); strSql.Append("SBT_CreatedDate=@SBT_CreatedDate"); strSql.Append(" where SBT_Guid=@SBT_Guid "); SqlParameter[] parameters = { new SqlParameter("@SBT_Guid", SqlDbType.VarChar,36), new SqlParameter("@SBT_ButtonCode", SqlDbType.VarChar,200), new SqlParameter("@SBT_ButtonName", SqlDbType.VarChar,100), new SqlParameter("@SBT_IconUrl", SqlDbType.VarChar,100), new SqlParameter("@SBT_IconCss", SqlDbType.VarChar,100), new SqlParameter("@SBT_CreateBy", SqlDbType.VarChar,100), new SqlParameter("@SBT_CreatedDate", SqlDbType.DateTime,8)}; parameters[0].Value = model.SBTGuid; parameters[1].Value = model.SBTButtonCode; parameters[2].Value = model.SBTButtonName; parameters[3].Value = model.SBTIconUrl; parameters[4].Value = model.SBTIconCss; parameters[5].Value = model.SBTCreateBy; parameters[6].Value = model.SBTCreatedDate; try { res = db.ExecuteNonQuery(strSql.ToString(), parameters); } catch (Exception ex) { throw ex; } finally { } return res; } #endregion #region 根據主鍵查詢出DataSet GetModel(string Id) /// <summary> /// 根據主鍵查詢出DataSet /// </summary> public DataSet GetModel(string Id) { StringBuilder strSql = new StringBuilder(); strSql.Append("select SBT_Guid,SBT_ButtonCode,SBT_ButtonName,SBT_IconUrl,SBT_IconCss,SBT_CreateBy,SBT_CreatedDate from System_Button "); strSql.Append(" where SBT_Guid=@SBT_Guid "); SqlParameter[] parameters = { new SqlParameter("@SBT_Guid", SqlDbType.Char,36)}; parameters[0].Value = Id; DataSet ds = db.ExecuteDataSet(strSql.ToString(), parameters); return ds; } #endregion #region 根據where 條件查詢出DataSet GetList(string strWhere) /// <summary> /// 根據where 條件查詢出DataSet /// </summary> public DataSet GetList(string strWhere) { StringBuilder strSql = new StringBuilder(); strSql.Append("select SBT_Guid,SBT_ButtonCode,SBT_ButtonName,SBT_IconUrl,SBT_IconCss,SBT_CreateBy,SBT_CreatedDate "); strSql.Append(" FROM System_Button "); if (strWhere.Trim() != "") { strSql.Append(" where " + strWhere); } DataSet ds = db.ExecuteDataSet(strSql.ToString()); return ds; } #endregion #region 根據存儲過程查詢出DataSet GetListByProc(string procName,SqlParameter[] paras) /// <summary> ///根據存儲過程查詢出DataSet /// </summary> /// <param name="procName">procName</param> /// <param name="paras">paras</param> public DataSet GetListByProc(string procName,SqlParameter[] paras) { DataSet ds = db.ExecuteDataSet(procName, paras); return ds; } #endregion } }
namespace MCFramework.SQLDAL { /// <summary> /// Author: MaChun /// Description: DALTier -- the DAL class of System_Button. /// Datetime:2015/4/20 16:01:42 /// </summary> public class System_ButtonRepository:BaseSystem_ButtonRepository,ISystem_ButtonRepository { public bool IsExit(string ButtonCode) { bool flag = false; string sql = string.Format(@"SELECT * FROM dbo.System_Button WHERE SBT_ButtonCode='{0}'", ButtonCode); DataSet ds = db.ExecuteDataSet(sql); if (ds.Tables.Count > 0) { flag = ds.Tables[0].Rows.Count > 0; } return flag; } } }
數據訪問層操做數據庫我沒有用ORM框架,用的是傳統的ADO.Net,我我的以爲這樣可控性會更好,也利於之後的優化。ide
業務邏輯層的調用:學習
namespace MCFramework.BLL { /// <summary> /// Author: MaChun /// Description: BLLTier -- the BLL class of System_Button. /// Datetime:2015/5/6 17:00:35 /// </summary> public class BaseSystem_ButtonService { protected static readonly ISystem_ButtonRepository dal = RepositoryFactory.RepositoryFactory.System_ButtonRepository; #region 新增一條記錄 Add(System_ButtonModel model) /// <summary> /// 新增一條記錄 /// </summary> public int Add(System_ButtonModel model) { return dal.Add(model); } #endregion #region 根據ID 邏輯刪除一條記錄 UpdateDel(string ids, bool isDel) /// <summary> /// 根據ID 邏輯刪除一條記錄 /// </summary> public int UpdateDel(string ids, bool isDel) { return dal.UpdateDel(ids, isDel); } #endregion #region 根據ID物理刪除一條記錄 Del(string id) /// <summary> /// 根據ID物理刪除一條記錄 /// </summary> public int Del(string id) { return dal.Del(id); } #endregion #region 更新一條記錄 Update(System_ButtonModel model) /// <summary> /// 更新一條記錄 /// </summary> public int Update(System_ButtonModel model) { return dal.Update(model); } #endregion #region 根據存儲過程來查詢返回一個list 集合 GetListByProc /// <summary> ///根據存儲過程來查詢返回一個list 集合 /// </summary> /// <param name="procName">procName</param> /// <param name="paras">paras</param> public List<System_ButtonModel> GetListByProc(string procName,System.Data.SqlClient.SqlParameter[] paras) { DataTable dt= dal.GetListByProc(procName,paras).Tables[0]; List<System_ButtonModel> list = null; list = new List<System_ButtonModel>(); LoadListData(ref list, dt); if (list.Count > 0) { return list; } else { return null; } } #endregion #region 根據主鍵來查詢獲得一個實體 GetModel(string Id) /// <summary> /// 根據主鍵來查詢獲得一個實體 /// </summary> public System_ButtonModel GetModel(string Id) { DataTable dt= dal.GetModel(Id).Tables[0]; System_ButtonModel model = new System_ButtonModel(); if (dt.Rows.Count > 0) { LoadEntityData(ref model, dt.Rows[0]); return model; } else { return null; } } #endregion #region 根據 where 條件來查詢獲得一個list集合 GetList(string strWhere) /// <summary> /// 根據 where 條件來查詢獲得一個list集合 /// </summary> public List<System_ButtonModel> GetList(string strWhere) { DataTable dt= dal.GetList(strWhere).Tables[0]; List<System_ButtonModel> list = null; list = new List<System_ButtonModel>(); LoadListData(ref list, dt); if (list.Count > 0) { return list; } else { return null; } } #endregion #region 將DataTable轉換爲 List 對象集合 LoadListData /// <summary> /// 將DataTable轉換爲 List 對象集合 /// </summary> /// <param name="list">GenericList</param> /// <param name="dt">DataTable</param> public void LoadListData(ref List<System_ButtonModel> list, DataTable dt) { if (dt.Rows.Count > 0) { System_ButtonModel model; foreach (DataRow dr in dt.Rows) { model = new System_ButtonModel(); LoadEntityData(ref model, dr); list.Add(model); } } } #endregion #region 將Datatable中的Dr 轉換成 Model 實體 LoadEntityData /// <summary> /// 將Datatable中的Dr 轉換成 Model 實體 /// </summary> /// <param name="model">Entity</param> /// <param name="dr">DataRow</param> public void LoadEntityData(ref System_ButtonModel model, DataRow dr) { model.SBTGuid = dr["SBT_Guid"].ToString(); model.SBTButtonCode = dr["SBT_ButtonCode"].ToString(); model.SBTButtonName = dr["SBT_ButtonName"].ToString(); model.SBTIconUrl = dr["SBT_IconUrl"].ToString(); model.SBTIconCss = dr["SBT_IconCss"].ToString(); model.SBTCreateBy = dr["SBT_CreateBy"].ToString(); if (dr["SBT_CreatedDate"].ToString() != "") { model.SBTCreatedDate = DateTime.Parse(dr["SBT_CreatedDate"].ToString()); } } #endregion } }
public class System_ButtonService:BaseSystem_ButtonService { #region 單例模式 private System_ButtonService() { } private static readonly System_ButtonService instance = new System_ButtonService(); public static System_ButtonService Instance { get { return instance; } } #endregion public bool IsExit(string ButtonCode) { return dal.IsExit(ButtonCode); } } }
對於,業務層到UI層之間的解耦,我沒有按架構圖中的去實現,我覺在通常中的項目中沒有這個必要,爲了簡化 ,我因此省去了,若是你想加上,徹底能夠按抽象工廠的方式加上。以上就是我對整個項目的架構上作的一個說明。接下來咱們再看看我數據庫的設計。大數據
權限的細化顆粒度到各頁面的按鈕。對於以上的架構和表設計,若是有什麼好的建議能夠給我留言。下一節,咱們將完成主頁面的主休框架和登陸驗證。