前面的两篇文章中。我们对NHibernate已经做了大致了解

ORM利器:NHibernate(一)简单介绍》Nhibernate的作用:攻克了对象和数据库的转化问题

ORM利器:NHibernate(二)使用CodeSmith高速生成映射文件和映射类》利用CodeSmith由表导出映射类(就是通常所说的Entity)和映射文件(告诉你表和对象之间是怎样建立一一相应的关系的)。

接下来将会对NHibernate的使用做Demo解析,分为五部曲:

  1. 创建表。若要把对象转换为数据库中的表。自然要有对一个的表。

    因此。首先要在数据库中创建把.Net类持久化的相应表。

  2. 创建类。创建须要被持久化的.Net类.对象。
  3. 创建映射文件。 描写叙述对象和库之间的关系,告诉NH如何持久化这些类的属性.
  4. 创建NH的配置文件,以告诉NH如何连接数据库,以何种方式连接不同种类的数据库。
  5. 使用NH提供的API。维护对象和库之间的关系,对对象的CRUD和对数据库的DML.


步骤详情:
第一部:创建表(步骤非常easy,这里不做解释)

第二部:创建类+第三部:创建映射文件(本Demo利用CodeSmith自己主动生成,具体请參见《ORM利器:NHibernate(二)使用CodeSmith高速生成映射文件和映射类》)


第四部:创建NH配置文件  
      主要用于连接数据库:驱动的提供者、驱动的位置、数据库的身份验证信息等,和我们以前写过的数据库连接语句无意,仅仅只是放在了配置文件里而已。并且NH採用代理工厂,针对不同的数据库产品进行生产。提供了更好的灵活性。假设你须要把SQLServer数据库。更改为Oracle数据库,仅仅须要更改对应的配置信息就能够。
  1. <?
  2.  
  3. xml version="1.0" encoding="utf-8" ?>
  4. <configuration>
  5. <configSession>
  6. <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler,NHibernate" requireParmission="false"/>
  7. </configSession>
  8. <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
  9. <!--Session工厂,用户级别的对象-->
  10. <session-factory name="NHibernate.Test">
  11. <!--驱动是由谁提供的-->
  12. <property name="connection.provider">NHibernate.Connection.ConnectionProvider,NHibernate</property>
  13. <!--驱动类的位置-->
  14. <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
  15. <!--身份验证登陆-->
  16. <property name="connection.connection_string">Server=(local);initial catalog=NHibernate;Integrated Security=SSPI</property>
  17. <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
  18. <!--是否显示sql语句-->
  19. <property name="show_sql">False</property>
  20. <!--代理工厂,针对不同的数据库产品进行生产-->
  21. <property name="proxyfactory.factory_class">NHibernate.ByteCode.Linfu.ProcxyFactoryFactory,NHibernate.ByteCode.Linfu</property>
  22. </session-factory>
  23. </hibernate-configuration>
  24. </configuration>

假设你认为配置文件非常复杂、记不住,也没有关系。NH为我们提供了非常多配置文件的模板以供參考。这里我们採用SQLServer,因此能够參照:Configuration_Templates—MSSQL.cfg.xml


第五部:使用NH提供的API。维护对象和库之间的关系,对对象的CRUD和对数据库的DML

1、文件夹结构例如以下:

1)新建类库Test:

用于存放全部的对象和.NET映射文件(如此处的Person.cs对象,Person.hbm.xml映射文件),为了让NHibernate可以找到全部的映射文件。必须设置为“嵌入资源”,生成Test.dll文件备用。

2)加入引用:

    1. 外部引用NHibernate和NHibernate.ByteCode.Linfu.
    2. 项目引用Test.dll

2、加入窗口Form1。如图所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhb2xpamluZzIwMTI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

3、窗口Form1中的代码例如以下所看到的:

首先,通过config读取配置文件。读取全部映射文件,载入程序集(必须是嵌入资源)

    其次。通过SessionFactory创建session工厂,负责持久化的连接以及OR映射(该对象的开销比較大。一般建议用单例模式实现)

    然后,通过session创建一个能够用于用户级别的操作对象。

开启事务对象trans = session.BeginTransaction();

上面的思路和我们以前使用过的SQLServer是一个道理。

接下来看一下不同点:

