在上一篇中,我们已经搭建起了整个解决方案的项目,并且建好了数据库,完成了实体类和Nhibernate映射文件.在本文中,将定义数据访问接口,并利用Nhibernate实现接口,利用Spring.net配置起来dao.并对其进行单元测试.

数据访问层也和Petshop等框架一样,分为数据访问的接口以及实现,不过这里的数据访问实现相比之下就清晰和明显了的多,Nhibernate本身就是支持多数据库的,所以这样做不是为了多数据库,而是为了Nhibernate的可插拨,即使哪一天发现由于一些问题,比如说性能问题,可以重新实现IDAL接口,而不会对业务层造成比较大的改动.

说到这里,其实我们还不太清楚前台到底需要哪些功能,所以我们就先简单的实现实体的增删改查吧.等需要其它的功能时,再来完善接口和实现.

DirectCenter.IDAL不依赖于Spring或者是Nhibernate,只需要添加项目引用DirectCenter.Model.以用户来说吧,添加接口IUserDao.cs

IUserDao.csusing System.Collections;using DirectCenter.Model;

namespace DirectCenter.IDAL
{publicinterface IUserDao
{
User FindById(string userId);void Delete(User user);
User Save(User user);
User SaveOrUpdate(User user);
}
}

同样,我们添加ICompanyDao和IDepartmentDao.

接下来,我们实现刚才的数据接口,DirectCenter.DAL项目中添加对DirectCenter.IDAL和DirectCenter.Model的项目引用,然后再添加引用Spring.Data.NHibernate20,Spring.Data,Spring.Core(在lib/Spring.net下面).

一种方式是可以直接使用Nhibernate完成数据访问:

UserDao.cspublic User Save(User user)
{//通过一种方式获取Session           Session session = SessionFactory.OpenSession();
session.Save(user);
}

不过我们不打算使用这种单纯Nhibernate的方式,而是使用继承spring对hibernate的封装类HibernateDaoSupport,这样我们把Spring.net作为Nhibernate的容器可以方便的进行统一管理和利用一些特性.

UserDao.csusing System.Collections;

using Spring.Data.NHibernate.Support;

using DirectCenter.IDAL;using DirectCenter.Model;

namespace DirectCenter.DAL
{publicclass UserDao:HibernateDaoSupport,IUserDao
{public User Save(User user)
{
HibernateTemplate.Save(user);return user;
}public User SaveOrUpdate(User user)
{
HibernateTemplate.SaveOrUpdate(user);return user;
}publicvoid Delete(User user)
{
HibernateTemplate.Delete(user);
}public User  FindById(string userId)
{return  HibernateTemplate.Get(typeof(User), userId) as User;
}

}
}

同时添加CompanyDao和DepartmentDao.

一个HibernateTemplate怎么就完成了上面的这些操作.Nhibernate相关的呢?Session在哪里?通过查看代码,我们知道HibernateTemplate是HibernateDaoSupport的一个属性,我们就截取HibernateTemplate的一些代码片断来简单看一下:

HibernateTemplate.cs///<summary>/// Gets or sets the session factory that should be used to create/// NHibernate ISessions.///</summary>///<value>The session factory.</value>publicoverride ISessionFactory SessionFactory
{get { return sessionFactory; }set
{
sessionFactory = value;
}
}

///<summary>/// Gets or sets the template flush mode.///</summary>///<remarks>/// Default is Auto. Will get applied to any <b>new</b> ISession/// created by the template.///</remarks>///<value>The template flush mode.</value>publicoverride TemplateFlushMode TemplateFlushMode
{get { return templateFlushMode; }set { templateFlushMode = value; }
}

///<summary>/// Gets or sets a value indicating whether to /// cache all queries executed by this template.///</summary>///<remarks>/// If this is true, all IQuery and ICriteria objects created by/// this template will be marked as cacheable (including all/// queries through find methods).///<p>To specify the query region to be used for queries cached/// by this template, set the QueryCacheRegion property.///</p>///</remarks>///<value><c>true</c> if cache queries; otherwise, <c>false</c>.</value>publicoverridebool CacheQueries
{get { return cacheQueries; }set { cacheQueries = value; }
}

