NHibernate Quick Start Guide

本文介绍NHibernate的基本使用方法,包括实体类定义、映射文件配置、数据库操作等,并演示了一对多及多对多关系的处理。

1 实体类:

Code
using System;
using System.Collections.Generic;
using System.Text;

namespace NHibernate.Examples.QuickStart
{
    
public class User
    
{
        
private string id;
        
private string userName;
        
private string password;
        
private string emailAddress;
        
private DateTime lastLogon;


        
public User()
        
{
        }


        
public virtual string Id
        
{
            
get return id; }
            
set { id = value; }
        }


        
public virtual string UserName
        
{
            
get return userName; }
            
set { userName = value; }
        }


        
public virtual string Password
        
{
            
get return password; }
            
set { password = value; }
        }


        
public virtual string EmailAddress
        
{
            
get return emailAddress; }
            
set { emailAddress = value; }
        }


        
public virtual DateTime LastLogon
        
{
            
get return lastLogon; }
            
set { lastLogon = value; }
        }


    }


}

注意点:在属性之前要加上virtual关键字,否则运行时会报错。


2 map文件:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  
<class name="NHibernate.Examples.QuickStart.User, NHibernate.Examples.QuickStart" table="users">
    
<id name="Id" column="LogonId" type="String" length="20">
      
<generator class="assigned" />
    
</id>
    
<property name="UserName" column="Name" type="String" length="40"/>
    
<property name="Password" type="String" length="20"/>
    
<property name="EmailAddress" type="String" length="40"/>
    
<property name="LastLogon" type="DateTime"/>
  
</class>
</hibernate-mapping>

注意点:如果对应的是.net framework2.0的版本,则

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">2.2

其次是class name一定要写对。前面是要映射类的全称,后面是namespase,也就是Assembly的名称。

还有在生成操作中一定要选:嵌入的资源。

1class: name属性指示了Post实体类的类名和所在的Assebmly的名称,NH将通过反射的方式找到所指示的实体类,关于.Net的反射的说明,请参考MSDN; table属性指示了该实体所对应的数据表的表名

2property: 指示实体属性和数据列的如何映射。name为实体的属性名称,实体的该属性可以为public/private/protected,甚至是 internalcolumn指示了该属性对应的数据列,若实体属性名称和数据列名称相同(忽视大小写),可以省略;type指示了实体属性的.Net 数据类型,可以省略,NH可以自动转换;length只是对string类型的属性适用,指示了字符串的最大长度。

3id: 指示主键。NH支持自动生成主键、数据库生成主键和手工赋值三种方式,我们这里手工赋值的方式,设定generatorclass="assigned"

3 hibernate.cfg.xml—配置文件

<?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" 
    
/>
  
</configSections>

  
<nhibernate>
    
<add 
      
key="hibernate.connection.provider"
      value
="NHibernate.Connection.DriverConnectionProvider"
    
/>
    
<add
      
key="hibernate.dialect"
      value
="NHibernate.Dialect.MsSql2000Dialect"
    
/>
    
<add
      
key="hibernate.connection.driver_class"
      value
="NHibernate.Driver.SqlClientDriver"
    
/>
    
<add
      
key="hibernate.connection.connection_string"
      value
="Server=192.168.0.11;database=NHibernate;uid=sa;pwd=davey@citiz.net;"
    
/>
  
</nhibernate>
</configuration>

注意:hibernate.connection.connection_string是数据库的连接字符串。

4 测试类:

using NHibernate;

using NHibernate.Cfg;

这两个是必须的。

        [SetUp]
        
public void BuildNHibernate()
        
{
            cfg 
= new Configuration();
            cfg.AddAssembly(
"NHibernate.Examples.QuickStart");
            factory 
= cfg.BuildSessionFactory();
            session 
= factory.OpenSession();

        }


在使用NHibernate进行数据库操作时需要以上这些东西。

3 Insert

Code
[Test]
        
public void AddUser()
        
{
            User newUser 
= new User();


            Configuration cfg 
= new Configuration();
            cfg.AddAssembly(
"NHibernate.Examples.QuickStart");
            ISessionFactory factory 
= cfg.BuildSessionFactory();
            ISession session 
= factory.OpenSession();
            ITransaction transaction 
= null;
            
try
            
{
                transaction 
= session.BeginTransaction();
                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
                session.Save(newUser);
                
// commit all of the changes to the DB and close the ISession
                transaction.Commit();
                session.Close();
            }

            
catch (HibernateException ex)
            
{
                
if (transaction != null) transaction.Rollback();
                
throw ex;
            }

            
finally
            
{
                
//关闭ISession
                session.Close();
            }

        }



4 update:
Code
        [Test]
        
public void UpdateUser()
        
{
            User joeCool 
= (User)session.Load(typeof(User), "joe_cool");
            Assert.AreEqual(
"Joseph Cool", joeCool.UserName);
            
try
            
{
                transaction 
= session.BeginTransaction();
                
// set Joe Cool's Last Login property
                joeCool.LastLogon = DateTime.Now;

                
// flush the changes from the Session to the Database
                session.Flush();
                
// commit all of the changes to the DB and close the ISession
                transaction.Commit();
            }

            
catch (HibernateException ex)
            
{
                
if (transaction != null) transaction.Rollback();
                
throw ex;
            }

            
finally
            
{
                
//关闭ISession
                session.Close();
            }


        }


