本文约定:
1.NHibernate简写为NH;
2.本文例子的开发平台为:WinXP + sp2 ,SqlServer 2005,NHibernate 1.0.0.0;
3.本文只是本人学习NHibernate时随手写的学习笔记,不保证程序的准确性,使用本程序造成的任何损失与本人无关;
4.转载请注明出处。
本文的内容:
1.简单介绍NH;
2.使用NH实现单表单对象的CRUD操作。
经验教训:
1.实体类的映射文件的Build Action属性务必设为Embedded Resource,若则会出错;
2.使用NH操作数据表时,数据表表名和字段名不能为SqlServer 2005的关键字,若则会提示:could not User...
一、NH简介
NH是基于ms.net的O/R Mapping持久框架,它从基于Java的Hibernate项目移植而来。O/R Mapping就是把对象到映射关系数据库的记录,简单的说就是能实现把一个对象存储为数据表中的一条记录和由一条记录创建一个相应的对象,数据表中的数据就是对象的属性。
那么为什么要使用O/R Mapping?它与传统的DataSet/DataTable又有什么不同了?
首先是设计上的不同,当使用O/R Mapping时,更多的是从对象的角度来设计程序,而把数据(对象的属性)存储的细节放在后面, 可以完全采用面向对象(OO)的方式来设计,而在使用DataSet/DataTable时,它只是存放数据的对象,看起来更像一个数据表,不能直观的表达业务概念。
二、NH中主要接口的介绍
ISession:是面向用户的主要接口,主要用于对象持久化,数据加载等操作,支持数据库事务,它隐藏了NHB内部复杂的实现细节,ISession由ISessionFactory创建。
ISessionFactory:是NHB内部的核心类,它维护到持久机制(数据库)的连接并对它们进行管理,同时还会保存所有持久对象的映射信息。
ISessionFactory由Configuration创建,因为创建ISessionFactory的开销非常大(需要加载映射信息),所以这个对象一般使用Singleton(单例)模式。
ITransaction:是NH的事务处理接口,它只是简单的封装了底层的数据库事务。事务必须由ISession来启动。
ICriteria:是Expression(表达式)数据加载接口,Expression是一个关系表达式组合,通过它能产生SQL语句的Where部分, 用户需要通过ISession来间接调用它。
IQuery:是HQL数据加载接口,HQL(Hibernate Query Language)是NHB专用的面向对象的数据查询语言,它与数据库的SQL有些类似,但功能更强大!同ICriteria一样,也需要通过ISession来间接调用它。
三、介绍封装的几个类:BizObject、ObjectBroker、Sessions。
Sessions类:封装了NH中的ISession和ISessionFactory两个接口,Sessions类的属性和方法都是静态的,它有一个Factory属性, 用于返回ISessionFactory, 有一个GetSession方法,用于取得一个新的ISession。Sessions类的代码如下:
using NHibernate;
using System.Reflection;
namespace NHibernateTest
{
///
/// Sessions 的摘要说明。
///
public class Sessions
{
private static readonly object lockObj = new object();
private static ISessionFactory _factory;
public Sessions()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public static ISessionFactory Factory
{
get
{
if (_factory == null)
{
lock (lockObj)
{
if (_factory == null)
{
NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
cfg.AddAssembly(Assembly.GetExecutingAssembly());
_factory = cfg.BuildSessionFactory();
}
}
}
return _factory;
}
}
public static ISession GetSession()
{
return Factory.OpenSession();
}
}
}
ObjectBroker类:ObjectBroker对ISession进行了必要的封装,通过ISession,就可以简单的完成对象的CRUD操作了。ObjectBroker类的代码如下:
using NHibernate;
namespace NHibernateTest
{
///
/// ObjectBroker 的摘要说明。
///
public class ObjectBroker
{
private ObjectBroker() { }
public static void Load(object obj, object id)
{
ISession s = Sessions.GetSession();
try
{
s.Load(obj, id);
}
finally
{
s.Close();
}
}
public static void Create(object obj)
{
ISession s = Sessions.GetSession();
ITransaction trans = null;
try
{
trans = s.BeginTransaction();
s.Save(obj);
trans.Commit();
}
finally
{
s.Close();
}
}
public static void Update(object obj)
{
ISession s = Sessions.GetSession();
ITransaction trans = null;
try
{
trans = s.BeginTransaction();
s.Update(obj);
trans.Commit();
}
finally
{
s.Close();
}
}
public static void Delete(object obj)
{
ISession s = Sessions.GetSession();
ITransaction trans = null;
try
{
trans = s.BeginTransaction();
s.Delete(obj);
trans.Commit();
}
finally
{
s.Close();
}
}
}
}
BizObject:业务实体类的基类,实现CRUD操作。BizObject类的代码如下:
namespace NHibernateTest
{
///
/// BizObject 的摘要说明。
///
public class BizObject
{
public BizObject() { }
public BizObject(object existingId)
{
ObjectBroker.Load(this, existingId);
}
public virtual void Create()
{
ObjectBroker.Create(this);
}
public virtual void Update()
{
ObjectBroker.Update(this);
}
public virtual void Delete()
{
ObjectBroker.Delete(this);
}
}
}
四、编写程序配置文件App.config/Web.config
< configuration >
< configSections >
< section name ="nhibernate" type ="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</ configSections >
< nhibernate >
<!-- 指定在log中是否显示sql语句, 用于调试 -->
< add key ="hibernate.show_sql" value ="true" />
<!-- 数据库连接提供 -->
< add key ="hibernate.connection.provider" value ="NHibernate.Connection.DriverConnectionProvider" />
<!-- 指定数据库方言, NHB可以针对数据库方言进行优化 -->
< add key ="hibernate.dialect" value ="NHibernate.Dialect.MsSql2000Dialect" />
<!-- 数据驱动对象 -->
< add key ="hibernate.connection.driver_class" value ="NHibernate.Driver.SqlClientDriver" />
<!-- 连接字符串, userid和password改成你自己的哦。 -->
< add key ="hibernate.connection.connection_string" value ="Password=admin;Persist Security Info=True;User ID=NIIT03;Initial Catalog=nmis_dev;Data Source=210.34.132.18" />
</ nhibernate >
</ configuration >
五、编写业务实体类User。 代码如下:
using System.Collections.Generic;
using System.Text;
namespace NHibernateTest
{
public class User : BizObject
{
fields
constructors
properties
}
}
六、编写实体类User对应的映射文件User.hbm.xml。 注意:实体类的映射文件以.hbm.xml做为后辍,确记得把映射文件的Build Action属性设为:Embedded Resource,若则会出错,确记确记!
< hibernate-mapping xmlns ="urn:nhibernate-mapping-2.0" >
< class name ="NHibernateTest.User,NHibernateTest" table ="Users" >
< id name ="UserID" column ="ID" type ="Int32" unsaved-value ="0" >
< generator class ="identity" />
</ id >
< property name ="UserName" column ="UserName" type ="String" length ="20" />
< property name ="Password" column ="Password" type ="String" length ="20" />
</ class >
</ hibernate-mapping >
七、调式代码,执行CRUD操作 ,代码如下:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace NHibernateTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
User objUser;
//添加新用户:添加新用户后才能更新和删除用户!!
private void btnAdd_Click(object sender, EventArgs e)
{
try
{
objUser = new User();
objUser.UserName = "test";
objUser.Password = "123";
objUser.Create();
MessageBox.Show("Success");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnUpdate_Click(object sender, EventArgs e)
{
try
{
objUser.UserName = "Update Name";
objUser.Password = "321";
objUser.Update();
MessageBox.Show("Success");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnDelete_Click(object sender, EventArgs e)
{
try
{
objUser.Delete();
MessageBox.Show("Success");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button1_Click(object sender, EventArgs e)
{
objUser = new User(1);
MessageBox.Show("UserID:" + objUser.UserID.ToString() + "\r\n" + "UserName:" +objUser.UserName + "\r\n" + "Password" +objUser.Password);
}
}
}
八、本文使用到的数据库脚本 :
(
[ ID ] int identity ( 1 , 1 ) constraint PK_UserID1 Primary Key ,
[ UserName ] varchar ( 20 ) not null ,
[ Password ] varchar ( 20 ) not null
)
通过以上这些代码,算是用NH实现了"Hello World"了,更多关于NH的操作还有待进一步的学习。