C#.NET编程----Spring.NET & NHibernate整合(三)
Spring.NET 与 NHibernate 的整合
我们成功的运行了自己的第一个Spring.NET程序和第一个NHibernate程序。下面我们将上面的程序整合到一个项目中来。让Spring.NET的容器来管理NHibernate。
建立新的项目(SpringNHibernateSample)
项目名称为:SpringNHibernateSample 名字空间:OKEC.Sample
添加NHibernate程序
将NHibernateSample项目的User.cs、User.hbm.xml加入的新的项目中。
<class name=" OKEC.Sample.NHibernate.NHibernateTest.User,NHibernateSample"
table="my_users">
改为table="my_users">
<class name=" OKEC.Sample.NHibernate.NHibernateTest.User,SpringNHibernateSample"
table="my_users">
table="my_users">
添加Spring.NET的程序
n 首先,需要将SpringSample项目中的HelloTest.cs、Spring_bean.xml、SpringContext.cs加入到新的项目,并修改其中有用到程序集相关的地方。
<object id="Hello" type="OKEC.Sample.Spring.HelloTest,SpringSample" />
改为<object id="Hello" type="OKEC.Sample.Spring.HelloTest,SpringNHibernateSample" />
n 然后,添加一个为NHibernate提供DbProvider的实现类,此类实现了Spring.Data.Common.IDbProvider接口,为NHibernate提供DbProvider所需的链接字串(ConnectionString)。
using System;
using Spring.Data.Common;
namespace OKEC.Sample.Spring
{
/// <summary>
/// SQLPriv 的摘要说明。
/// </summary>
public class SQLProvider:IDbProvider
{
public SQLProvider()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#region IDbProvider 成员
public System.Data.IDbConnection CreateConnection()
{
// TODO: 添加 SQLPriv.CreateConnection 实现
return null;
}
public string CreateParameterName(string name)
{
// TODO: 添加 SQLPriv.CreateParameterName 实现
return null;
}
public System.Data.IDbDataParameter CreateParameter()
{
// TODO: 添加 SQLPriv.CreateParameter 实现
return null;
}
private string _connectionString="";
public string ConnectionString
{
get
{
// TODO: 添加 SQLPriv.ConnectionString getter 实现
return _connectionString;
}
set
{
_connectionString = value;
// TODO: 添加 SQLPriv.ConnectionString setter 实现
}
}
public string ExtractError(Exception e)
{
// TODO: 添加 SQLPriv.ExtractError 实现
return null;
}
public System.Data.IDbDataAdapter CreateDataAdapter()
{
// TODO: 添加 SQLPriv.CreateDataAdapter 实现
return null;
}
public bool IsDataAccessException(Exception e)
{
// TODO: 添加 SQLPriv.IsDataAccessException 实现
return false;
}
public System.Data.IDbCommand CreateCommand()
{
// TODO: 添加 SQLPriv.CreateCommand 实现
return null;
}
public object CreateCommandBuilder()
{
// TODO: 添加 SQLPriv.CreateCommandBuilder 实现
return null;
}
public IDbMetadata DbMetadata
{
get
{
// TODO: 添加 SQLPriv.DbMetadata getter 实现
return null;
}
}
#endregion
}
}
using Spring.Data.Common;
namespace OKEC.Sample.Spring
{
/// <summary>
/// SQLPriv 的摘要说明。
/// </summary>
public class SQLProvider:IDbProvider
{
public SQLProvider()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#region IDbProvider 成员
public System.Data.IDbConnection CreateConnection()
{
// TODO: 添加 SQLPriv.CreateConnection 实现
return null;
}
public string CreateParameterName(string name)
{
// TODO: 添加 SQLPriv.CreateParameterName 实现
return null;
}
public System.Data.IDbDataParameter CreateParameter()
{
// TODO: 添加 SQLPriv.CreateParameter 实现
return null;
}
private string _connectionString="";
public string ConnectionString
{
get
{
// TODO: 添加 SQLPriv.ConnectionString getter 实现
return _connectionString;
}
set
{
_connectionString = value;
// TODO: 添加 SQLPriv.ConnectionString setter 实现
}
}
public string ExtractError(Exception e)
{
// TODO: 添加 SQLPriv.ExtractError 实现
return null;
}
public System.Data.IDbDataAdapter CreateDataAdapter()
{
// TODO: 添加 SQLPriv.CreateDataAdapter 实现
return null;
}
public bool IsDataAccessException(Exception e)
{
// TODO: 添加 SQLPriv.IsDataAccessException 实现
return false;
}
public System.Data.IDbCommand CreateCommand()
{
// TODO: 添加 SQLPriv.CreateCommand 实现
return null;
}
public object CreateCommandBuilder()
{
// TODO: 添加 SQLPriv.CreateCommandBuilder 实现
return null;
}
public IDbMetadata DbMetadata
{
get
{
// TODO: 添加 SQLPriv.DbMetadata getter 实现
return null;
}
}
#endregion
}
}
n 最后,添加一个Spring.Data.NHibernate对NHibernate的封装对像,此对像实现对User对像数据操作,继承自
using System;
using System.Collections;
using Spring.Data.NHibernate.Support;
namespace OKEC.Sample.NHibernate.NHibernateTest
{
/// <summary>
/// UserDao 的摘要说明。
/// </summary>
public class UserDao : HibernateDaoSupport
{
public UserDao()
{ //
// TODO: 在此处添加构造函数逻辑
//
}
public bool SaveObject(User user)
{
HibernateTemplate.Save(user);
return true;
}
public bool DeleteObject(User user)
{
HibernateTemplate.Delete(user);
return true;
}
public bool UpdateObject(User user)
{
HibernateTemplate.Update(user);
return true;
}
public IList GetAllObjectsList()
{
return HibernateTemplate.LoadAll(typeof(User));
}
public User Load(Object ID)
{
return (User)HibernateTemplate.Load(typeof(User),ID);
}
}
}
using System.Collections;
using Spring.Data.NHibernate.Support;
namespace OKEC.Sample.NHibernate.NHibernateTest
{
/// <summary>
/// UserDao 的摘要说明。
/// </summary>
public class UserDao : HibernateDaoSupport
{
public UserDao()
{ //
// TODO: 在此处添加构造函数逻辑
//
}
public bool SaveObject(User user)
{
HibernateTemplate.Save(user);
return true;
}
public bool DeleteObject(User user)
{
HibernateTemplate.Delete(user);
return true;
}
public bool UpdateObject(User user)
{
HibernateTemplate.Update(user);
return true;
}
public IList GetAllObjectsList()
{
return HibernateTemplate.LoadAll(typeof(User));
}
public User Load(Object ID)
{
return (User)HibernateTemplate.Load(typeof(User),ID);
}
}
}
添加Spring.NET为NHibernate的容器配置
现在就可以在Spring.NET的容器中添加Nhibernate的配置了。
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns='http://www.springframework.net'>
<!-- NHibernate初始化的 -->
<object id="DbProvider" type="OKEC.Sample.Spring.SQLProvider,SpringNHibernateSample">
<property name="ConnectionString" value="Data Source=192.168.88.15;Database=liluhua;User ID=sa;Password=sa;Trusted_Connection=False"/>
</object>
<object id="SessionFactory"
type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate">
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingAssemblies">
<list>
<value>SpringNhibernateSample</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry
key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<!--entry
key="hibernate.connection.connection_string" value="Data Source=192.168.188.188;Database=Test;User ID=satest;Password=satest;Trusted_Connection=False"/-->
<entry key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect"/>
<entry
key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
</dictionary>
</property>
</object>
<object id="HibernateTransactionManager" type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate">
<property name="DbProvider" ref="DbProvider"/>
<property name="sessionFactory" ref="SessionFactory"/>
</object>
<object id="TransactionInterceptor"
type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
<property name="TransactionManager" ref="HibernateTransactionManager"/>
<property name="TransactionAttributeSource">
<object
type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data"/>
</property>
</object>
<!-- 以下是业务相关的 -->
<objects xmlns='http://www.springframework.net'>
<!-- NHibernate初始化的 -->
<object id="DbProvider" type="OKEC.Sample.Spring.SQLProvider,SpringNHibernateSample">
<property name="ConnectionString" value="Data Source=192.168.88.15;Database=liluhua;User ID=sa;Password=sa;Trusted_Connection=False"/>
</object>
<object id="SessionFactory"
type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate">
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingAssemblies">
<list>
<value>SpringNhibernateSample</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry
key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<!--entry
key="hibernate.connection.connection_string" value="Data Source=192.168.188.188;Database=Test;User ID=satest;Password=satest;Trusted_Connection=False"/-->
<entry key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect"/>
<entry
key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
</dictionary>
</property>
</object>
<object id="HibernateTransactionManager" type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate">
<property name="DbProvider" ref="DbProvider"/>
<property name="sessionFactory" ref="SessionFactory"/>
</object>
<object id="TransactionInterceptor"
type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
<property name="TransactionManager" ref="HibernateTransactionManager"/>
<property name="TransactionAttributeSource">
<object
type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data"/>
</property>
</object>
<!-- 以下是业务相关的 -->
<object id="UserDao"
type="OKEC.Sample.NHibernate.NHibernateTest.UserDao, SpringNHibernateSample">
<property name="SessionFactory" ref="SessionFactory"/>
</object>
我们现在对上面的加以细解:
<object id="DbProvider" type="OKEC.Sample.Spring.SQLProvider,SpringNHibernateSample">
<property name="ConnectionString" value="Data Source=192.168.88.15;Database=liluhua;User ID=sa;Password=sa;Trusted_Connection=False"/>
</object>
<property name="ConnectionString" value="Data Source=192.168.88.15;Database=liluhua;User ID=sa;Password=sa;Trusted_Connection=False"/>
</object>
下面的是对Nhibernate的SessionFactory的封装的对像的定义
<object id="SessionFactory"
type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate">
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingAssemblies">
<list>
<value>SpringNhibernateSample</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<!--entry key="hibernate.connection.connection_string" value="Data Source=192.168.188.188;Database=Test;User ID=satest;Password=satest;Trusted_Connection=False"/-->
<entry key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect"/>
<entry key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
</dictionary>
</property>
</object>
type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate">
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingAssemblies">
<list>
<value>SpringNhibernateSample</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<!--entry key="hibernate.connection.connection_string" value="Data Source=192.168.188.188;Database=Test;User ID=satest;Password=satest;Trusted_Connection=False"/-->
<entry key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect"/>
<entry key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
</dictionary>
</property>
</object>
下面的是对Nhibernate中的Transaction封装对像
<object id="HibernateTransactionManager" type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate">
<property name="DbProvider" ref="DbProvider"/>
<property name="sessionFactory" ref="SessionFactory"/>
</object>
<object id="TransactionInterceptor" type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
<property name="TransactionManager" ref="HibernateTransactionManager"/>
<property name="TransactionAttributeSource">
<object type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data"/>
</property>
</object>
<property name="DbProvider" ref="DbProvider"/>
<property name="sessionFactory" ref="SessionFactory"/>
</object>
<object id="TransactionInterceptor" type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
<property name="TransactionManager" ref="HibernateTransactionManager"/>
<property name="TransactionAttributeSource">
<object type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data"/>
</property>
</object>
下面是对NHibernate业务操作对像的定义
<object id="UserDao"
type="OKEC.Sample.NHibernate.NHibernateTest.UserDao, SpringNHibernateSample">
<property name="SessionFactory" ref="SessionFactory"/>
</object>
type="OKEC.Sample.NHibernate.NHibernateTest.UserDao, SpringNHibernateSample">
<property name="SessionFactory" ref="SessionFactory"/>
</object>
一切准备就绪,我们就可以编写测试程序的代码了。
如下:StartMain.cs
using System;
using System.Collections;
using OKEC.Sample.NHibernate.NHibernateTest;
namespace OKEC.Sample.Spring
{
/// <summary>
/// StartMain 的摘要说明。
/// </summary>
public class StartMain
{
public StartMain()
{ //
// TODO: 在此处添加构造函数逻辑
//
}
[STAThread]
static void Main()
{
//Startup Spring & NHibernate Content
SpringContext.init();
//Test Spring IOC
HelloTest test = (HelloTest)SpringContext.Context.GetObject("Hello");
test.Test();
//Test Spring & NHibernate
UserDao dao = SpringContext.Context.GetObject("UserDao") as UserDao;
User newUser = null;
try
{
newUser = dao.Load("joe_cool");
}
catch
{}
if(newUser==null)
{
newUser = new User();
newUser.Id = "joe_cool";
newUser.UserName = "Joseph Cool";
newUser.Password = "abc123";
newUser.EmailAddress = "joe@cool.com";
newUser.LastLogon = DateTime.Now;
// Tell NHibernate that this object should be saved
dao.SaveObject(newUser);
}
User joeCool = dao.Load("joe_cool");
// set Joe Cool's Last Login property
joeCool.LastLogon = DateTime.Now;
// flush the changes from the Session to the Database
dao.UpdateObject(joeCool);
IList recentUsers = dao.GetAllObjectsList();
foreach(User user in recentUsers)
{
//Assert.IsTrue(user.LastLogon > (new DateTime(2004, 03, 14, 20, 0, 0)) );
Console.WriteLine(user.UserName);
Console.WriteLine(user.Password);
}
Console.ReadLine();//让程序停留,回车关闭。
}
}
}
using System.Collections;
using OKEC.Sample.NHibernate.NHibernateTest;
namespace OKEC.Sample.Spring
{
/// <summary>
/// StartMain 的摘要说明。
/// </summary>
public class StartMain
{
public StartMain()
{ //
// TODO: 在此处添加构造函数逻辑
//
}
[STAThread]
static void Main()
{
//Startup Spring & NHibernate Content
SpringContext.init();
//Test Spring IOC
HelloTest test = (HelloTest)SpringContext.Context.GetObject("Hello");
test.Test();
//Test Spring & NHibernate
UserDao dao = SpringContext.Context.GetObject("UserDao") as UserDao;
User newUser = null;
try
{
newUser = dao.Load("joe_cool");
}
catch
{}
if(newUser==null)
{
newUser = new User();
newUser.Id = "joe_cool";
newUser.UserName = "Joseph Cool";
newUser.Password = "abc123";
newUser.EmailAddress = "joe@cool.com";
newUser.LastLogon = DateTime.Now;
// Tell NHibernate that this object should be saved
dao.SaveObject(newUser);
}
User joeCool = dao.Load("joe_cool");
// set Joe Cool's Last Login property
joeCool.LastLogon = DateTime.Now;
// flush the changes from the Session to the Database
dao.UpdateObject(joeCool);
IList recentUsers = dao.GetAllObjectsList();
foreach(User user in recentUsers)
{
//Assert.IsTrue(user.LastLogon > (new DateTime(2004, 03, 14, 20, 0, 0)) );
Console.WriteLine(user.UserName);
Console.WriteLine(user.Password);
}
Console.ReadLine();//让程序停留,回车关闭。
}
}
}
测试并查看结果
如果你看到了以下的输出结果,说明你已经成功了!
This is Spring.NET Sample Test!
Please press Enter close the windows!
Joseph Cool
abc123
Please press Enter close the windows!
Joseph Cool
abc123
文档中的项目源代码请从以下地址下载:
http://www.springframework.cn/read.php?fid=8&tid=2&toread=1
完整的文档请下载PDF文档:
http://www.springframework.cn/read.php?fid=2&tid=1&toread=1