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

前面的两篇文章中,我们对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.

步骤详情:

第一部:创建表(步骤很简单,这里不做解释)

第二部:创建类+第三部:创建映射文件(本Demo利用CodeSmith自动生成,详细请参见《ORM利器:NHibernate(二)使用CodeSmith快速生成映射文件和映射类》)

第四部:创建NH配置文件

主要用于连接数据库:驱动的提供者、驱动的位置、数据库的身份验证信息等,和我们曾经写过的数据库连接语句无意,只不过放在了配置文件中而已。而且NH采用代理工厂,针对不同的数据库产品进行生产,提供了更好的灵活性,如果你需要把SQLServer数据库,更改为Oracle数据库,只需要更改相应的配置信息就可以。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSession>
    <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler,NHibernate" requireParmission="false"/>
  </configSession>
  <hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
    <!--Session工厂,用户级别的对象-->
    <session-factory name="NHibernate.Test">
      <!--驱动是由谁提供的-->
      <property name="connection.provider">NHibernate.Connection.ConnectionProvider,NHibernate</property>
      <!--驱动类的位置-->
      <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
      <!--身份验证登陆-->
      <property name="connection.connection_string">Server=(local);initial catalog=NHibernate;Integrated Security=SSPI</property>
      <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
      <!--是否显示sql语句-->
      <property name="show_sql">False</property>
      <!--代理工厂,针对不同的数据库产品进行生产-->
      <property name="proxyfactory.factory_class">NHibernate.ByteCode.Linfu.ProcxyFactoryFactory,NHibernate.ByteCode.Linfu</property>
    </session-factory>
  </hibernate-configuration>
</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,如图所示:

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<Person> persons = query.List<Person>();
            //persons.p1();

            //查询编号为2的人的信息
            //IQuery query = session.CreateQuery("from Person where Id=3");
            //query.List<Person>().p1();

            //查询名字中有字母a的人
            //session.CreateQuery("from Person where Name like '%a%'").List<Person>().p1();
            //session.CreateQuery("from Person where t_Name like '%a%'").List<Person>().p1();
            //session.CreateQuery("from Person where name like '%a%'").List<Person>().p1();//错误

            //查找全部
            //session.CreateQuery("select p from Person p").List<Person>().p1();
            //session.CreateQuery("select * from Person ").List<Person>().p1();//错误,没有*

            //查找编号大于5的人的信息
            //session.CreateQuery("from Person p where p.Id>5 ").List<Person>().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<Person>().p1();
            //传参2
            //IQuery query = session.CreateQuery("from Person p where p.Id>:id");
            //query.SetParameter("id", 7);
            //query.List<Person>().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<Person>().Skip<Person>(3).Take<Person>(5).ToList<Person>(); ;
            //用ICriteria来实现该功能可能更方便
        }

        //对IList<Person>类型数据的输出,建议用C#3.0的拓展方法来实现
        public static class ExtraClass
        {
            public static void p1(this IList<Person> p)
            {
                //获取可枚举的接口对象
                IEnumerator<Person> 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的使用。

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

时间: 2024-11-05 22:01:18

ORM利器:NHibernate(三)五部曲+简单对象CRUD+HQL的相关文章

我的NHibernate之行(一):NHibernate五部曲

NHibernate是一个面向.NET环境的对象/关系数据库映射工具.对象/关系数据库映射(object/relational mapping,ORM)这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去.--百度百科 简介 从网上找到下面的一张图,自认为这张图相当好: 简单的说ORM,能够达到这样一种效果:我们不用去知道数据库(R)的内容,系统根据M,通过对对象(O)的操作,自动完成访问数据库.例如要完成"根据ID查询",我们对对象使用了Get<

ORM利器:NHibernate(一)简介

简介: ORM(Object Relational Mapping)对象关系映射,是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术 . 为什么出现ORM?     面向对象的特征:我们通常使用的开发语言Java,.Net都是面向对象的.面向封装了对象,对象内部有属性和方法.     关系型数据库的特点:以表的形式组织我们的数据.以列的形式表述了表的特征.表中的一条记录=一个对象,表中的列代表了对象中的属性.表之间是建立了一定的联系.     如何表中的一条记录提取出来封装成一个对象?

ORM利器:NHibernate(二)使用CodeSmith快速生成映射文件和映射类

    在上一篇文章<ORM利器:NHibernate(一)简介>,我们对NHibernate做了简要介绍,接下来的系列文章将以Demo的形式和大家分享使用NHibernate的初步使用. 一 CodeSmith简介 本文以表自动生成NHibernate的映射文件和映射类的实例来说明一下本软件的使用方法.     CodeSmith是一种基于模板的代码生成工具,其使用类似于ASP.NET的语法来生成任意类型的代码和文件.使用 CodeSmith,可以生成包括简单的强类型集合和完整应用程序在内的

Json转换利器Gson之实例一-简单对象转化和带泛型的List转化

Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库.可以将一个 JSON 字符串转成一个 Java 对象,或者反过来. jar和源码下载地址: http://code.google.com/p/google-gson/downloads/list 实体类: [java] view plaincopy [java] view plaincopy public class Student { private int id; private Str

VC控件自绘制三步曲

http://blog.csdn.net/lijie45655/article/details/6362441 实现自定义绘制的三步曲 既然您已经了解了绘制控件可用的各种选项(包括使用自定义绘制的好处),那么,让我们来看看实现一个自定义绘制控件需要的三个主要步骤. 执行一个 NM_CUSTOMDRAW 消息处理程序. 指定处理所需的绘制阶段. 筛选特定的绘制阶段(在这些阶段中,您需要加入自己的特定于控件的绘制代码). 执行一个NM_CUSTOMDRAW 消息处理程序 当需要绘制一个公共控件时,M

高效阅读文章的“三步曲”

高效阅读文章的“三步曲” 通读杨春玲老师的两篇博文“我科研过程中走过的弯路及纠偏探索 ”.“如何有效阅读文献(图) ”及其中链接的文章How to Read a Paper http://blog.sciencenet.cn/home.php?mod=attachment&filename=howtoread.pdf&id=47254,现给出自己对于这一问题的思考,以下没有标注的引号里的内容均来自杨老师的两篇博文中. 一.认真研读自己专业的经典教材,“教材是一个领域里最佳参考,研究之前先查

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

最近框架项目需要,数据层想使用Nhibernate,代替传统的sql语句的写法,更加使用面向对象的思维来维护实体与数据库的这层关系映射(ORM),好在之前接触过Java时学习使用了Hibernate,先来了解ORM.    什么是ORM? 对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的.面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统.对象和关系数据是业务

OpenCV-2.4.2 安装三步曲

注意:本人未使用  ffmpeg 的全部依赖库,比如AAC 音频编码库(libfaac-dev),MP3 编码库(ibmp3lame-dev),具体的配置为: ./configure --enable-shared --enable-gpl --enable-version3 --enable-nonfree --enable-x11grab --enable-libx264 --enable-libxvid ===========================================

LAMP环境配置三步曲之(一) CentOS 编译安装 Apache

LAMP环境的配置现今虽然已比之前大大的简化了,但对于一些不熟悉Linux系统的朋友来说,还是有一定难度的,这里将本人的配置过程记录下来,希望能对大家有一些帮助. 本期介绍CentOS下编译安装Apache的方法: 1. 下载Apache服务器 httpd-2.2.26 wget http://apache.fayea.com/apache-mirror//httpd/httpd-2.2.26.tar.gz 2. 安装gcc等必须的编译器 yum install autoconf automak