publicobject Load(Type entityType, object id, LockMode lockMode)
{return Execute(new LoadByTypeHibernateCallback(entityType, id, lockMode),true);

}

internalclass LoadByTypeHibernateCallback : IHibernateCallback
{private Type entityType;privateobject id;private LockMode lockMode;

public LoadByTypeHibernateCallback(Type entityType, object id, LockMode lockMode)
{this.entityType = entityType;this.id = id;this.lockMode = lockMode;

}

///<summary>/// Gets called by HibernateTemplate with an active/// Hibernate Session. Does not need to care about activating or closing/// the Session, or handling transactions.///</summary>///<remarks>///<p>/// Allows for returning a result object created within the callback, i.e./// a domain object or a collection of domain objects. Note that there's/// special support for single step actions: see HibernateTemplate.find etc.///</p>///</remarks>publicobject DoInHibernate(ISession session)
{if (lockMode !=null)
{return session.Load(entityType, id, lockMode);
}else
{return session.Load(entityType, id);
}
}

}

本质还是通过调用Nhibernate的Session来完成的,具体的原来请查看相关资料或源代码.

但是只有上面的代码肯定是不行的,我们在哪里连接数据库呢?通过IOC向HibernateTemplate中注入SessionFactory,然后在Spring.net中声明一个SessionFactory的对象.

DirectCenter.App添加一个Dao.xml,主要是是进行数据访问的配置.

Dao.xml<?xml version="1.0" encoding="utf-8" ?><objects xmlns="http://www.springframework.net"
xmlns:db="http://www.springframework.net/database">                    <!-- 用以我们在其它的应用程序中,配置数据访问 --><object type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core"><property name="ConfigSections" value="databaseSettings"/></object>

<!-- 数据库和Nhibernate的相关配置 --><db:provider id="DbProvider"
provider="SqlServer-2.0"
connectionString="Data Source=miaozy;Database=DirectCenter;Integrated Security=true;User Instance=false;"/>

<!--SessionFactory对象,其中包括一些比较重要的属性 -->              <object id="NHibernateSessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate20"><property name="DbProvider" ref="DbProvider"/><property name="MappingAssemblies"><list><value>DirectCenter.Model</value></list></property><property name="HibernateProperties"><dictionary><entry key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"/><entry key="dialect"
value="NHibernate.Dialect.MsSql2000Dialect"/><entry key="hibernate.connection.driver_class"
value="NHibernate.Driver.SqlClientDriver"/>

</dictionary></property><property name="ExposeTransactionAwareSessionFactory" value="true"/></object>

<!--将id为NHibernateSessionFactory的对象注入到HibernateTemplate中--><object id="HibernateTemplate" type="Spring.Data.NHibernate.HibernateTemplate"><property name="SessionFactory" ref="NHibernateSessionFactory"/><property name="TemplateFlushMode" value="Auto"/><property name="CacheQueries" value="true"/></object>

<!-- 我们的数据访问类,将HibernateTemplate注入进来--><object id="UserDao" type="DirectCenter.DAL.UserDao, DirectCenter.DAL"><property name="HibernateTemplate" ref="HibernateTemplate"/></object>

<object id="CompanyDao" type="DirectCenter.DAL.CompanyDao, DirectCenter.DAL"><property name="HibernateTemplate" ref="HibernateTemplate"/></object>

<object id="DepartmentDao" type="DirectCenter.DAL.DepartmentDao, DirectCenter.DAL"><property name="HibernateTemplate" ref="HibernateTemplate"/></object>

</objects>

注意: 1.NHibernateSessionFactory的MappingAssemblies属性,是我们实体映射文件所在的程序集,也可以通过MappingResources属性引入映射文件,通过ConfigFilenames属性引入Nhibernate的配置文件hibernate.cfg.xml

