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的名称。
还有在生成操作中一定要选:嵌入的资源。
1)class: name属性指示了Post实体类的类名和所在的Assebmly的名称,NH将通过反射的方式找到所指示的实体类,关于.Net的反射的说明,请参考MSDN; table属性指示了该实体所对应的数据表的表名
2)property: 指示实体属性和数据列的如何映射。name为实体的属性名称,实体的该属性可以为public/private/protected,甚至是 internal;column指示了该属性对应的数据列,若实体属性名称和数据列名称相同(忽视大小写),可以省略;type指示了实体属性的.Net 数据类型,可以省略,NH可以自动转换;length只是对string类型的属性适用,指示了字符串的最大长度。
3)id: 指示主键。NH支持自动生成主键、数据库生成主键和手工赋值三种方式,我们这里手工赋值的方式,设定generator的class="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()[0] as 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);
}