前言:
谈到NHibernate大伙并不陌生,搞Java的更是清楚,Hibernate是一个目前应用的最广泛的开放源代码的对象关系映射框架,它对Java的JDBC(类似于ADO.Net)进行了非常轻量级的对象封装。NHibernate 是一个基于.Net 的针对关系型数据库的对象持久化类库。Nhibernate 来源于非常优秀的基于Java的Hibernate 关系型持久化工具(ORM)。
SessionFactory(NHibernate.IsessionFactory):它是Session的工厂,是ConnectionProvider的客户。可以持有一个可选的(第二级)数据缓存,可以在进程级别或集群级别保存的可以在事物中重用的数据。
会话(NHibernate.ISession):单线程,生命期较短的对象,代表应用程序和持久化层之间的一次对话。封装了一个ADO.NET连接,也是Transaction的工厂。保存有必需的(第一级)持久化对象的缓存,用于遍历对象图,或者通过标识符查找对象。
持久化对象(Persistent)其集合(Collections):生命期较短的单线程的对象,包含了持久化状态和商业功能。这些可能是普通的对象,唯一特别的是现在从属于且仅从属于一个Session。一旦Session被关闭,它们都将从Session中取消联系,可以在任何程序层自由使用(比如,直接作为传送到表现层的DTO,数据传输对象)。
事务Transaction (NHibernate.ITransaction):(可选)单线程,生命期较短的对象,应用程序用其来表示一批工作的原子操作,它是底层的ADO.NET事务的抽象。一个Session在某些情况下可能跨越多个Transaction事务。
持久化类是暂时存在的,实例会被持久性保存于数据库中.如:virtual public string Name { get; set; }
NHibernate默认使用代理功能,要求持久化类不是sealed的,而且其公共方法、属性和事件声明为virtual。
属性不一定需要声明为public的。NHibernate可以对default、protected、internal或private的属性执行持久化.
映射(Mapping)
对象和关系数据库之间的映射是用一个XML文档(XML document)来定义的。
2、在项目中配置NHibernate:
(1)、打开本项目文件夹下有个"packages"文件夹-->NHibernate.3.3.3.4000-->ConfigurationTemplates-->MSSQL.cfg.xml。
(2)、复制MSSQL.cfg.xml到项目根目录下,改名为”hibernate.cfg.xml“,紧接着 右键属性:无,如果较新则复制。否则出现“failed: NHibernate.Cfg.HibernateConfigException : An exception occurred during configuration of persistence layer. ----> System.IO.FileNotFoundException : 未能找到文件“NHibernateSample\NHibernateSample.Data.Test\bin\Debug\hibernate.cfg.xml””异常。
如下图:
3、数据库中添加表:Users。
4、在项目中建立”Entities“文件夹,添加Users类。
logs_code_hide('753e65b7-2e06-48af-924c-a40e21886c5f',event)" src="/Upload/Images/2013082016/2B1B950FA3DF188F.gif" alt="" />public class Users { virtual public int ID { get; set; } [DisplayName("姓名")] virtual public string Name { get; set; } [DisplayName("密码")] virtual public string PassWord { get; set; } [DisplayName("身高")] virtual public string Height { get; set; } [DisplayName("工作")] virtual public string Descript { get; set; [DisplayName("创建时间")] virtual public DateTime CreateTime { get; set; } }Users类
5、添加”Users.hbm.xml“,右键属性:不复制,嵌入的资源。
6、XML出现智能提示,在代码中右键属性:架构添加:nhibernate-configuration.xsd和nhibernate-mapping.xsd,文件位置如下图:
7、Users.hbm.xml文档代码如下:
(1) <hibernate-mappingxmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateDemo" namespace="NHibernateDemo.Entities">
解释:定义了NHibernate的版本信息,assembly:加载的程序集名称。namespace:映射到体类的文件夹。
(2) <class name="Users" table="Users" lazy="false">,name定义了所要映射的类,table定义了要映射的数据库中的表,lazy定义了是否要延迟加载,如 果是默认值的话lazy=”true”,是延迟加载,这样的话需要在定义的类字段中加入Virtual,而lazy=”true”则不用延迟加载,立即执行。
(3)<id name="ID" column="ID"><generator class="native"/></id>
这段代码的作用是被映射的类必须定义对应数据库的表主键字段,属于int自增的。name标识实体属性的名字,column标识数据库主键的名字。
(4)<property name="Name"/>字段名称,如果实体类中的名称和数据库中的一致,不需要定义column。
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateDemo" namespace="NHibernateDemo.Entities"> <class name="Users" table="Users" > <id name="ID" column="ID"> <generator class="native"/> </id> <property name="Name"/> <property name="PassWord" /> <property name="Height"/> <property name="Descript"/> <property name="CreateTime"/> </class> </hibernate-mapping>Users.hbm.xml
8、hibernate.cfg.xml文档代码如下:
(1) hibernate.dialect 数据库方言类,NHibernate根据不同的方言来适应不同的数据库,到0.7版只提供了支持MsSql2000的方言。
(2) hibernate.connection.driver_class 数据库连接的驱动类
(3) hibernate.connection.connection_string 数据库的连接字符串,包括主机名,数据库名,用户名和密码,注意,很多实际项目中出于安全性,会将该连接字符串写入注册表中,那么该参数就只能在程序中动态赋值了。
(4)<mapping assembly="NHibernateDemo"/>映射的程序集
<?xml version="1.0" encoding="utf-8"?> <!-- This template was written to work with NHibernate.Test. Copy the template to your NHibernate.Test project folder and rename it in hibernate.cfg.xml and change it for your own use before compile tests in VisualStudio. --> <!-- This is the System.Data.dll provider for SQL Server --> <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" > <session-factory name="NHibernate.Test"> <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property> <property name="connection.connection_string"> Server=.\SQLEXPRESS;initial catalog=TXUsers;User ID=sa;Password=sasa;Integrated Security=SSPI </property> <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property> <mapping assembly="NHibernateDemo"/> </session-factory> </hibernate-configuration>hibernate.cfg.xml
创建NHibernateHelp类:
(1)、我们要从ISessionFactory中获取一个ISession(NHibernate的工作单元)。
(2)、ISessionFactory可以创建并打开新的Session。
(3)、一个Session代表一个单线程的单元操作。 ISessionFactory是线程安全的,很多线程可以同时访问它。
(4)、ISession不是线程安全的,它代表与数据库之间的一次操作。ISession通过ISessionFactory打开,在所有的工作完成后,需要关闭。
(5)、ISessionFactory通常是个线程安全的全局对象,只需要被实例化一次。我们可以使用单例(Singleton)模式在程序中创建ISessionFactory。
public class NHibernateHelper { private ISessionFactory _sessionFactory; public NHibernateHelper() { _sessionFactory = GetSessionFactory(); } private ISessionFactory GetSessionFactory() { return (new Configuration()).Configure().BuildSessionFactory(); } public ISession GetSession() { return _sessionFactory.OpenSession(); } }NHibernateHelper类
(6)、有了返回的ISession类型的GetSession()方法,就可以实现增删改查的功能了。
NHibernate的查询:
分为以下几种:(我在项目中用的第三种方式(Linq))
return _session.CreateQuery("from Customer c where c.Firstname=:fn") .SetString("fn", firstname) .List<Customer>();HQL写法
2、条件查询(Criteria Query):在NHibernate中,提供了一种直观的、可扩展的Criteria API。在我们键入查询语句的时候,提供了编译时的语法检查,VS提供了强大的智能提示。如果你对HQL的语法感觉不是很舒服的话,用这种方法可能更容易。这种API也比HQL更可扩展。
public IList<Customer> Order() { return _session.CreateCriteria(typeof(Customer)) .Add(Restrictions.Like("Firstname","T%")) .AddOrder(new NHibernate.Criterion.Order("Firstname", false)) .AddOrder(new NHibernate.Criterion.Order("Lastname", true)) .List<Customer>(); }Criteria Query写法
3、Linq支持:首先得引入 using NHibernate.Linq;和之前你用的Linq是一模一样的。在NHibernate 3.0.0版本中,Query方式新增了Linq支持和强类型查询API(QueryOver)两种查询方式。
public List<Entities.Users> List() { var List = Session.Query<Users>().ToList(); return List; }Linq写法
根据前面的总结,很容易的可以在项目中使用NHibernate了(其中使用了事务)。
//增加 public void Add(Entities.Users Userss) { ITransaction tansction = Session.BeginTransaction(); try { Session.Save(Userss); tansction.Commit(); } catch (Exception) { tansction.Rollback(); } }增加
//删除 public void Delete(Entities.Users Userss) { var session = Session; using (session.BeginTransaction()) { session.Delete(Userss); session.Transaction.Commit(); } }删除
//编辑 public void Edit(Entities.Users Userss) { var session = Session; using (session.BeginTransaction()) { try { session.Update(Userss); session.Transaction.Commit(); } catch (Exception ex) { session.Transaction.Rollback(); throw new Exception(ex.Message, ex); } } }编辑
//根据ID获取单个实体 public Users GetUserByID(int ID) { var session = Session; return session .Query<Users>() .Where(p => p.ID == ID).FirstOrDefault(); }根据ID获取单个实体
总结:
NHibernate不止这么简单,还有以下内容(本人研究的也不是很深,大家可以加入QQ群:331273083,进行MVC、EF、NHibernate的交流与学习,互相进步嘛):
1、SchemaExport的工具(根据实体类生成数据库)。
2、NHibernate中使用存储过程。
3、NHibernate一级缓存、NHibernate二级缓存。
源码下载:点击下载,或者QQ群:331273083 共享里下载!(关于博主的其他示例代码,也都在共享里。)