当时的前端,我们开发了基于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的封装与抽象。期待!
版权声明:本文博客原创文章,博客,未经同意,不得转载。