NHibernate Step by Step(二) 单表操作 (转)

NHibernate Step by Step() 单表操作

接着第一期,我们继续。

为了方便学习测试,从今天开始我将使用MS Test来进行测试,这样就避免了在一个Console工程里不停地添加、注释代码了。

 

提示:为了在VS2005IDE中获得NHibernate配置文件的代码提示,请将你的$NHibernate\src\NHibernate下的nhibernate-configuration-2.0.xsdnhibernate-mapping-2.0.xsd拷贝到\Program Files\Microsoft Visual Studio 8\Xml\Schemas下,这样当你编辑配置文件或者映射文件时,你将得到完整的代码提示。
VS2003请拷贝到\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\schemas\xml下。

 

NHibernat内部使用log4net来进行日志操作,今天我们将在配置文件中添加log4net的配置,这样我们在测试的时候将可以清楚地看到NHibernate是如何进行工作的。

应用配置文件修改如下:

None.gif <? xml version="1.0" encoding="utf-8"  ?>
None.gif
< configuration >
None.gif  
< configSections >
None.gif    
< section  name ="nhibernate"  type ="System.Configuration.NameValueSectionHandler, System,Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"   />
None.gif    
< section  name ="log4net"  type ="log4net.Config.Log4NetConfigurationSectionHandler,log4net"   />
None.gif  
</ configSections >
None.gif
None.gif  
< nhibernate >
None.gif    
< add  key ="hibernate.connection.provider"  value ="NHibernate.Connection.DriverConnectionProvider"   />
None.gif    
< add  key ="hibernate.connection.driver_class"  value ="NHibernate.Driver.SqlClientDriver"   />
None.gif    
< add  key ="hibernate.connection.connection_string"  value ="Server=localhost;Initial Catalog=NHibernate;Integrated Security=SSPI"   />
None.gif    
< add  key ="hibernate.connection.isolation"  value ="ReadCommitted" />
None.gif    
< add  key ="hibernate.dialect"  value ="NHibernate.Dialect.MsSql2000Dialect"   />
None.gif    
< add  key ="show_sql"  value ="true"   />
None.gif  
</ nhibernate >
None.gif
None.gif  
< log4net >
None.gif    
< appender  name ="ConsoleAppender"  type ="log4net.Appender.ConsoleAppender"   >
None.gif      
< layout  type ="log4net.Layout.PatternLayout" >
None.gif        
< conversionPattern  value ="%date [%thread] %-5level %logger [%ndc] - %message%newline"   />
None.gif      
</ layout >
None.gif    
</ appender >
None.gif    
< root >
None.gif      
< level  value ="ALL"   />
None.gif      
< appender-ref  ref ="ConsoleAppender"   />
None.gif    
</ root >
None.gif
None.gif  
</ log4net >
None.gif
None.gif
</ configuration >
None.gif

 

请注意添加:

None.gif < add  key ="show_sql"  value ="true"   />

  

 

关于log4net的使用,我们这里不做详细的讲解,有兴趣的请参考如下地址:

http://logging.apache.org/log4net/

 

接着,我们在上次的工程组中添加一个名为Test1的测试项目,将其中的不需要的手动测试去掉。请注意:除了NHibernate\Model引用外,还需要添加如下3个引用:

log4net,System.Data,System.Xml.


修改代码如下:

None.gif using  System;
None.gif
using  System.Text;
None.gif
using  System.Collections;
None.gif
using  Microsoft.VisualStudio.TestTools.UnitTesting;
None.gif
using  NHibernate;
None.gif
using  NHibernate.Cfg;
None.gif
using  log4net;
None.gif
using  log4net.Config;
None.gif
using  Test.Model;
None.gif
None.gif
namespace  Test1
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// Summary description for UnitTest1
ExpandedSubBlockEnd.gif    
/// </summary> 

InBlock.gif    [TestClass]
InBlock.gif    
public class UnitTest1
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
static ISessionFactory factory;
InBlock.gif        
static ILog logger;
InBlock.gif        ISession session;
InBlock.gif
InBlock.gif        
public UnitTest1()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockEnd.gif        }

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
Additional test attributes#region Additional test attributes
InBlock.gif        
InBlock.gif         [ClassInitialize()]
InBlock.gif         
public static void MyClassInitialize(TestContext testContext) 
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif             XmlConfigurator.Configure();
InBlock.gif             logger 
= LogManager.GetLogger(typeof(Test1.UnitTest1));
InBlock.gif             Configuration config 
= new Configuration().AddAssembly("Test.Model");
InBlock.gif             factory 
= config.BuildSessionFactory();
ExpandedSubBlockEnd.gif         }

InBlock.gif        
InBlock.gif         [ClassCleanup()]
ExpandedSubBlockStart.gifContractedSubBlock.gif         
public static void MyClassCleanup() dot.gif{ }
InBlock.gif        
InBlock.gif         [TestInitialize()]
InBlock.gif         
public void MyTestInitialize() 
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif             session 
= factory.OpenSession();
ExpandedSubBlockEnd.gif         }