2.这里的HibernateProperties属性是指定的是dialect,而不是hibernate.dialect.这是Nhibernate 2.0更新的.不然会提示"Could not find the dialect in the configuration"

接下来,就让测试一下我们的代码吧.稍微检验一下我们的成果.为DirectCenter.UnitTest项目添加相关的引用,其中重要的是NUnit.Framework和Spring.Testing.NUnit.
添加测试类,UserDaoTest.cs

UserDaoTest.csusing System;

using NUnit.Framework;using Spring.Testing.NUnit;

using DirectCenter.Model;using DirectCenter.IDAL;

namespace DirectCenter.UnitTest
{
[TestFixture]publicclass UserDaoTest : AbstractTransactionalDbProviderSpringContextTests
{protectedoverridestring[] ConfigLocations
{get
{returnnew String[] { "objects.xml" };
}
}

protected IUserDao UserDao
{get
{return applicationContext.GetObject("UserDao") as IUserDao;
}
}
[Test]publicvoid SaveUserTest()
{
User user =new User();
user.UserID ="buyer000";
user.Password ="1356";
user.UserName ="刘翔";
user.ValidFrom = Convert.ToDateTime("2008-8-18");
user.ValidTo = Convert.ToDateTime("2012-8-18");
user.CreateTime = DateTime.Now;
UserDao.Save(user);
}
}
}

objectx.xml中引入我们的配置文件dao.xml ,另外应用程序配置文件App.Config中有Spring.Net和Nhibernate的相关配置信息,就不贴太多代码了.呵呵

利用nunit运行SaveUserTest,发现显示测试成功了,不过查看数据库为什么没有添加进去呢??? ?

淡定淡定,因为我们并没有提交,在最后加上   transactionManager.Commit(transactionStatus);再看一下结果..剩余的我还都并没有测试,如果你尝试,就尝试其它的dao的方法吧...

回过头来,看我们的Dao的实现,基本上都是那几种,而且继承于HibernateDaoSupport ,这样使我们的数据访问直接依赖于Spring.net和Nhibernate,以后想直接拿掉Spring.net或者是更换版本都会有些困难,怎么办呢.可以写一个基类继承于HibernateDaoSupport ,并且通过泛型或者是获以当前类型统一完成这些操作.这个我看下,可以放在最后再来讲一下我的实现.

ps.希望这篇文章能够给也在使用类似框架的朋友带来些收获,这样也不会违背放在首页的原则.目的还是想以这个框架的整合为主,以及我在使用的过程中遇到的一些问题和大家分享.至于Spring.Net或者是Nhibernate,Asp.net mvc相关的技术,请参考相关的学习资料.或者是在这里给我留言.

本次代码下载

作者:孤独侠客(似水流年)
出处:http://lonely7345.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

