Configuring NHibernate with App.config
使用App.config配置NHibernate
NHibernate提供了多种配置设置的方法,本节将介绍如何使用应用程序的配置文件去配置NHibernate,这样可以使配置的数量最小化,以提高应用程序的性能(启动&运行).本节内容也是本章中其他章节的基础
准备工作
1. 完成第一章中Eg.Core项目的模式和映射部分.
2. 在你的解决方案中添加一个名为ConfigByAppConfig的控制台项目.
3. 将她设置为启动项目.
4. 为该项目添加NHibernate.dll 和NHibernate.ByteCode.Castle.dll引用,这两个文件在Lib文件夹中.
5. 为该项目添加到Eg.Core的引用.
6. 为该项目添加一个App.config文件.
步骤
1. 打开App.config文件.
2. 为NHibernate配置声明一个section,代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<configSections> <section name="hibernate-configuration" type="NHibernate.Cfg. ConfigurationSectionHandler, NHibernate"/> </configSections>
3. 添加一个连接字符串:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<connectionStrings> <add name="db" connectionString="Server=.\SQLExpress; Database=NHCookbook; Trusted_Connection=SSPI"/> </connectionStrings>
4. 添加hibernate-configuration section:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> <session-factory> <property name="proxyfactory.factory_class"> NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate. ByteCode.Castle </property> <property name="dialect"> NHibernate.Dialect.MsSql2008Dialect, NHibernate </property> <property name="connection.connection_string_name"> db </property> <property name="adonet.batch_size"> 100 </property> <mapping assembly="Eg.Core"/> </session-factory> </hibernate-configuration>>
5. 现在App.config文件应该如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="hibernate-configuration" type="NHibernate.Cfg. ConfigurationSectionHandler, NHibernate"/> </configSections> <connectionStrings> <add name="db" connectionString="Server=.\SQLExpress; Database=NHCookbook; Trusted_Connection=SSPI"/> </connectionStrings> <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> <session-factory> <property name="proxyfactory.factory_class"> NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate. ByteCode.Castle </property> <property name="dialect"> NHibernate.Dialect.MsSql2008Dialect, NHibernate </property> <property name="connection.connection_string_name"> db </property> <property name="adonet.batch_size"> 100 </property> <mapping assembly="Eg.Core"/> </session-factory> </hibernate-configuration>> </configuration>
6. 打开Program.cs为其添加using NHibernate.Cfg;.
7. 在Main函数中添加下面的代码以完成对NHibernate的配置:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
var nhConfig = new Configuration().Configure(); var sessionFactory = nhConfig.BuildSessionFactory(); Console.WriteLine("NHibernate Configured!"); Console.ReadKey();
8. 编译运行,可以看到提示文本NHibernate Configured!.
原理
我们定义的连接字符串指向本地Microsoft SQL Server Express 2008中的NHCookbook数据库,然后,我们定义了几个属性告诉NHibernate如何去运行。proxyfactory.factory_class指定了我们所用的代理框架,本节中,我们使用Castle's DynamicProxy2。另外,NHibernate也支持LinFu和Spring框架。
dialect属性指定一个方言类, NHibernate用她去创建所用的关系数据库(RDBMS)的SQL语句。此处我们使用Microsoft SQL 2008的方言。另外,大多数方言可以自动为其他 NHibernate属性提供默认值,例如connection.driver_class .
connection.connection_string_name属性使用连接字符串的名字:db。连接字符串的名字是可以更改的,只要connection.connection_string_name属性和连接字符串的名字相同即可。
默认情况下,NHibernate会发送一个单独的SQL语句并等待数据库对该语句的响应。但如果我们将adonet.batch_size属性设置为100,那么在一个单独的ADO.NET命令中NHibernate也可以批量(以100条语句为上限)执行SQL语句的INSERT, UPDATE,和 DELETE语句。实际上,这100次交互操作被组合成了一个。
而对数据库的一次交互操作,在最好的情况下是一次进程调用,但糟糕的是,有时需要通过本地网甚至是Internet来实现。因此,如果设置了该属性,将会显著提升程序的性能有。
当前,SqlClientDriver for Microsoft SQL Server和OracleDataClientDriver for Oracle都支持这样的批处理。
mappings 元素为NHibernate定义了查找映射的数据源。本节中,NHibernate从Eg.Core程序集中后缀为.hbm.xml的嵌入资源中查找。
扩展内容
NHibernate引用程序中有几个关键组件,如下图所示:
初始化时,NHibernate应用程序将生成一个配置对象。本节中,我们通过设置App.config文件来生成该配置对象。该对象负责加载映射信息、反射模型的其他信息 、生成映射的元数据并最终生成一个会话工厂。生成一个会话工厂的开销是昂贵的,因此在一个应用程序的生命周期中只构建一次。该会话工厂负责生成会话。和生成会话工厂不同,生成一个会话的开销是很小的。
在应用程序中,一个会话代表一个工作单元。马丁·福勒将一个工作单元定义为一个对象(该对象包含业务与coordinates相关的对象的列表)和the writing out of changes 和并发性问题的解决方案。NHibernate会话会跟踪实体的变化,并根据这些变化统一更新数据库。在NHibernate中,这种先等待后统一更新数据库的处理方法被称为延迟事务处理。另外,该会话是大部分NHibernate API的入口。
工作单元模式的更多信息请参看http://martinfowler.com/eaaCatalog/unitOfWork.html和马丁·福勒的著作《Patterns of Enterprise Application Architecture》.
该会话充当了应用程序和几个关键NHibernate组件的媒介。也就是说应用程序将不会直接与这些组件交互,但是理解这些组件将是理解NHibernate的关键。
dialect用来生成符合特定的RDBMS的语法的SQL语句。例如,在Microsoft SQL Server中, SELECT TOP 20这个语句会生成结果集中的前20条记录,也就是只有20条记录返回。但是在SQLite中,还要在该语句的末尾加上LIMIT 20. 每一个dialect都为所选定的RDBMS提供必要的SQL语法转换和其他信息以确保可以生成正确的SQL语句.
driver负责生成batcher、创建IDbConnection和IDbCommand对象,以及准备这些指令.
connection provider只负责打开关闭数据库连接.
batcher负责管理发送给数据库/数据读取器结果集的批处理。目前只有和SqlClientDriver和OracleDataDriver支持该功能 。不支持该功能的drivers使用NonBatchingBatcher管理 IDbCommands和IDataReaders,她可以模拟实现单一的批处理(逻辑上的)功能.
NHibernate 属性列表
下表是几个常用的NHibernate属性.
属性名 | 描述 |
connection.provider | 打开关闭数据库连接 |
connection.driver_class | 由所使用的RDBMS确定,通常由dialect自动设置。 |
connection.connection_string |
数据库连接字符串
|
connection.connection_string_name |
数据库连接字符串名称(定义在.Net配置文件
<connectionStrings>
配置节里面的连接字符串名。
|
connection.isolation |
ADO.NET事务隔离级别
|
dialect | 必须配置。生成特定于RDBMS的SQL. NHibernate.Dialect 命名空间下有许多可选的dialect |
show_sql | Boolean值.设置为true时输入所有SQL语句到控制台或者使用log4net将SQL语句输出倒其他位置 |
current_session_context_class | 管理上下文相关的会话的一个类,将在第三章进一步阐述 |
query.substitutions | 将执行的查询字符串替换为用逗号分割的列表,例如True=1, Yes=1, False=0, No=0. |
sql_exception_converter | 将特定数据库的ADO.NET异常转化为自定义的异常 |
prepare_sql | Boolean值. 准备SQL语句和缓存持续数据库连接的执行计划。 |
command_timeout | Nhibernate等待完成一个SQL命令的超时时间:单位:秒。 |
adonet.batch_size | 指定用ADO.Net的批量更新的数量,默认设置为0(不启用该功能)。 |
generate_statistics | 启用对统计信息的跟踪,例如多少个查询被执行,多少个实体被加载。 |
proxyfactory.factory_class | 必须配置.为所选的代理框架指定一个工厂类,本节使用:Castle DynamicProxy2. |
format_sql | 添加行结束标记以增强SQL语句的可读性 |
关于这些设置的详细信息请参考:http://www.nhforge.org/doc/nh/en/index.html .
Dialects and drivers
大多数情况下,dialects设置完以后可以为部分的NHibernate属性提供默认值,比如connection.driver_class。NHibernate的NHibernate.Dialect namespace和NHibernate.Driver namespace中的dialects和drivers见下表:
RDBMS | Dialect(s) | Driver(s) |
Microsoft SQL Server | MsSql2008Dialect | SqlClientDriver |
MsSql2005Dialect | SqlServerCEDriver | |
MsSql2000Dialect | ||
MsSql7Dialect | ||
MsSqlCEDialect | ||
Oracle | Oracle10gDialect | OracleClientDriver |
Oracle9iDialect | OracleDataClientDriver | |
Oracle8iDialect | OracleLiteDataDriver | |
OracleLiteDialect | ||
MySql | MySQLDialect | MySqlDataDriver |
MySQL5Dialect | ||
PostgreSQL | PostGreSQLDialect | NpgsqlDriver |
PostGreSQL81Dialect | ||
PostGreSQL82Dialect | ||
DB2 | DB2Dialect | DB2Driver |
Db2400Dialect | DB2400Driver | |
Informix | InformixDialect | IfxDriver |
InformixDialect0940 | ||
InformixDialect1000 | ||
Sybase | SybaseDialect | SybaseClientDriver |
SybaseASA10Dialect | ASAClientDriver | |
SybaseASA9Dialect | ASA10ClientDriver | |
Sybase11Dialect | SybaseAdoNet12ClientDriver | |
SybaseAdoNet12Dialect | ||
SybaseAnywhereDialect | ||
Firebird | FirebirdDialect | FirebirdDriver |
FirebirdClientDriver | ||
SQLite | SQLiteDialect | SQLiteDriver |
SQLite20Driver | ||
Ingres | IngresDialect | IngresDriver |