NHibernate应用二:第一个NHibernate程序
當前期工作都準備完成后,將開始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
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"><class name ="NHibernateExample01.Model.Entity.CustomerEntity,NHibernateExample01.Model" table="CustomerInfo"><id name="CustomerID" column="CustomerID" type="string" length="36"><generator class ="native"></generator></id><property name="CustomerName" column ="CustomerName" type="string" length="200" /><property name ="LinkPhone" column="LinkPhone" type="string" length="20"/><property name ="LinkAddress" column="LinkAddress" type="string" length="500" /></class> </hibernate-mapping>
說明:
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. 配置節<hibernate-mapping>中,如果沒有限定assembly 和namespace,那么在配置節<Class>中,需要完整限定名。否則出現異常,異常內容如下:
?? Could not compile the mapping document: NHibernateExample01.Model.Entity.Customer.hbm.xml
D. 配置節<generator>中,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<CustomerEntity>(customerID);}}
?
4. App層
1. NHibernate配置文件
?
<?xml version="1.0" encoding="utf-8" ?> <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" ><session-factory><property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property><property name="connection.connection_string">server=.;database=NHibernateSample;uid=sa;pwd=123456;</property><property name="adonet.batch_size">10</property><property name="show_sql">true</property><property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property><property name="command_timeout">10</property><property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property><mapping assembly="NHibernateExample01.Model"/></session-factory> </hibernate-configuration>說明:
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 = "48CBCDFC-1AAA-4A08-9C9B-4578C6F59E8C";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-4A08-9C9B-4578C6F59E8C | huhai | 18618181513 | 內蒙古呼和浩特市賽罕區東影西路 |
?
?
B. 顯示結果如下:
?
轉載于:https://www.cnblogs.com/huhai121/p/3958263.html
總結
以上是生活随笔為你收集整理的NHibernate应用二:第一个NHibernate程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 字符集与编码(四)——Unicode
- 下一篇: 手写PE文件(一)