InBlock.gif        
InBlock.gif         [TestCleanup()]
InBlock.gif         
public void MyTestCleanup() 
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif             session.Close();
ExpandedSubBlockEnd.gif         }

InBlock.gif        
ExpandedSubBlockEnd.gif        
#endregion

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

 

我们在测试的开始对Configuration\SessionFactory\Log进行初始化。在每一个Test的开始获取一个新的session,每一个Test结束后即关闭session


添加如下一个
Get测试:

 
 
None.gif [TestMethod]
None.gif
public   void  TestRead()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif      Person person 
= (Person)session.Get(typeof(Person), 1);
InBlock.gif      Assert.IsTrue(person.Name 
== "Jackie Chan");
ExpandedBlockEnd.gif}

None.gif


我们在前面曾经插入一条名为“Jackie Chan”的记录,现在在Test Manager中选中TestRead,运行,ok,Passed!
我们使用了session.Get来获取记录,方法如下:

object Get(Type clazz,object id);

很简单,一目了然。


我们切换到
Test Results窗口,双击测试成功的TestRead方法,这时将会有一个详细的测试结果显示出来,NHibernate将使用我们指定的log4net来输出详细信息,我们仔细观察:


2006-04-15 13:52:13,000 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.SessionImpl [(null)] - opened session

