ORM武器:NHibernate(三)五个步骤+简单对象CRUD+HQL

news/2024/7/5 2:13:12

前面的两篇文章中。我们对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数据库,仅仅须要更改对应的配置信息就能够。
<?

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{//创建sessionISession 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的使用。


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


http://lihuaxi.xjx100.cn/news/244619.html

相关文章

Java面试题汇总2021最新(含答案下载)

Java基础面试题2021最新&#xff08;含答案下载&#xff09; 最近给大家整理了一批Java基础面试题一共110题&#xff0c;20201最新时间整理的&#xff0c;并且都含答案打包下载。 适宜阅读人群 需要面试的初/中/高级 java 程序员 想要查漏补缺的人 想要不断完善和扩充自己 …

SpringDataJpA或查询

1.需求 进入投诉建议模块的人员列表时候&#xff0c;可以查到客服和售后管家类型的数据 private Specification<Employee> whereClause(Employee entity) { return new Specification<Employee>() { Override public Predicate toPredicate(Root<Emp…

软件安全访谈:ZipSlip、NodeJS安全性和BBS攻击

正如Nodejs Security WG成员和Snyk开发者布道师Liran Tal所写的那样&#xff0c;自BBS早期以来&#xff0c;这种漏洞利用的矢量攻击已经为人所知。InfoQ采访了Tal&#xff0c;了解了更多有关软件安全性&#xff08;尤其是Nodejs安全性&#xff09;的相关信息。今年早些时候&…

Java面试题汇总2021最新(集合泛型含答案下载)

Java面试题及答案2021最新24题&#xff08;集合&泛型&#xff09; 最近给大家整理了一批Java面试题一共24题&#xff0c;主要是搜集的Java集合&泛型这块的&#xff0c;是20201最新时间整理的&#xff0c;并且都含答案打包下载。 适宜阅读人群 需要面试的初/中/高级 j…

UIScrollView offset in UINavigationController

转&#xff1a;UIScrollView offset in UINavigationController 通过设置viewCtronller的 self.automaticallyAdjustsScrollViewInsets NO; 禁用苹果scrollview提供的自适应功能。 延伸阅读&#xff1a;https://developer.apple.com/library/ios/documentation/UserExperience…

PriorityBlockingQueue详解

1.PriorityBlockingQueue public class PriorityBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, Serializable 所有添加进入PriorityBlockingQueue的元素都必须实现Comparable接口。当插入元素时&#xff0c;PriorityBlockingQueu…

bats-Bash自动化测试工具

本文分析了bats--Bash自动化测试工具的安装、语法、常用指令及常用函数等内容。上篇文章回顾&#xff1a;学习RAID 01/10/10E的区别bats 是一个符合 TAP 标准 的 Bash 版测试框架&#xff0c;它使用了一种极为简便的方法来验证命令行程序是否正常运行。bats 要求 Bash 的最低版…

SpringBoot如何处理java内存溢出

在上线的项目中&#xff0c;本地测试没有问题&#xff0c;部署上去就会出现java 内存溢出 java.lang.OutOfMemoryError: Java heap space 解决方案&#xff1a; -Xms512m -Xmx512m 问题得到解决