曾经D层和数据库打交道的时候,我们通常使用sql语句,而后直接对数据库进行操作。而在NH中全部的操作(增删改查)全都是针对“对象”而言的,假设想要把对象保存在数据库中,就须要先将对象必须转化为数据库能识别的sql语句,因为在SessionFactory中已经保存了全部的OR映射,ISession能依据对应的方言实现sql语句。

下文的代码中已经实现了简单操作对象。主要是通过session的get、save、delete方法来实现。若要实现复杂的查询不免会比較繁琐。NHibernate提供了一种强大的查询语言HQL(Hibernate
Query Language)。它的语法很类似于Sql。不同的是仅仅能用于对数据进行查询操作,不能用于数据增、删、改。它是全然面向对象的,具备继承、多态和关联等特性。

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Windows.Forms;
  5. using NHibernate;
  6. using NHibernate.Cfg;
  7. using Test.Model;
  8. using System.Linq;
  9.  
  10. namespace WinFormTest
  11. {
  12. public partial class Form1 : Form
  13. {
  14. //创建session
  15. ISession session = null;
  16. //创建session工厂
  17. ISessionFactory factory = null;
  18. //创建事务
  19. ITransaction trans = null;
  20.  
  21. public Form1()
  22. {
  23. InitializeComponent();
  24. }
  25.  
  26. private void Form1_Load(object sender, EventArgs e)
  27. {
  28.  
  29. //读取配置文件
  30. //读取全部映射文件,载入程序集,必须是嵌入资源
  31. Configuration config = new Configuration().AddAssembly("Test.Model");
  32. //创建session工厂,负责持久化的连接以及OR映射,该对象的开销比較大,一般建议用单例模式实现
  33. factory = config.BuildSessionFactory();
  34. //创建一个能够用于用户级别的操作对象
  35. session = factory.OpenSession();
  36.  
  37. }
  38.  
  39. //加入用户
  40. private void btnAdd_Click(object sender, EventArgs e)
  41. {
  42. //开启事务对象
  43. trans = session.BeginTransaction();
  44. //使用NHibernate现有API
  45. //体验过程
  46. try
  47. {
  48. //对象的实例化方式
  49. Person p = new Person();
  50. p.Name = this.txtName.Text;
  51. //把对象保存在数据库中
  52. //将对象必须转化为数据库能识别的sql语句
  53. //因为在SessionFactory中已经保存了全部的OR映射
  54. //ISession能依据对应的方言实现sql语句
  55. session.Save(p);
  56. trans.Commit();
  57. }
  58. catch (Exception)
  59. {
  60. //出错后,事务回滚
  61. trans.Rollback();
  62. }
  63. }
  64.  
  65. //查询用户
  66. private void btnFind_Click(object sender, EventArgs e)
  67. {
  68. //trans = session.BeginTransaction();
  69. //查找ID编号为2的人
  70. //2-->ID属性——OR——>SQL的Where语句
  71. Person p = (Person)session.Get(typeof(Person), int.Parse(this.txtID.Text));
  72. //Console.WriteLine(p.ToString());
  73. this.txtName.Text = p.Name;
  74. }
  75.  
  76. //删除用户
  77. private void btnDelete_Click(object sender, EventArgs e)
  78. {
  79. try
  80. {
  81. //开启事务
  82. trans = session.BeginTransaction();
  83. //依据提供的ID查找该对象
  84. Person p = (Person)session.Get(typeof(Person), int.Parse(this.txtID.Text));
  85. //对象删除
  86. session.Delete(p);
  87. trans.Commit();
  88. }
  89. catch (Exception)
  90. {
  91. trans.Rollback();
  92. }
  93. }
  94.  
  95. //更新用户
  96. private void btnUp_Click(object sender, EventArgs e)
  97. {
  98. try
  99. {
  100. //开启事务
  101. trans = session.BeginTransaction();
  102. //依据提供的ID查找该对象
  103. Person p = (Person)session.Get(typeof(Person), int.Parse(this.txtID.Text));
  104. //改动对象属性
  105. p.Name = this.txtName.Text;
  106. session.Update(p);
  107. trans.Commit();
  108. }
  109. catch (Exception)
  110. {
  111. trans.Rollback();
  112. }
  113. }
  114.  
  115. //IQuery接口。是针对对象查询
  116. private void btnHQL_Click(object sender, EventArgs e)
  117. {
  118. //HQL体验——HQL是针对对象的查询语言
  119. //查询全部人的信息
  120. //IQuery query = session.CreateQuery("from Person");
  121. //IList<Person> persons = query.List<Person>();
  122. //persons.p1();
  123.  
  124. //查询编号为2的人的信息
  125. //IQuery query = session.CreateQuery("from Person where Id=3");
  126. //query.List<Person>().p1();
  127.  
  128. //查询名字中有字母a的人
  129. //session.CreateQuery("from Person where Name like '%a%'").List<Person>().p1();
  130. //session.CreateQuery("from Person where t_Name like '%a%'").List<Person>().p1();
  131. //session.CreateQuery("from Person where name like '%a%'").List<Person>().p1();//错误
  132.  
  133. //查找全部
  134. //session.CreateQuery("select p from Person p").List<Person>().p1();
  135. //session.CreateQuery("select * from Person ").List<Person>().p1();//错误,没有*
  136.  
  137. //查找编号大于5的人的信息
  138. //session.CreateQuery("from Person p where p.Id>5 ").List<Person>().p1();
  139.  
  140. //聚合函数的使用--统计人数
  141. //session.CreateQuery("select count(p.Id) from Person p ").List().p2();
  142.  
  143. //传參1
  144. //IQuery query = session.CreateQuery("from Person p where p.Id>?");
  145. //query.SetParameter(0,7);
  146. //query.List<Person>().p1();
  147. //传參2
  148. //IQuery query = session.CreateQuery("from Person p where p.Id>:id");
  149. //query.SetParameter("id", 7);
  150. //query.List<Person>().p1();
  151.  
  152. //插入数据——Insert/Update/Delete不建议在HQL里面操作
  153. //IQuery query = session.CreateQuery("insert into t_Person(t_Name) values(?
  154.  
  155. )");
  156. //query.SetParameter(0,"kkk");
  157. //query.ExecuteUpdate();
  158.  
  159. //查询指定范围的数据——查询第3-7条记录
  160. IQuery query = session.CreateQuery("from Person");
  161. query.List<Person>().Skip<Person>(3).Take<Person>(5).ToList<Person>(); ;
  162. //用ICriteria来实现该功能可能更方便
  163. }
  164.  
  165. //对IList<Person>类型数据的输出。建议用C#3.0的拓展方法来实现
  166. public static class ExtraClass
  167. {
  168. public static void p1(this IList<Person> p)
  169. {
  170. //获取可枚举的接口对象
  171. IEnumerator<Person> ie = p.GetEnumerator();
  172. Console.WriteLine("\n-----------------------\n");
  173. //遍历
  174. while (ie.MoveNext())
  175. {
  176. Console.WriteLine(ie.Current.ToString());
  177. }
  178. Console.WriteLine("\n-----------------------\n");
  179. }
  180. public static void p2(this IList p)
  181. {
  182. IEnumerator ie = p.GetEnumerator();
  183. Console.WriteLine("\n-----------------------\n");
  184. while (ie.MoveNext())
  185. {
  186. Console.WriteLine(ie.Current.ToString());
  187. }
  188. Console.WriteLine("\n-----------------------\n");
  189. }
  190. }
  191. }
  192. }

