NHibernate Step by Step(二) 单表操作

NHibernate Step by Step(二) 单表操作
 
接着第一期,我们继续。
 
为了方便学习测试,从今天开始我将使用MS Test来进行测试,这样就避免了在一个Console工程里不停地添加、注释代码了。
 
 
 
提示:为了在VS2005IDE中获得NHibernate配置文件的代码提示,请将你的$NHibernate/src/NHibernate下的nhibernate-configuration-2.0.xsd、nhibernate-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是如何进行工作的。
 
应用配置文件修改如下:

 
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System,Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
  </configSections>

  <nhibernate>
    <add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
    <add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
    <add key="hibernate.connection.connection_string" value="Server=localhost;Initial Catalog=NHibernate;Integrated Security=SSPI" />
    <add key="hibernate.connection.isolation" value="ReadCommitted"/>
    <add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" />
    <add key="show_sql" value="true" />
  </nhibernate>

  <log4net>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
      </layout>
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="ConsoleAppender" />
    </root>

  </log4net>

</configuration>

 
 
 
 
 


请注意添加:
 
 
 
<add key="show_sql" value="true" />
 
 
 
 
 
关于log4net的使用,我们这里不做详细的讲解,有兴趣的请参考如下地址:
 
http://logging.apache.org/log4net/
 
 
 
接着,我们在上次的工程组中添加一个名为Test1的测试项目,将其中的不需要的手动测试去掉。请注意:除了NHibernate/Model引用外,还需要添加如下3个引用:
 
log4net,System.Data,System.Xml.

 

修改代码如下:
 


using System;
using System.Text;
using System.Collections;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NHibernate;
using NHibernate.Cfg;
using log4net;
using log4net.Config;
using Test.Model;

namespace Test1
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class UnitTest1
    {
        static ISessionFactory factory;
        static ILog logger;
        ISession session;

        public UnitTest1()
        {
        }

        #region Additional test attributes
       
         [ClassInitialize()]
         public static void MyClassInitialize(TestContext testContext)
         {
             XmlConfigurator.Configure();
             logger = LogManager.GetLogger(typeof(Test1.UnitTest1));
             Configuration config = new Configuration().AddAssembly("Test.Model");
             factory = config.BuildSessionFactory();
         }
       
         [ClassCleanup()]
         public static void MyClassCleanup() { }
       
         [TestInitialize()]
         public void MyTestInitialize()
         {
             session = factory.OpenSession();
         }
       
         [TestCleanup()]
         public void MyTestCleanup()
         {
             session.Close();
         }
       
        #endregion
    }
}

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

 

添加如下一个Get测试:
 
[TestMethod]
public void TestRead()
{
      Person person = (Person)session.Get(typeof(Person), 1);
      Assert.IsTrue(person.Name == "Jackie Chan");
}

 

我们在前面曾经插入一条名为“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语句,并添加一个参数,然后将我们在代码中赋的id值1来填充,这样,一条完整的可以执行的sql语句产生了。
 
请注意:在产生sql语句的前面,NHibernate构造了一个IDBCommand,然后在sql语句产生完全后,获取连接,通过一个DataReader来填充Persion对象给我们使用,这就是NHibernate替我们做的事,是不是很简单啊?(真的很简单吗??看看源代码吧!!)
 
请仔细研究输出的日志。
 
 
 
如法炮制,我们添加另外3个Test,完成单个表的全部CRUD操作,如下完整代码:
 


[TestMethod]

        public void TestCreate()

        {

            Person person = new Person();

            person.Name = "Jackie Chan";

 

            ITransaction trans = session.BeginTransaction();

            try

            {

                session.Save(person);

                trans.Commit();

                Assert.IsTrue(person.Id > 0);

            }

            catch (Exception ex)

            {

                trans.Rollback();

                Assert.Fail(ex.Message);

            }

        }

 

        [TestMethod]

        public void TestUpdate()

        {

            Person person = (Person)session.Get(typeof(Person), 1);

            person.Name = "Jet Li";

 

            ITransaction trans = session.BeginTransaction();

            try

            {

                session.Save(person);

                trans.Commit();

                Assert.IsTrue(person.Name == "Jet Li");

            }

            catch (Exception ex)

            {

                trans.Rollback();

                Assert.Fail(ex.Message);

            }

        }

 

        [TestMethod]

        public void TestRead()

        {

            Person person = (Person)session.Get(typeof(Person), 1);

            Assert.IsTrue(person.Name == "Jackie Chan");

        }

 

        [TestMethod]

        public void TestDelete()

        {

            Person person = (Person)session.Get(typeof(Person), 1);

 

            ITransaction trans = session.BeginTransaction();

            try

            {

                session.Delete(person);

                trans.Commit();

            }

            catch (Exception ex)

            {

                trans.Rollback();

                Assert.Fail(ex.Message);

            }

        }


 
 
 
Delete的方法如下:
 
void Delete(object obj);
 
直接传入需要delete的对象即可。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/su317/archive/2009/08/05/4413778.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值