从零开始在.net中使用Nhibernate对数据库进行操作详细步骤
从学习NhibernateERP中,还得知不单只ADO.NET能是实现对数据库表进行操作,还有Nhibernate、Linq、EntityFramwork这些技术。算我孤陋寡闻吧。
刚学完Nhibernate,也折腾了一天才搞好,就拿出来跟大家分享一下吧。
首先我们必须知道的是,NhibernateERP是ORM框架,所谓ORM就是Object Relational Mapping,是一种将关系型数据库中的数据与面向对象语言中对象建立映射关联的技术。
用Nhibernate的好处是什么呢?使用Nhibernate操作数据库,我们可以像操作对象一样操作数据库,Nhibernate将我们对对象的变更保存到数据库中去,还负责以对象的方式从数据库中查询数据,好处就是可以使开发人员从处理数据库这里节省时间和精力用于处理业务逻辑。
我们使用的Nhibernate框架,可以再官网上找到,www.nhibernate.org 或者csdn找咯。我这里用的版本是2.1.2.GA 。
一、Nhibernate目录下的内容
1、Configuration_Templates:存放Nhibernate连接数据库的配置文件的示例
根据实制所用的数据库选择示例中的代码并更改其中的数据源即可。
2、Required_Bins:存放Nhibernate运行过程中所需要的类库文件(dll)
其中还包含第三方的开源日志框架Log4Net,这个框架主要用于记录程序日志信息。()
3、Required_For_LazyLoading:存放延时加载特性支持所需的框架文件,在这个文件夹下提供了三种实现,选择其中一种将其所有的dll文件引用到项目中去。在本实例中选择了Castle
Castel的核心是个轻量级容器,实现了IoC模式的容器,基于此核心容器所建立的应用程序,可以达到程序组件的松散耦合,让程序组件可以进行测试,这些特性都使得整个应用程序可以再架构上与维护上都能得到相当程度的简化。(来自百度 )
4、Tests:存放测试试用文件,在此文件夹下有一个名为ABC.bhm.xml的文件,这个是数据表对应配置文件的示例。
二、开始创建第一个程序测试和配置
1、 首先在数据库创建我们的表,表结构如下:
我们先创建一个名为ERP的数据库,建表,表名:Person
把如下语句在数据库执行就好了:
USE [ERP] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Person]( [ID] [int] IDENTITY(1,1) NOT NULL, [UserID] [int] NULL, [UserName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL, [BirtherDate] [datetime] NULL, [Height] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL, [Sex] [int] NULL, CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY]
三、创建一个解决方案命名为NHIbernateERP
1、在解决方案添加三个项目,分别为DAL,DomainModel,WebApp
1) 在项目DomainModel中分别见两个目录,Entities和Mappings从大意上我们可以知道,
Entities是放实体类的(持久化类),Mapping是放映射对象。
持久化类:是指其实例需要被Hibernate持久化到数据库中的类。持久化类包含一些属性,有get和set,且属性名的首字母为大写。
首先我们把Iesi.Collections文件引用进来。
Lesi.Collection类库作用相当于现在的Linq,提供集合运算功能,且支持泛型。这里我们使用它 在两个集合里取相同部分的功能。
2)、【Entities】下建立Person类
代码如下,我们只要求包含get和set,属性的首字母要大写
public class Person { public virtual int ID { get; set; } public virtual int UserID { get; set; } public virtual string UserName { get; set; } public virtual DateTime BirtherDate { get; set; } public virtual float Height { get; set; } public virtual bool Sex { get; set; } }
3)、【Mappings】下建立映射文件Person.hbm.xml,注意Person是对应上面实体类的名称,必须以.hbm.xml为后缀名。我们可以参照Nhibernate包里面的实例Tests文件夹里面的ABC.hbm.xml。如果想在编写时候有智能提示的,可以把【Required_Bins】目录下的
[Nhibernate-configuration.xsd]和[nhibernate-mapping.xsd]两个文件拷贝到VS 的安装目录/Microsoft Visual Studio 10.0/Xml/Schemas下,就可以有智能提示了。
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DomainModel" namespace="DomainModel"> <class name="DomainModel.Entities.Person,DomainModel" table="Person"> //name=类的全名,命名空间 table=表名 <id name="ID" column="ID"> <generator class="native" /> </id> <property name="UserID" column="UserID" /> // name=属性名 cloumn=字段名称 <property name="UserName" column="UserName" /> <property name="BirtherDate" column="BirtherDate" /> <property name="Height" column="Height" /> <property name="Sex" column="Sex" /> </class> </hibernate-mapping>
注意,属性名必须跟实体类的属性名相同,注意大小写,字段名必须对应Person表的字段,注意大小写。
在配置完这个文件以后,要注意关键的一步,把【Person.hbm.xml】文件的属性
复制到输出目录:始终复制
生成操作:嵌入的资源
在完成上面的操作之后把该项目生成以下。
2、在DAL项目中,引用需要的dll文件,包括以下
主要是:DomainModel(上一个项目生成的dll文件),Iesi.Collections,Nhibernate,nunit.framework
在这里我们添加一个NhibernateHelper.cs类,这个类主要是辅助下面PersonHQ.cs,获取Isession.代码如下:
public class NHinbernateHelper { // private ISessionFactory _sessionfacotry; //构造函数,在new这个类的时候就调用GetSessionFactory这个方法获取到ISessionFactory public NHinbernateHelper() { _sessionfacotry = GetSessionFactory(); } private ISessionFactory GetSessionFactory() { Configuration cfg = new Configuration(); ISessionFactory sf = cfg.Configure().BuildSessionFactory(); return sf; } //获得Isession public ISession GetSession() { ISession session = _sessionfacotry.OpenSession(); return session; } }
然后再添加一个PersonHQL.cs类,实现增删改查,还有分页查询方法。
PersonHQL.cs类的代码如下:
public class PersonHQL { private ISession _session; public ISession Session { get { return _session; } } //构造函数,在new这个类的时候,需要传一个ISession参数 public PersonHQL(ISession session) { _session = session; } //增加一条记录 /// <summary> /// 增加记录 /// </summary> /// <param name="person">Person实体</param> /// <returns>int</returns> public int CreatePerson(Person person) { int newid = (int)_session.Save(person); _session.Flush(); return newid; } //删除一条记录 /// <summary> /// 删除记录 /// </summary> /// <param name="person">Person实体</param> /// <returns>bool</returns> public bool DeletePerson(Person person) { _session.Delete(person); _session.Flush(); return true; } //更新一条记录 /// <summary> /// 更新记录 /// </summary> /// <param name="person">Person实体</param> /// <returns>无返回值</returns> public void UpdatePerson(Person person) { _session.Update(person); _session.Flush(); } //获取Person整张表的数据 /// <summary> /// 获取整张Person的记录 /// </summary> /// <param>无参数</param> /// <returns>IList<Person></returns> public IList<Person> GetList() { return _session.CreateQuery("from Person").List<Person>(); } //把查询某一段的数据,pagesize是第几条记录开始从0开始记起,pageindex读取多少条记录 /// <summary> /// 查询某一段的记录 /// </summary> /// <param name="pagesize">开始的位置</param> /// <param name="pageindex">记录数量</param> /// <returns>IList<Person></returns> public IList<Person> GetList(int pagesize, int pageindex) { return _session .CreateQuery("from Person") .SetFirstResult(pagesize) .SetMaxResults(pageindex) .List<Person>(); } //每个页面10条记录,参数page为第几页从1开始 /// <summary> /// 以每页为10条记录,查询第几页的记录,从1开始 /// </summary> /// <param name="page">第几页</param> /// <returns>IList<Person></returns> public IList<Person> GetList(int page) { IList<Person> pers=GetList(); return GetList((page-1)*10, 10);//第二个参数为每页的记录数量 } //读取某条记录 /// <summary> /// 读取 /// </summary> /// <param name="ID">ID</param> /// <returns></returns> public Person GetPerson(int id) { var result = from c in this.GetList() where c.ID == id select c; return result.First(); } //读取某条记录 /// <summary> /// 读取 /// </summary> /// <param name="ID">ID</param> /// <returns></returns> public Person Read(int id) { Person person = _session.Get<Person>(id); _session.Close(); return person; } }
完成以上的步骤,然后生成以下改项目。
3、在WebApp项目中,添加dll文件
主要包括以上圈着的文件,在Nhibernate包里能找到。DAL和DomainMode是上两个项目生成的dll文件。
1) 在这里我们需要配置一个文件
【Hibernate.cfg.xml】这个文件在Nhibernate包里面的【Configuration_Templates】目录,找相应的文件,我们使用的是SQL Server所以把MSSQL.cfg.xml文件复制过来。最好把复制过来的文件名改一下,如果不改为hibernate.cfg.xml,在后面获取Isession时要把文件名引用进来,如下区别:
Configuration cfg = new Configuration().configure();//以hibernate.cfg.xml为文件名
Configuration cfg = new Configuration().configure("文件名");//指定文件名
ISessionFactory factory = cfg.buiddSessionfactory();
ISession session = factory.openSession();
在hibernate.cfg.xml文件中,我们需要注意的是:
<?xml version="1.0" encoding="utf-8" ?> <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" > <session-factory name="WebApp"> <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property> <property name="connection.connection_string"> Data Source=.;Initial Catalog=ERP;User ID=sa;Password=123456 </property> <property name="adonet.batch_size">10</property> <property name="show_sql">true</property> <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property> <property name="use_outer_join">true</property> <property name="command_timeout">10</property> <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property> <property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory,NHibernate.ByteCode.LinFu</property> <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory,NHibernate.ByteCode.Castle</property> <mapping assembly="DomainModel"/> </session-factory> </hibernate-configuration>
配以一下数据库的链接字符串。配置好这个文件之后需要设置它的属性:
复制到输出目录:始终复制
2)、接下来让我们建一个简单的页面,验证对数据表Person的增删改查和分页查询功能。
页面很简单
2) 前台主要代码:简单用几个按钮测试一下
<div> 使用顺序:请先Create创建一条记录,再Read阅读第一条记录,然后Updat更新第一条记录,然后Read阅读对比之前的记录,然后再删除。<br /> <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Create" /> <br /> <asp:Button ID="ButtonDelete" runat="server" Text="Delete" onclick="ButtonDelete_Click" /> 删除第一条记录<br /> <asp:Button ID="ButtonRead" runat="server" Text="Read" onclick="ButtonRead_Click" /> 阅读第一条记录<br /> <asp:Button ID="ButtonUpdate" runat="server" Text="Update" onclick="ButtonUpdate_Click" /> 更新第一条记录<br /> <asp:TextBox ID="TextBoxReadList" runat="server"></asp:TextBox> <asp:Button ID="ButtonReadList" runat="server" Text="ReadList" onclick="ButtonReadList_Click" /> 请输入查询第几页数据<br /> </div>
2) 后台代码主要代码
using DomainModel.Entities; using DAL; namespace WebApp { public partial class WebForm1 : System.Web.UI.Page { private PersonHQL pHQL; protected void Page_Load(object sender, EventArgs e) { NHinbernateHelper helper = new NHinbernateHelper(); pHQL = new PersonHQL(helper.GetSession()); } protected void Button1_Click(object sender, EventArgs e) { Person person = new Person { UserID=Convert.ToInt32(1), BirtherDate =Convert.ToDateTime("2012-12-25"), Height = 200, UserName = "张三"+DateTime.Now.Second.ToString(), Sex =Convert.ToBoolean(true) }; pHQL.CreatePerson(person);//增加记录 } protected void ButtonRead_Click(object sender, EventArgs e) { Person person = pHQL.Read(1);//阅读第一条记录 Response.Write(person.UserID.ToString()+"<br>"+person.UserName.ToString ()+"<br>"+person.BirtherDate.ToShortDateString()+"<br>"+person.Height.ToString()); } protected void ButtonDelete_Click(object sender, EventArgs e) { Person person = new Person { ID=1, UserID=1, BirtherDate = Convert.ToDateTime("2012-12-25"), Height = 200, UserName = "张三", }; pHQL.DeletePerson(person); } protected void ButtonUpdate_Click(object sender, EventArgs e) { Person person = new Person { ID=1, UserID = 1, BirtherDate = Convert.ToDateTime("2012-12-25"), Height = 198, UserName = "李四", Sex = false }; pHQL.UpdatePerson(person); } protected void ButtonReadList_Click(object sender, EventArgs e) { IList<Person> persons = pHQL.GetList(Convert.ToInt32(TextBoxReadList.Text.ToString())); foreach (Person person in persons) { Response.Write(person.UserName.ToString() + "<br>"); } } } }
好了,终于完成了,让我们来运行看一下
1)运行效果:
2)Create之后,数据增加了数据啦
3)Read第一条记录
3)ReadList之后