分类: .NET
标签: Spring.Net, Nhibernate, HibernateTemplate, Spring.Testing.NUnit, AbstractTransactionalDbProviderSpringContextTests
本文转自孤独侠客博客园博客,原文链接:http://www.cnblogs.com/lonely7345/archive/2008/09/09/1287212.html,如需转载请自行联系原作者

Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 3 ----数据访问层相关推荐

  1. Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 6 ----asp.net MVC+Extjs

    现在mvc采用了ModelBinder, Controller中现在可以接受很多复杂类型的参数,但是对于jquery,extjs等js框架来说,更多的是采用json格式与服务器端传递参数更合理.对于简 ...

  2. ASP.NET MVC 音乐商店 - 4. 数据访问

    上一次,我们使用了模拟的数据从控制器发送到视图模板.现在,我们开始使用真正的数据库,在这个教程中,我们将指导如何使用 SQL Server Compact 版的数据库,它经常被称为 SQL CE, 来 ...

  3. ASP.NET MVC实践系列9-filter原理与实践

    filter实际上是一个特性(attribute),它提供了一种向controller 或 action中添加某些任务的方法,当controller 或 action被调用时,会触发filter中定义 ...

  4. Spring.net与Asp.net Mvc结合示例《转载》

    一.介绍 因为项目要用到Ioc框架,所以要为Ioc框架选型,优秀的Ioc框架好几款,例如:sping.net,castle,unity--当然还不止三款,还有其它的Ioc框架,castle跟unity ...

  5. 搭建你的Spring.Net+Nhibernate+Asp.Net Mvc 框架

    搭建你的Spring.Net+Nhibernate+Asp.Net Mvc 框架 学习网址哦: 很不错的 http://www.cnblogs.com/fly_dragon/archive/2010/ ...

  6. 开源框架完美组合之Spring.NET + NHibernate + ASP.NET MVC + jQuery + easyUI 中英文双语言小型企业网站Demo项目分析

    开源框架完美组合之Spring.NET + NHibernate + ASP.NET MVC + jQuery + easyUI 中英文双语言小型企业网站Demo,这个是一个在网上流传比较多的Spri ...

  7. ASP.NET MVC实践系列6-Grid实现(上)

    ASP.NET MVC中不推荐使用webform的控件了,也就是说当希望列表显示数据时不能使用GridView了,很多开源软件为ASP.NET MVC实现了列表的解决方案,这些具体的解决方案我们放到下 ...

  8. ASP.NET MVC实践系列11-FCKEditor和CKEditor的使用

    FCKEditor是一款强大的在线编辑器,简单实用,多浏览器兼容,免费开源,应用十分广泛,据他的官方网站上称有三百多万的下载量,而且无数的知名大公司正在使用它.所以FCKEditor是很值得信赖的,现 ...

  9. ASP.NET MVC动态加载数据

    ASP.NET MVC动态加载数据,一般的做法是使用$.each方法来循环产生tabel: 你可以在html时先写下非动态的部分: <table><tr><th styl ...

最新文章

  1. Nginx入门笔记之————配置文件结构
  2. ANSI C中的sizeof详解
  3. 将指定日期字符串转换为Calendar对象
  4. JZOJ 3813. 【NOIP2014模拟9.7】我要的幸福
  5. 3_10 MediaMode 中介者模式
  6. Socket之UDP客户端【Python】
  7. 微型计算机选用要点,微型计算机原理以及应用考试_new要点分析.doc
  8. javascript的list循环
  9. 锁Lock,主要是重入锁和读写锁
  10. 国内信号处理类EI期刊
  11. python 占用内存过高_PyCharm如何优化?太占内存了,太慢了
  12. java rnn生成古诗_基于循环神经网络(RNN)的古诗生成器
  13. 什么是pid控制算法_控制算法原理及实现之PID(以飞控为例)
  14. RFID定位之隧道人员定位系统解决方案--新导智能
  15. matlab算sma,如何计算简单移动平均线(SMA)
  16. coe_xfr_sql_profile.sql和coe_load_sql_profile.sql
  17. 本周言论 之 违法行为
  18. 熊掌号周级推送php教程,浅析,熊掌号:实时、小时、天级、周级收录!
  19. 波士顿动力开源代码_学生为这所开源高中提供动力
  20. html页面输出json数据,带格式,带中文

热门文章

  1. checked js 获取值_js获取所有checkbox的值的简单实例
  2. md5加密后的数据如何解密_如何在云中加密数据
  3. c++数据结构代码整理_抄代码对自己编程提高有用嘛
  4. layui移动端适配_实战:移动端适配的最佳实践
  5. phpstorm运行java项目_phpstorm的提速设置
  6. 【大连】2021年下半年软考报考时间及通知
  7. Linux系统中软链接与硬链接使用特点
  8. CentOS中使用Docker来部署Tomcat
  9. 信息系统项目管理师-合同法、招投标法、政府采购法、著作权法考点笔记
  10. ElementUI中的el-table怎样实现每一列显示的是控件并能动态实现双向数据绑定