Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 3 ----数据访问层
来源:互联网 发布:数据恢复精灵离线激活 编辑:程序博客网 时间:2024/06/09 17:42
在上一篇中,我们已经搭建起了整个解决方案的项目,并且建好了数据库,完成了实体类和Nhibernate映射文件.在本文中,将定义数据访问接口,并利用Nhibernate实现接口,利用Spring.net配置起来dao.并对其进行单元测试.
数据访问层也和Petshop等框架一样,分为数据访问的接口以及实现,不过这里的数据访问实现相比之下就清晰和明显了的多,Nhibernate本身就是支持多数据库的,所以这样做不是为了多数据库,而是为了Nhibernate的可插拨,即使哪一天发现由于一些问题,比如说性能问题,可以重新实现IDAL接口,而不会对业务层造成比较大的改动.
说到这里,其实我们还不太清楚前台到底需要哪些功能,所以我们就先简单的实现实体的增删改查吧.等需要其它的功能时,再来完善接口和实现.
DirectCenter.IDAL不依赖于Spring或者是Nhibernate,只需要添加项目引用DirectCenter.Model.以用户来说吧,添加接口IUserDao.cs
IUserDao.cs<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->using System.Collections;using DirectCenter.Model;namespace DirectCenter.IDAL{ public interface 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.cs<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> public User Save(User user) { //通过一种方式获取Session Session session = SessionFactory.OpenSession(); session.Save(user); }
不过我们不打算使用这种单纯Nhibernate的方式,而是使用继承spring对hibernate的封装类HibernateDaoSupport,这样我们把Spring.net作为Nhibernate的容器可以方便的进行统一管理和利用一些特性.
UserDao.cs<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->using System.Collections;using Spring.Data.NHibernate.Support;using DirectCenter.IDAL;using DirectCenter.Model;namespace DirectCenter.DAL{ public class UserDao:HibernateDaoSupport,IUserDao { public User Save(User user) { HibernateTemplate.Save(user); return user; } public User SaveOrUpdate(User user) { HibernateTemplate.SaveOrUpdate(user); return user; } public void 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<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> /// <summary> /// Gets or sets the session factory that should be used to create /// NHibernate ISessions. /// </summary> /// <value>The session factory.</value> public override 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> public override 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> public override bool CacheQueries { get { return cacheQueries; } set { cacheQueries = value; } } public object Load(Type entityType, object id, LockMode lockMode) { return Execute(new LoadByTypeHibernateCallback(entityType, id, lockMode),true); } internal class LoadByTypeHibernateCallback : IHibernateCallback { private Type entityType; private object 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> public object 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<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><?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.cs<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->using System;using NUnit.Framework;using Spring.Testing.NUnit;using DirectCenter.Model;using DirectCenter.IDAL;namespace DirectCenter.UnitTest{ [TestFixture] public class UserDaoTest : AbstractTransactionalDbProviderSpringContextTests { protected override string[] ConfigLocations { get { return new String[] { "objects.xml" }; } } protected IUserDao UserDao { get { return applicationContext.GetObject("UserDao") as IUserDao; } } [Test] public void 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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
»博主后一篇:设计模式学习实践---策略模式(Strategy Pattern)
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 3 ----数据访问层
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 3 ----数据访问层
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 3 ----数据访问层
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 3 ----数据访问层
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 1
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 2
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 1
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 2
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 1
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 1---准备
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs系列总结
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 4 ----业务逻辑层
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 4 ----业务逻辑层
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 4 ----业务逻辑层
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 5 ----asp.net MVC+Extjs
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 6 ----asp.net MVC+Extjs
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 2----整体架构
- Jquery Select操作方法集合
- iphone开发基础三和c语言混编
- [转贴]俞天任:日本家电行业还能起死回生吗
- 使用CxImage库的初体验
- mysql 操纵数据语句
- Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 3 ----数据访问层
- VC程序员常用工具篇(加补充整理)
- c++ 临时对象
- php标准库函数功能之ArrayObject
- jion方法(合并某个线程) jion()调用优先级别,把"谢霆锋"调到前面输出
- C# WinForm开发系列
- 用JS编写日历的简单思路
- 计算机图形管线
- 验证码