5 select

根据主键查询

IList<User> userList = session.CreateCriteria(typeof(User)).List<User>();
有条件的查询


IList<User> recentUsers = session.CreateCriteria(typeof(User))
              .Add(Expression.Expression.Eq(
"UserName""Joseph Cool"))
                .List
<User>();

利用Hql语言查询
string hql = "  from User u where u.UserName = :Name ";
            IQuery query 
= session.CreateQuery(hql);
            query.SetString(
"Name","Joseph Cool");
            IList
<User> recentUsers = query.List<User>();

6 一对多,多对多关系的查询

实体类:

Category

Code
   public class Category
    
{
       
private Guid _categoryId; 
       
private string _name = string.Empty;
       
private IList<Item> _items;

       
public virtual Guid CategoryID
       
{
          
get return this._categoryId; }
          
set this._categoryId = value; }
        }


       
public virtual string Name
       
{
         
get return this._name; }
         
set this._name = value; }
       }


        
public virtual IList<Item> Items
        
{
           
get return this._items; }
           
set this._items = value; }
        }

 
    
        
public Category()
        
{
            
this._items = new List<Item>();
        }

     }


Item
Code
    public class Item
    
{
       
private Guid _itemId;
       
private string _name = string.Empty;
       
private Category _category;

       
public virtual Guid ItemID
       
{
        
get return this._itemId; }
        
set this._itemId = value; }
       }


       
public virtual string Name
       
{
           
get return this._name; }
           
set this._name = value; }
       }


        
public virtual Category Category
        
{
           
get return this._category; }
           
set this._category = value; }
        }

     }

Category中包含类Item,是一对多的关系。

映射文件:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  
<class name="NHibernate.Examples.OneToMany.Category, NHibernate.Examples.OneToMany" table="nh_categories">
    
<id name="CategoryID" column="CategoryID" type="Guid" 
      unsaved-value
="00000000-0000-0000-0000-000000000000">
      
<generator class="guid" />
    
</id>
    
<property name="Name" type="string" length="50" />
    
<bag name="Items" lazy="true" inverse="true" cascade= "all-delete-orphan">
    
<key column="CategoryID" />
    
<one-to-many class="NHibernate.Examples.OneToMany.Item, NHibernate.Examples.OneToMany" />
    
</bag>
  
</class>
  
<class name="NHibernate.Examples.OneToMany.Item, NHibernate.Examples.OneToMany" table="nh_items">
    
<id name="ItemID" column="ItemID" type="Guid" 
      unsaved-value
="00000000-0000-0000-0000-000000000000">
      
<generator class="guid" />
    
</id>
    
<property name="Name" type="string" length="50" />
    
<many-to-one name="Category" class="NHibernate.Examples.OneToMany.Category, NHibernate.Examples.OneToMany" 
    column
="CategoryID" />
  
</class>
</hibernate-mapping>


其中在Category中指定了一对多的关系:

    <bag name="Items" lazy="true" inverse="true" cascade= "all-delete-orphan">
    
<key column="CategoryID" />
    
<one-to-many class="NHibernate.Examples.OneToMany.Item, NHibernate.Examples.OneToMany" />
</bag>


且指定了级联关系。
在类Item中指定了多对一的关系:

<many-to-one name="Category" class="NHibernate.Examples.OneToMany.Category, NHibernate.Examples.OneToMany" column="CategoryID" />


测试方法1(插入):

Code
       [Test]
        
public void TestCascadingSave()
        
{
            
// prepare test objects
            Category expectedCategory = new Category();
            expectedCategory.Name 
= "category" + System.Environment.TickCount.ToString();
            
for (int i = 0; i < 10; i++)
            
{
                Item item 
= new Item();
                item.Name 
= "item" + System.Environment.TickCount.ToString();
                item.Category 
= expectedCategory;

                expectedCategory.Items.Add(item);
            }

            
// save objects in a all-cascading way
            
// note: cascading option should at least set as "all" in objects.hbm.xml
            transaction = session.BeginTransaction();
            
try
            
{
                session.SaveOrUpdate(expectedCategory);
                transaction.Commit();
            }

            
catch
            
{
                transaction.Rollback();
                
throw;
            }

            
// that works?
            Category actualCategory =
                session.Get(
typeof(Category), expectedCategory.CategoryID) as Category;
            Assert.IsNotNull(actualCategory);
            Assert.AreEqual(expectedCategory.Items.Count, actualCategory.Items.Count);
        }


测试方法2(级联删除):

Code
        [Test]
        
public void TestCascadingDelete()
        
{
            Category expectedCategory 
= 
              session.CreateCriteria(
typeof(Category)).List()[0as Category;
            
// remove category from the repository
            transaction = session.BeginTransaction();
            
try
            
{
                session.Delete(expectedCategory);
                transaction.Commit();
            }

            
catch
            
{
                transaction.Rollback();
                
throw;
            }

            
// that works?
            Assert.AreEqual(0, session.CreateCriteria(typeof(Category)).List().Count);
            Assert.AreEqual(
0, session.CreateCriteria(typeof(Item)).List().Count);
        }


转载于:https://www.cnblogs.com/nerozhang/archive/2008/02/15/1069129.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值