0

0

ORM利器:NHibernate(三)五部曲+简单对象CRUD+HQL

php中文网

php中文网

发布时间:2016-06-07 15:59:17

|

1087人浏览过

|

来源于php中文网

原创

前面的两篇文章中,我们对nhibernate已经做了大致了解 《ORM利器:NHibernate(一)简介》Nhibernate的作用:解决了对象和数据库的转化问题 《ORM利器:NHibernate(二)使用CodeSmith快速生成映射文件和映射类 》利用CodeSmith由表导出映射类(就是通常所说

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

《ORM利器:NHibernate(一)简介》Nhibernate的作用:解决了对象和数据库的转化问题

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

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

  1. 创建表。若要把对象转换为数据库中的表,自然要有对一个的表。因此,首先要在数据库中创建把.Net类持久化的对应表。创建类。创建需要被持久化的.Net类.对象。创建映射文件。 描述对象和库之间的关系,告诉NH怎样持久化这些类的属性.创建NH的配置文件,以告诉NH怎样连接数据库,以何种方式连接不同种类的数据库。使用NH提供的API。维护对象和库之间的关系,对对象的CRUD和对数据库的DML.
    步骤详情: 第一部:创建表(步骤很简单,这里不做解释)
    第二部:创建类+第三部:创建映射文件(本Demo利用CodeSmith自动生成,详细请参见《ORM利器:NHibernate(二)使用CodeSmith快速生成映射文件和映射类 》)
    第四部:创建NH配置文件 主要用于连接数据库:驱动的提供者、驱动的位置、数据库的身份验证信息等,和我们曾经写过的数据库连接语句无意,只不过放在了配置文件中而已。而且NH采用代理工厂,针对不同的数据库产品进行生产,提供了更好的灵活性,如果你需要把SQLServer数据库,更改为Oracle数据库,只需要更改相应的配置信息就可以。
    
    
      
        
    NHibernate.Connection.ConnectionProvider,NHibernate NHibernate.Driver.SqlClientDriver Server=(local);initial catalog=NHibernate;Integrated Security=SSPI NHibernate.Dialect.MsSql2008Dialect False NHibernate.ByteCode.Linfu.ProcxyFactoryFactory,NHibernate.ByteCode.Linfu
    如果你觉得配置文件很复杂、记不住,也没有关系。NH为我们提供了很多配置文件的模板以供参考,这里我们采用SQLServer,因此可以参照:Configuration_Templates—MSSQL.cfg.xml

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

    1、目录结构如下:

    1)新建类库Test: 用于存放所有的对象和.NET映射文件(如此处的Person.cs对象,Person.hbm.xml映射文件),为了让NHibernate能够找到所有的映射文件,必须设置为“嵌入资源”,生成Test.dll文件备用。 2)添加引用:
    外部引用NHibernate和NHibernate.ByteCode.Linfu.项目引用Test.dll

     

    \

    2、添加窗体Form1,如图所示:

    \

    HaiSnap
    HaiSnap

    一站式AI应用开发和部署工具

    下载

    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,不同的是只能用于对数据进行查询操作,不能用于数据增、删、改。它是完全面向对象的,具备继承、多态和关联等特性。 

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using NHibernate;
    using NHibernate.Cfg;
    using Test.Model;
    using System.Linq;
    
    namespace WinFormTest
    {
        public partial class Form1 : Form
        {
            //创建session
            ISession session = null;
            //创建session工厂
            ISessionFactory factory = null;
            //创建事务
            ITransaction trans = null;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
    
                //读取配置文件
                //读取所有映射文件,加载程序集,必须是嵌入资源
                Configuration config = new Configuration().AddAssembly("Test.Model");
                //创建session工厂,负责持久化的连接以及OR映射,该对象的开销比较大,一般建议用单例模式实现
                factory = config.BuildSessionFactory();
                //创建一个可以用于用户级别的操作对象
                session = factory.OpenSession();
    
            }
    
            //添加用户
            private void btnAdd_Click(object sender, EventArgs e)
            {
                //开启事务对象
                trans = session.BeginTransaction();
                //使用NHibernate现有API
                //体验过程
                try
                {
                    //对象的实例化方式
                    Person p = new Person();
                    p.Name = this.txtName.Text;
                    //把对象保存在数据库中
                    //将对象必须转化为数据库能识别的sql语句
                    //由于在SessionFactory中已经保存了所有的OR映射
                    //ISession能根据相应的方言实现sql语句
                    session.Save(p);
                    trans.Commit();
                }
                catch (Exception)
                {
                    //出错后,事务回滚
                    trans.Rollback();
                }
            }
    
            //查询用户
            private void btnFind_Click(object sender, EventArgs e)
            {
                //trans = session.BeginTransaction();
                //查找ID编号为2的人
                //2-->ID属性——OR——>SQL的Where语句
                Person p = (Person)session.Get(typeof(Person), int.Parse(this.txtID.Text));
                //Console.WriteLine(p.ToString());
                this.txtName.Text = p.Name;
            }
    
            //删除用户
            private void btnDelete_Click(object sender, EventArgs e)
            {
                try
                {
                    //开启事务
                    trans = session.BeginTransaction();
                    //根据提供的ID查找该对象
                    Person p = (Person)session.Get(typeof(Person), int.Parse(this.txtID.Text));
                    //对象删除
                    session.Delete(p);
                    trans.Commit();
                }
                catch (Exception)
                {
                    trans.Rollback();
                }
            }
    
            //更新用户
            private void btnUp_Click(object sender, EventArgs e)
            {
                try
                {
                    //开启事务
                    trans = session.BeginTransaction();
                    //根据提供的ID查找该对象
                    Person p = (Person)session.Get(typeof(Person), int.Parse(this.txtID.Text));
                    //修改对象属性
                    p.Name = this.txtName.Text;
                    session.Update(p);
                    trans.Commit();
                }
                catch (Exception)
                {
                    trans.Rollback();
                }
            }
    
            //IQuery接口,是针对对象查询
            private void btnHQL_Click(object sender, EventArgs e)
            {
                //HQL体验——HQL是针对对象的查询语言
                //查询所有人的信息
                //IQuery query = session.CreateQuery("from Person");
                //IList persons = query.List();
                //persons.p1();
    
                //查询编号为2的人的信息
                //IQuery query = session.CreateQuery("from Person where Id=3");
                //query.List().p1();
    
                //查询名字中有字母a的人
                //session.CreateQuery("from Person where Name like '%a%'").List().p1();
                //session.CreateQuery("from Person where t_Name like '%a%'").List().p1();
                //session.CreateQuery("from Person where name like '%a%'").List().p1();//错误
    
                //查找全部
                //session.CreateQuery("select p from Person p").List().p1();
                //session.CreateQuery("select * from Person ").List().p1();//错误,没有*
    
                //查找编号大于5的人的信息
                //session.CreateQuery("from Person p where p.Id>5 ").List().p1();
    
    
    
                //聚合函数的使用--统计人数
                //session.CreateQuery("select count(p.Id) from Person p ").List().p2();
    
                //传参1
                //IQuery query = session.CreateQuery("from Person p where p.Id>?");
                //query.SetParameter(0,7);
                //query.List().p1();
                //传参2
                //IQuery query = session.CreateQuery("from Person p where p.Id>:id");
                //query.SetParameter("id", 7);
                //query.List().p1();
    
                //插入数据——Insert/Update/Delete不建议在HQL里面操作
                //IQuery query = session.CreateQuery("insert into t_Person(t_Name) values(?)");
                //query.SetParameter(0,"kkk");
                //query.ExecuteUpdate();
    
                //查询指定范围的数据——查询第3-7条记录
                IQuery query = session.CreateQuery("from Person");
                query.List().Skip(3).Take(5).ToList(); ;
                //用ICriteria来实现该功能可能更方便
            }
    
            //对IList类型数据的输出,建议用C#3.0的拓展方法来实现
            public static class ExtraClass
            {
                public static void p1(this IList p)
                {
                    //获取可枚举的接口对象
                    IEnumerator ie = p.GetEnumerator();
                    Console.WriteLine("\n-----------------------\n");
                    //遍历
                    while (ie.MoveNext())
                    {
                        Console.WriteLine(ie.Current.ToString());
                    }
                    Console.WriteLine("\n-----------------------\n");
                }
                public static void p2(this IList p)
                {
                    IEnumerator ie = p.GetEnumerator();
                    Console.WriteLine("\n-----------------------\n");
                    while (ie.MoveNext())
                    {
                        Console.WriteLine(ie.Current.ToString());
                    }
                    Console.WriteLine("\n-----------------------\n");
                }
            }
        }
    }
    

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

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

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

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

c++ 字符串格式化
c++ 字符串格式化

本专题整合了c++字符串格式化用法、输出技巧、实践等等内容,阅读专题下面的文章了解更多详细内容。

9

2026.01.30

java 字符串格式化
java 字符串格式化

本专题整合了java如何进行字符串格式化相关教程、使用解析、方法详解等等内容。阅读专题下面的文章了解更多详细教程。

12

2026.01.30

python 字符串格式化
python 字符串格式化

本专题整合了python字符串格式化教程、实践、方法、进阶等等相关内容,阅读专题下面的文章了解更多详细操作。

4

2026.01.30

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

20

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

18

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

19

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

3

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
ThinkPHP6.x API接口--十天技能课堂
ThinkPHP6.x API接口--十天技能课堂

共14课时 | 1.1万人学习

极客学院ASP.NET视频教程
极客学院ASP.NET视频教程

共90课时 | 20.7万人学习

ThinkPHP开发大型商城项目实战视频
ThinkPHP开发大型商城项目实战视频

共54课时 | 21.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号