NHibernate历程2

更新时间:2024-03-30 13:04:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

当前期工作都准备完成后,将开始NHibernate的学习过程,而在第一个

NHibernate程序中,将实现通过NHibernate根据客户编号对客户表进行单条记录的查询示例。该示例中,我们将按以下几部分说明。 一、结构分析 1.分层

习惯了分层的体系结构,所以将第一个NHibernate程序按以下方式进行分层

说明:

A.Model层:模型层,是最底层,类似于传统三层中的实体层,用于持久化类和O/R Mapping操作。

B.DAL层:DataAccessLayer层,高于Model层而低于App层,是数据访问层,定义对象的CRUD 操作。

C.App层:应用层,最高层,用于跟用户的交互。 2.引用

Model层:引用Iesi.Collections.dll 程序集

DAL层:引用NHibernate.dll 和Iesi.Collections.dll 程序集,引用Model层。

App层:引用NHibernate.dll 和Iesi.Collections.dll 程序集,引用Model层和DAL层。

二、Model层

按简单传统.NET 对象(POCOs,Plain Old CLR Objects(Plain Ordinary CLR Objects))模型编程时需要持久化类,也可以说是DTO(Data Transfer Object,数据传

送对象)模式(这是迄今为止可以工作的最简单方式)。在NHibernate 中,POCO 通过.NET 的属性机制存取数据,就可以把它映射成为数据库表。 1.客户表的持久化类

Customer对象新建一个类文件,命名为CustomerEntity.cs

public class CustomerEntity {

public virtual string CustomerID { get; set; } public virtual string CustomerName { get; set; } public virtual string LinkPhone { get; set; } public virtual string LinkAddress { get; set; } }

说明:

A. NHibernate 使用属性的getter 和setter 来实现持久化

B. 属性可设置为public、internal、protected、protected internal 或private

注意:

NHibernate默认使用代理功能,要求持久化类不是 sealed 的,而且其公共方

法、属性和事件声明为virtual。在这里,类中的字段要设置为virtual,否则出现异常, 异常内容如下:

“failed: NHibernate.InvalidProxyTypeException : The following types may not be used as proxies: DomainModel.Entities.Customer: method get_CustomerId

should be virtual,method set_CustomerId should be virtual”。 2. 客户表的映射文件

为Customer对象新建一XML 文件,命名为Customer.hbm.xml

=\l\ table=\>

说明:

A. XML文件的默认生成操作为“内容”,这里需要修改为“嵌入的资源”生成,否

则出现异常,异常内容如下:

Unable to locate persister for the entity named

'NHibernateExample01.Model.Entity.CustomerEntity'.

The persister define the persistence strategy for an entity. Possible causes:

The mapping for 'NHibernateExample01.Model.Entity.CustomerEntity'

was not added to the NHibernate configuration

B. 配置节< hibernate-mapping>中,urn:nhibernate-mapping-2.2是Xml

的命名空间,跟NHibernate的DLL版本无关

C. 配置节中,如果没有限定assembly 和

namespace,那么在配置节中,需要完整限定名。否则出现异常,异常内容如下:

Could not compile the mapping document:

NHibernateExample01.Model.Entity.Customer.hbm.xml

D. 配置节中,Native主键生成方式会根据不同的底层数据库自动

选择Identity、Sequence、Hilo主键生成方式根据不同的底层数据库采用不同的主键 生成方式。由于Hibernate会根据底层数据库采用不同的映射方式,因此便于程序移植,项目中如果用到多个数据库时,可以使用这种方式。 三、DAL

1. 会话管理类

整个NHibernate的数据流程如下:

A.通过Configuration(NHibernate.Cfg.Configuration)构建ISessionFactory的属性和映射文件。

B. 通过ISessionFactory生成Session。ISessionFactory 是线程安全的,很多线程可以同时访问它。

C. Session进行一个单线程的单元操作(数据操作)。Session 不是线程安全的,它代表与数据库之间的一次操作,在所有的工作完成后,需要关闭。

由此可见,ISessionFactory是整个数据访问的核心,由于它是线程安全性的,所以它可以做全局性对象,将使用单例模式来构建对它的管理。

public class SessionManager {

private ISessionFactory _sessionFactory; public SessionManager() {

_sessionFactory = GetSessionFactory(); }

private ISessionFactory GetSessionFactory() {

return (new Configuration()).Configure().BuildSessionFactory(); }

public ISession GetSession() {

return _sessionFactory.OpenSession(); } }

2. 数据访问类

NHibernate数据访问是交由Session完成的,所以,数据访问的重点就在ISession上。

在DAL层上新建一个CustomerDal.cs类,用来进行数据访问,编写一方法GetCustomerId 用于读取客户信息。

public class CustomerDal {

private ISession _session;

public ISession Session {

set {

_session = value; } }

public CustomerDal(ISession session) {

_session = session; }

public CustomerEntity GetCustomerByID(string customerID) {

return _session.Get(customerID); } }

4. App层 1. NHibernate

配置文件

NHibernate.Driver.SqlClientDriver

server=.;database=NHibernateSample;uid=sa;pwd=123456;

10 true

NHibernate.Dialect.MsSql2008Dialect

10 true 1, false 0, yes 'Y', no 'N'

说明:

A.XML文件的默认“复制到输出目录”为“不复制”,这里需要修改为“始终复制”,否

则出现异常,异常内容如下:

failed: NHibernate.Cfg.HibernateConfigException : An exception

occurredduring configuration of persistence layer. ----> System.IO.FileNotFoundException : 未能找到文件“NHibernateSample\\DAL.Test\\bin\\Debug\\hibernate.cfg.xml””

B.配置文件会随着NHibernate的DLL版本不同而不同,需要详细查看NHibernate

的DLL的Change日志。

C.属性connection.provider设置了数据库连接提供者(一般不需要更改,除非你

决定自己实现提供者)。

D. 属性connection.driver_class设置了数据库的的驱动类(这里设置了

SqlServer的驱动类)。

E. 属性connection.connection_string是数据库的连接字符串。

F. 属性show_sql设置是否在运行时是否在控制台显示正在执行的SQL语句(这

个属性在调试程序时很有用)。

G. 属性dialect是NHibernate方言, 可以让NHibernate使用某些特定的数据

库平台的特性。

H. 属性query.substitutions,把NHibernate查询中的一些短语替换为SQL短

语(比如说短语可能是函数或者字符)。

I. 属性mapping节点设置了将使用到的映射文件。

2. 窗体文件内容

public partial class Form1 : Form {

public Form1() {

InitializeComponent();

Init(); }

private void Init() {

string CustomerID =

\;

SessionManager _helper = new SessionManager(); ISession _session = _helper.GetSession();

CustomerDal _sample = new CustomerDal(_session);

CustomerEntity entity = _sample.GetCustomerByID(CustomerID);

if (entity != null) {

txtName.Text = entity.CustomerName; txtAddress.Text = entity.LinkAddress; txtPhone.Text = entity.LinkPhone; }

} }

说明:

A.数据库中CustomerInfo表中有一条数据:

CustomerID CustomerName LinkPhone LinkAddress 48CBCDFC-1AAA-4A0huhai 8-9C9B-4578C6F59E8C 18618181513 内蒙古呼和浩特市赛罕区东影西路 B. 显示结果如下:

本文来源:https://www.bwwdw.com/article/gker.html

Top