2006-04-15 13:52:13,015 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.SessionImpl [(null)] - loading [Person#1]

2006-04-15 13:52:13,015 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.SessionImpl [(null)] - attempting to resolve [Person#1]

2006-04-15 13:52:13,015 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.SessionImpl [(null)] - object not resolved in any cache [Test.Model.Person#1]

2006-04-15 13:52:13,015 [AdpaterExeMgrThread1] DEBUG NHibernate.Persister.EntityPersister [(null)] - Materializing entity: Test.Model.Person#1


2006-04-15 13:52:13,078 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.BatcherImpl [(null)] - Opened new IDbCommand, open IDbCommands :1

2006-04-15 13:52:13,078 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.BatcherImpl [(null)] - Building an IDbCommand object for the SqlString: SELECT person0_.id as id0_, person0_.name as name0_ FROM Person person0_ WHERE person0_.id=:id

2006-04-15 13:52:13,093 [AdpaterExeMgrThread1] DEBUG NHibernate.Type.Int32Type [(null)] - binding '1' to parameter: 0

2006-04-15 13:52:13,093 [AdpaterExeMgrThread1] INFO  NHibernate.Loader.Loader [(null)] - SELECT person0_.id as id0_, person0_.name as name0_ FROM Person person0_ WHERE person0_.id=@p0

2006-04-15 13:52:13,093 [AdpaterExeMgrThread1] DEBUG NHibernate.SQL [(null)] - SELECT person0_.id as id0_, person0_.name as name0_ FROM Person person0_ WHERE person0_.id=@p0

2006-04-15 13:52:13,093 [AdpaterExeMgrThread1] DEBUG NHibernate.SQL [(null)] - @p0 = '1'


2006-04-15 13:52:13,093 [AdpaterExeMgrThread1] DEBUG NHibernate.Connection.DriverConnectionProvider [(null)] - Obtaining IDbConnection from Driver

2006-04-15 13:52:13,859 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.BatcherImpl [(null)] - Opened Reader, open Readers :1

2006-04-15 13:52:13,859 [AdpaterExeMgrThread1] DEBUG NHibernate.Loader.Loader [(null)] - processing result set

2006-04-15 13:52:13,875 [AdpaterExeMgrThread1] DEBUG NHibernate.Loader.Loader [(null)] - result row: 1

2006-04-15 13:52:13,875 [AdpaterExeMgrThread1] DEBUG NHibernate.Loader.Loader [(null)] - Initializing object from DataReader: 1

2006-04-15 13:52:13,875 [AdpaterExeMgrThread1] DEBUG NHibernate.Loader.Loader [(null)] - Hydrating entity: Test.Model.Person#1

2006-04-15 13:52:13,906 [AdpaterExeMgrThread1] DEBUG NHibernate.Type.StringType [(null)] - returning 'Jackie Chan' as column: name0_

2006-04-15 13:52:13,906 [AdpaterExeMgrThread1] DEBUG NHibernate.Loader.Loader [(null)] - done processing result set (1 rows)

2006-04-15 13:52:13,937 [AdpaterExeMgrThread1] DEBUG NHibernate.Driver.NHybridDataReader [(null)] - running NHybridDataReader.Dispose()

2006-04-15 13:52:13,937 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.BatcherImpl [(null)] - Closed Reader, open Readers :0

2006-04-15 13:52:13,937 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.BatcherImpl [(null)] - Closed IDbCommand, open IDbCommands :0

2006-04-15 13:52:13,937 [AdpaterExeMgrThread1] DEBUG NHibernate.Loader.Loader [(null)] - total objects hydrated: 1

2006-04-15 13:52:13,953 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.SessionImpl [(null)] - resolving associations for: [Test.Model.Person#1]

2006-04-15 13:52:13,953 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.SessionImpl [(null)] - done materializing entity [Test.Model.Person#1]

2006-04-15 13:52:13,953 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.SessionImpl [(null)] - initializing non-lazy collections

2006-04-15 13:52:13,953 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.SessionImpl [(null)] - closing session

2006-04-15 13:52:13,953 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.SessionImpl [(null)] - disconnecting session

2006-04-15 13:52:13,953 [AdpaterExeMgrThread1] DEBUG NHibernate.Connection.ConnectionProvider [(null)] - Closing connection

2006-04-15 13:52:13,968 [AdpaterExeMgrThread1] DEBUG NHibernate.Impl.SessionImpl [(null)] - transaction completion

 

在其中,我们可以发现:


2006-04-15 13:52:13,093 [AdpaterExeMgrThread1] DEBUG NHibernate.SQL [(null)] - SELECT person0_.id as id0_, person0_.name as name0_ FROM Person person0_ WHERE person0_.id=@p0

2006-04-15 13:52:13,093 [AdpaterExeMgrThread1] DEBUG NHibernate.SQL [(null)] - @p0 = '1'


对了,就是这里,
NHibernate替我们构造了一条sql语句,并添加一个参数,然后将我们在代码中赋的id1来填充,这样,一条完整的可以执行的sql语句产生了。

请注意:在产生sql语句的前面,NHibernate构造了一个IDBCommand,然后在sql语句产生完全后,获取连接,通过一个DataReader来填充Persion对象给我们使用,这就是NHibernate替我们做的事,是不是很简单啊?(真的很简单吗??看看源代码吧!!)

请仔细研究输出的日志。

 

如法炮制,我们添加另外3Test,完成单个表的全部CRUD操作,如下完整代码:

None.gif [TestMethod]
None.gif
None.gif        
public   void  TestCreate()
None.gif
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif
InBlock.gif            Person person 
= new Person();
InBlock.gif
InBlock.gif            person.Name 
= "Jackie Chan";
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif            ITransaction trans 
= session.BeginTransaction();
InBlock.gif
InBlock.gif            
try
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                session.Save(person);
InBlock.gif
InBlock.gif                trans.Commit();
InBlock.gif
InBlock.gif                Assert.IsTrue(person.Id 
> 0);
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
catch (Exception ex)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                trans.Rollback();
InBlock.gif
InBlock.gif                Assert.Fail(ex.Message);
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedBlockEnd.gif        }

None.gif
None.gif 
None.gif
None.gif        [TestMethod]
None.gif
None.gif        
public   void  TestUpdate()
None.gif
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif
InBlock.gif            Person person 
= (Person)session.Get(typeof(Person), 1);
InBlock.gif
InBlock.gif            person.Name 
= "Jet Li";
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif            ITransaction trans 
= session.BeginTransaction();
InBlock.gif
InBlock.gif            
try
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                session.Save(person);
InBlock.gif
InBlock.gif                trans.Commit();
InBlock.gif
InBlock.gif                Assert.IsTrue(person.Name 
== "Jet Li");
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
catch (Exception ex)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                trans.Rollback();
InBlock.gif
InBlock.gif                Assert.Fail(ex.Message);
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedBlockEnd.gif        }

None.gif
None.gif 
None.gif
None.gif        [TestMethod]
None.gif
None.gif        
public   void  TestRead()
None.gif
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif
InBlock.gif            Person person 
= (Person)session.Get(typeof(Person), 1);
InBlock.gif
InBlock.gif            Assert.IsTrue(person.Name 
== "Jackie Chan");
InBlock.gif
ExpandedBlockEnd.gif        }

None.gif
None.gif 
None.gif
None.gif        [TestMethod]
None.gif
None.gif        
public   void  TestDelete()
None.gif
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif
InBlock.gif            Person person 
= (Person)session.Get(typeof(Person), 1);
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif            ITransaction trans 
= session.BeginTransaction();
InBlock.gif
InBlock.gif            
try
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                session.Delete(person);
InBlock.gif
InBlock.gif                trans.Commit();
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
catch (Exception ex)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                trans.Rollback();
InBlock.gif
InBlock.gif                Assert.Fail(ex.Message);
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedBlockEnd.gif        }

None.gif
None.gif

 

Delete的方法如下:

void Delete(object obj);

直接传入需要delete的对象即可。

 

好了,基本的操作都完成了,是不是很Easy?

好了,这一篇就讲这么多,我们下次再接着练习。
 

Step by Step,顾名思义,是一步一步来的意思,整个教程我将贯彻这一理念。

任何建议或者批评,请eabluedog@163.com

 

原文:http://www.cnblogs.com/abluedog/archive/2006/04/15/375940.html

转载于:https://www.cnblogs.com/lyh55/archive/2010/07/08/1773504.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值