总结:对于NHibernate的操作。本文通过五部曲进行仔细的解说:1、创建表;2、创建类;3、创建映射文件(表和类是怎样相应的)。4、NH配置文件(连接数据库)。5、利用API操作。

当中。2、3 我们採用CodeSmith自己主动生成映射类和映射文件;4就是我们曾做的连接数据库操作。5通过NHibernate提供的API。通过对对象操作。已达到操作数据库的目的。避免了冗长复杂的sql语句。

希望大家重点理解创建的过程,以及API的使用。

版权声明:本文博客原创文章。博客,未经同意,不得转载。

ORM武器:NHibernate(三)五个步骤+简单对象CRUD+HQL的更多相关文章

  1. C++ 三/五法则

    当定义一个类时,我们显式地或隐式地指定了此类型的对象在拷贝.赋值和销毁时做什么.一个类通过定义三种特殊的成员函数来控制这些操作:拷贝构造函数.拷贝赋值运算符和析构函数. 拷贝构造函数定义了当用同类型的 ...

  2. 【转载】ADO.NET与ORM的比较(3):Linq to SQL实现CRUD

    [转载]ADO.NET与ORM的比较(3):Linq to SQL实现CRUD 说明:个人感觉在Java领域大型开发都离不了ORM的身影,所谓的SSH就是Spring+Struts+Hibernate ...

  3. Nhibernate系列学习之(一) ORM and Nhibernate入门实例解析

    最近框架项目需要,数据层想使用Nhibernate,代替传统的sql语句的写法,更加使用面向对象的思维来维护实体与数据库的这层关系映射(ORM),好在之前接触过Java时学习使用了Hibernate, ...

  4. 原生ajax请求的五个步骤

    //第一步,创建XMLHttpRequest对象 var xmlHttp = new XMLHttpRequest(); function CommentAll() { //第二步,注册回调函数 xm ...

  5. 使用Echarts的五个步骤

     _liuz 2015-07-22 09:35:53 参考网址:http://echarts.baidu.com/doc/start.html 一.制作一个图表容器<div id="m ...

  6. 用 C 语言编写 Windows 服务程序的五个步骤

    Windows 服务被设计用于需要在后台运行的应用程序以及实现没有用户交互的任务.为了学习这种控制台应用程序的基础知识,C(不是C++)是最佳选择.本文将建立并实现一个简单的服务程序,其功能是查询系统 ...

  7. .NET 常用ORM之NHibernate

    NHibernate做.Net应该都不陌生,今天我们就算是温故下这个技术,概念性的东西就不说了,这次主要说本人在实际使用的遇到的问题,比较费解现在就当是记录下,避免以后再犯.本次主要使用的情况是1对N ...

  8. 五个步骤教你理清Redis与Memcached的区别

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由Super发表于云+社区专栏 memcached和redis,作为近些年最常用的缓存服务器,相信大家对它们再熟悉不过了.前两年还在学校 ...

  9. RHCE学习笔记 管理1 (第三~五章)

    第三章 红帽企业linux 获取帮助 (略) man .pinfo. 第四章 编辑文件 1.输出重定向到文件和程序 >file    定向文件(覆盖) >>file   定向文件(附 ...

随机推荐

  1. EBS并发管理器请求汇总(按照并发消耗时间,等待时间,平均等待事件等汇总)

    此数据集用于确定正在使用中并发管理器,并可与实际的在启动时分配的并发管理器.而且考虑完成状态为 正常/警告 的请求. select q.concurrent_queue_name, count(*) ...

  2. android中用get和post方式向服务器提交请求

    通过get和post方式向服务器发送请求首先说一下get和post的区别get请求方式是将提交的参数拼接在url地址后面,例如http://www.baidu.com/index.jsp?num=23 ...

  3. c++ cin>>详解

    参考地址:http://www.cnblogs.com/A-Song/archive/2012/01/29/2331204.html 程序的输入都建有一个缓冲区,即输入缓冲区.一次输入过程是这样的,当 ...

  4. Oracle基础(五)pl/sql进阶(分页过程)

    编写分页过程         通过pl/sql实现分页过程,再该过程中由简单到难一步步深入,目的在于通过该案例熟悉pl/sql的各种存储过程,包,游标.怎样在java中调用等内容的学习. 1.无返回值 ...

  5. CentOS 6.5安全加固及性能优化

    (文章来自:http://www.cnblogs.com/seasonzone/p/3526296.html) 我们可以通过调整系统参数来提高系统内存.CPU.内核资源的占用,通过禁用不必要的服务.端 ...

  6. 隐马尔科夫模型(HMM)及事实上现

    马尔科夫模型 马尔科夫模型是单重随机过程,是一个2元组:(S,A). 当中S是状态集合,A是状态转移矩阵. 仅仅用状态转移来描写叙述随机过程. 马尔科夫模型的2个如果 有限历史性如果:t+l时刻系统状 ...

  7. bestcoder Round#52 1001(最短路+状压dp)

    求从1点出发,走遍所有的点,然后回到1点的最小代价. 每个点可以走若干遍. 如果每个点只能走一遍,那么设dp[i][s]为走完s状态个点(s是状态压缩),现在位于i的最小花费. 然后枚举从哪个点回到原 ...

  8. Class Diagram

  9. Java进阶 创建和销毁对象

    最近准备写点Javase的东西,希望可以帮助大家写出更好的代码. 1.给不可实例化的类提供私有构造器 比如:每个项目中都有很多工具类,提供了很多static类型的方法供大家使用,谁也不希望看到下面的代 ...

  10. 配置jndi服务,javax.naming.NamingException的四种情况

    1.当jndi服务没有启动,或者jndi服务的属性没有设置正确,抛出如下异常: javax.naming.CommunicationException: Can't find SerialContex ...