NHibernate官方文档中文版--ISessionFactory的配置(ISessionFactory Configuration)
由于NHibernate是被设计应用在许多不同环境中的,因此它存在很多配置参数。幸运的是,这些参数大多都有合理的默认值,而且NHibernate发布的时候伴随着一个App.config 例子(可在src\NHibernate.Test找到),这个例子已经包含了了很多配置信息。你通常只要把这个文件放如你的项目中然后定制它就行了。
编程式配置
一个NHibernate.Cfg.Configuration 实例表示一个完整的应用程序里面的类型和SQL数据库mapping信息的集合。Configuration 被用来创建一个(不变的)ISessionFactory。mapping信息编译自各种各样的XML mapping文件。
你可以通过直接实例化的方式获得Configuration 实例。这是一个从两个XML配置文件中的mapping信息建立数据库模型的例子:
Configuration cfg = new Configuration() .AddFile("Item.hbm.xml") .AddFile("Bid.hbm.xml");
另一个方式(在某些情况下更合适)是让NHibernate从嵌入的资源中加载mapping文件:
Configuration cfg = new Configuration() .AddClass(typeof(NHibernate.Auction.Item)) .AddClass(typeof(NHibernate.Auction.Bid));
NHibernate 会查找NHibernate.Auction.Item.hbm.xml 和NHibernate.Auction.Bid.hbm.xml 的mapping文件,这些XML文件都是嵌入在程序集中的资源。这种方式避免了文件名称硬代码。
其他方式(可能是最好的方式)就是让NHibernate加载包含在程序集中的所有mapping文件:
Configuration cfg = new Configuration()
.AddAssembly( "NHibernate.Auction" );
NHibernate会查找程序集中所有以.hbm.xml结尾的资源文件。这种方式避免了文件名称硬代码并且确保了在程序集中的mapping文件能够被添加。
如果使用类似于Visual Studio .NET or NAnt 的工具来生成程序集,要保证.hbm.xml 文件都要是以嵌入的资源编译到程序集中。
Configuration 也定义了一些可选的属性:
IDictionary props = new Hashtable(); ... Configuration cfg = new Configuration() .AddClass(typeof(NHibernate.Auction.Item)) .AddClass(typeof(NHibernate.Auction.Bind)) .SetProperties(props);
Configuration 只是一个配置的时候产生的对象,一旦一个ISessionFactory 实例被建立的时候,他就会被回收。
获得一个ISessionFactory
当所有的mapping都被Configuration解析之后,应用程序会得到一个生产ISession 实例的工厂。这个工厂会被所有线程共享:
ISessionFactory sessions = cfg.BuildSessionFactory();
然而,NHibernate的确会让你生成一个以上的ISessionFactory,这个是使用多个数据库的时候很有用。
用户提供的ADO.NET 连接
在一个由用户提供的ADO.NET 连接中,一个ISessionFactory会开启一个ISession 。这个设计让应用程序能够自由获得它想要的ADO.NET 连接:
IDbConnection conn = myApp.GetOpenConnection(); ISession session = sessions.OpenSession(conn); // do some data access work
要注意,应用程序不能通过在同一个ADO.NET 连接中同时打开两个ISessions 。
NHibernate 提供的 ADO.NET 连接
Alternatively, you can have the ISessionFactory open connections for you. The ISessionFactory must be provided with ADO.NET connection properties in one of the following ways:
-
Pass an instance of IDictionary mapping property names to property values to Configuration.SetProperties().
-
Add the properties to a configuration section in the application configuration file. The section should be named nhibernate and its handler set to System.Configuration.NameValueSectionHandler.
-
Include <property> elements in a configuration section in the application configuration file. The section should be named hibernate-configuration and its handler set to NHibernate.Cfg.ConfigurationSectionHandler. The XML namespace of the section should be set to urn:nhibernate-configuration-2.2.
-
Include <property> elements in hibernate.cfg.xml (discussed later).
If you take this approach, opening an ISession is as simple as:
另外,你也可以让ISessionFactory 为你打开连接。ISessionFactory 必须通过下面几种方式中的一种获得ADO.NET 连接属性:
- 传一个IDictionary 实例,给Configuration.SetProperties().
- 在应用程序配置文件中把属性添加到configuration section 中。这个节点必须叫做nhibernate 并且它的handler是System.Configuration.NameValueSectionHandler。
- 包含在配置文件的configuration section 的<property>属性中。
包含在hibernate.cfg.xml 中<property> 属性中(等会会提及)。
如果你使用这方式,那么打开一个ISession 就这么简单:
ISession session = sessions.OpenSession(); // open a new Session // do some data access work, an ADO.NET connection will be used on demand
NHibernate属性名称和语法都在NHibernate.Cfg.Environment中定义。我们现在说一说ADO.NET 连接配置的重要设定。
如果你设置了下面的属性,NHibernate将会使用一个ADO.NET data provider 来获得(或者保存)连接。
Table 3.1. NHibernate ADO.NET 属性
属性名称
通途
connection.provider_class 自定义 IConnectionProvider 实现.
例如. full.classname.of.ConnectionProvider 如果Provider在 NHibernate中创建, 或者 full.classname.of.ConnectionProvider, assembly 如果使用一个自定义的 IConnectionProvider 接口实现,它不包含在NHibernate中. 默认值是 NHibernate.Connection.DriverConnectionProvider.
connection.driver_class 自定义的 IDriver类型, 如果使用 DriverConnectionProvider.
full.classname.of.Driver 如果Driver在 NHibernate中创建, 或者full.classname.of.Driver, assembly 如果使用不包含在NHibernate中的IDriver 实现.
这个通常是不需要的,大多数情况下方言会使用合理的默认值来完成IDriver的配置。参见特定的方言API文档来或者这些默认值。
connection.connection_string 获得连接的连接字符串。 connection.connection_string_name 用来获得连接的连接字符串的名字(定义在配置文件的<connectionStrings>中) connection.isolation 设置事务的隔离级别。检查System.Data.IsolationLevel 来获得具体值,同时检查数据库文档来确定这个级别是被支持的。
例如:Chaos, ReadCommitted, ReadUncommitted, RepeatableRead, Serializable, Unspecified
connection.release_mode Specify when NHibernate should release ADO.NET connections. See
设置NHibernate 什么时候释放ADO.NET 连接。参见Section 11.7, “Connection Release Modes”
例如:auto (默认) | on_close | after_transaction
需要注意的是,这个配置仅仅影响ISessionFactory.OpenSession返回的ISession。对于从ISessionFactory.GetCurrentSession, ICurrentSessionContext 接口实现的ISession,参见Section 2.3, “Contextual Sessions”.
command_timeout 设置由NHibernate生成的IDbCommands 的默认超时值。 adonet.batch_size 设置使用batch更新时的batch的大小。如果设置成0,就会关闭这个功能。参见Section 19.6, “Batch updates”. 下面是一个在web.config配置数据库连接属性的例子:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" /> </configSections> <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> <session-factory> <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property> <property name="connection.connection_string"> Server=(local);initial catalog=theDb;Integrated Security=SSPI </property> <property name="connection.isolation">ReadCommitted</property> </session-factory> </hibernate-configuration> <!-- other app specific config follows --> </configuration>
NHibernate依赖ADO.NET data provider 实现的连接池。
你可以通过实现NHibernate.Connection.IConnectionProvider接口来自定义获得ADO.NET 连接的方式。你可以通过设置connection.provider_class来选择一个自定义的实现。
可选的配置属性
有许多其他的属性可以控制运行时的NHibernate的行为,所有的这些配置都是可选的,并且有一些合理的默认值。
系统级别的属性只能够通过手动设置NHibernate.Cfg.Environment 类或者在应用程序配置文件中的<nhibernate>中定义。这些属性不能使用Configuration.SetProperties设定,不能在配置文件的<hibernate-configuration>中定义。
Table 3.2. NHibernate Configuration Properties
属性名称
用途
dialect
NHibernate方言类型名称——可以让NHibernate使用某些数据库的特性
例如:full.classname.of.Dialect, assemblydefault_schema
在生成的SQL中确定某个表空间下面的表名称。
例如:SCHEMA_NAMEmax_fetch_depth
为单一终点(single-ended )的关联(one-to-one, many-to-one)设置外连(outer join)的最大深度。设置成0就会禁用外连。
例如:建议在0到3之间use_reflection_optimizer
Enables use of a runtime-generated class to set or get properties of an entity or component instead of using runtime reflection (System-level property). The use of the reflection optimizer inflicts a certain startup cost on the application but should lead to better performance in the long run. You can not set this property in hibernate.cfg.xml or <hibernate-configuration> section of the application configuration file.
eg. true | false
bytecode.provider
Specifies the bytecode provider to use to optimize the use of reflection in NHibernate. Use null to disable the optimization completely, lcg to use lightweight code generation.
eg. null | lcg
cache.provider_class
The classname of a custom ICacheProvider.
eg. classname.of.CacheProvider, assembly
cache.use_minimal_puts
Optimize second-level cache operation to minimize writes, at the cost of more frequent reads (useful for clustered caches).
eg. true | false
cache.use_query_cache
Enable the query cache, individual queries still have to be set cacheable.
eg. true | false
cache.query_cache_factory
The classname of a custom IQueryCacheFactory interface, defaults to the built-in StandardQueryCacheFactory.
eg. classname.of.QueryCacheFactory, assembly
cache.region_prefix
A prefix to use for second-level cache region names.
eg. prefix
query.substitutions
Mapping from tokens in NHibernate queries to SQL tokens (tokens might be function or literal names, for example).
eg. hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC
query.linq_provider_class
The classname of a custom LINQ provider class, one that implements INhQueryProvider. The default is DefaultQueryProvider
eg. true | false
show_sql
将所有SQL语句输出到控制台。
例如. true | false
hbm2ddl.auto
Automatically export schema DDL to the database when the ISessionFactory is created. With create-drop, the database schema will be dropped when the ISessionFactory is closed explicitly.
eg. create | create-drop
hbm2ddl.keywords
Automatically import reserved/keywords from the database when the ISessionFactory is created.
none : disable any operation regarding RDBMS KeyWords
keywords : imports all RDBMS KeyWords where the Dialect can provide the implementation of IDataBaseSchema.
auto-quote : imports all RDBMS KeyWords and auto-quote all table-names/column-names .
eg. none | keywords | auto-quote
use_proxy_validator
允许或者禁用代理接口或者类的验证。默认是允许。
例如: true | false
transaction.factory_class
自定义ITransactionFactory 实现的类名,默认值是内置的AdoNetWithDistributedTransactionFactory
例如. classname.of.TransactionFactory, assembly
default_flush_mode
默认的 FlushMode,默认值是Unspecified
例如: Unspecified | Never | Commit | Auto | AlwaysSQL方言
你应当根据你的数据库类型将dialect属性设置成对应的NHibernate.Dialect.Dialect 子类。这不是必要的,除非你想要使用native或者sequence主键生成策略或者乐观锁(例如:ISession.Lock()或者IQuery.SetLockMode())。然而,如果你确定了一个方言,NHibernate就会用适当的默认值来配置上面的属性来节省你的时间。
Table 3.3. NHibernate SQL Dialects (dialect)
RDBMS Dialect Remarks DB2 NHibernate.Dialect.DB2Dialect DB2 for iSeries (OS/400) NHibernate.Dialect.DB2400Dialect Ingres NHibernate.Dialect.IngresDialect PostgreSQL NHibernate.Dialect.PostgreSQLDialect PostgreSQL 8.1 NHibernate.Dialect.PostgreSQL81Dialect This dialect supports FOR UPDATE NOWAIT available in PostgreSQL 8.1. PostgreSQL 8.2 NHibernate.Dialect.PostgreSQL82Dialect This dialect supports IF EXISTS keyword in DROP TABLE and DROP SEQUENCE available in PostgreSQL 8.2. MySQL 3 or 4 NHibernate.Dialect.MySQLDialect MySQL 5 NHibernate.Dialect.MySQL5Dialect Oracle NHibernate.Dialect.Oracle8iDialect Oracle 9i NHibernate.Dialect.Oracle9iDialect Oracle 10g, Oracle 11g NHibernate.Dialect.Oracle10gDialect Oracle 12c NHibernate.Dialect.Oracle12cDialect Sybase Adaptive Server Enterprise 15 NHibernate.Dialect.SybaseASE15Dialect Sybase Adaptive Server Anywhere 9 NHibernate.Dialect.SybaseASA9Dialect Sybase SQL Anywhere 10 NHibernate.Dialect.SybaseSQLAnywhere10Dialect Sybase SQL Anywhere 11 NHibernate.Dialect.SybaseSQLAnywhere11Dialect Microsoft SQL Server 7 NHibernate.Dialect.MsSql7Dialect Microsoft SQL Server 2000 NHibernate.Dialect.MsSql2000Dialect Microsoft SQL Server 2005 NHibernate.Dialect.MsSql2005Dialect Microsoft SQL Server 2008 NHibernate.Dialect.MsSql2008Dialect Microsoft SQL Server 2012 NHibernate.Dialect.MsSql2012Dialect Microsoft SQL Server Compact Edition NHibernate.Dialect.MsSqlCeDialect Microsoft SQL Server Compact Edition 4 NHibernate.Dialect.MsSqlCe40Dialect Firebird NHibernate.Dialect.FirebirdDialect Set driver_class to NHibernate.Driver.FirebirdClientDriver for Firebird ADO.NET provider 2.0. SQLite NHibernate.Dialect.SQLiteDialect Set driver_class to NHibernate.Driver.SQLite20Driver for System.Data.SQLite provider for .NET 2.0. 在NHibernate.Dialect 名称空间中还包含其他的可用方言。
外连接获取
如果你的数据库支持ANSI或者Oracle风格的外连接,外连接抓取可能提高性能,因为可以限制和数据库交互的数量(代价是数据库自身进行了更多的工作)。外连接抓取允许你在一个SELECT语句中就可以得到一个由many-to-one, one-to-many 或者 one-to-one 连接构成的对象图。
默认情况下的抓取在叶对象,拥有代理的对象或者产生对自身的引用时终止。
对一个特定关联来说,可以通过在XML映射文件中设置outer-join属性可以控制是否开启抓取功能。
可以设置max_fetch_depth为0来禁用全局的外连接抓取。设置为1或者更大的数值将启用one-to-one和many-to-one关联(这些关联被map成fetch="join")中的外连接抓取。
参见Section 19.1, “Fetching strategies” 来获得更多信息。
在NHibernate 1.0,outer-join 特性有相似的作用,这个特性现在已经变不建议使用,我们推荐使用的是fetch。
自定义ICacheProvider
你可以通过实现NHibernate.Cache.ICacheProvider接口来继承一个二级缓存。你可以通过设置cache.provider_class来自定义实现。
参见Section 19.2, “The Second Level Cache” 来获得更多信息。
查询语言替换
你可以使用 query.substitutions 来定义NHibernate新的查询短语. 例如
query.substitutions true=1, false=0
会在生成的SQL中把短语true和false替换成整数值。
query.substitutions toLowercase=LOWER
这可以让你重新命名SQL的LOWER 函数。
日志
通过使用Apache log4net,NHibernate 可以记录很多事件。
你可以从http://logging.apache.org/log4net/ 下载log4net。要使用log4net,你要在app.config或者web.config中配置log4net节点。在src/NHibernate.Test工程中有一个配置的例子
我们强烈建议你熟悉NHibernate's的log信息。NHibernate's的很多工作都会尽量留下详尽却易读的log信息。这个是很重要的定位问题的方式。同样的,别忘记启用上文提到的SQL日志(show_sql),这个是你查找性能问题的第一步。
实现一个INamingStrategy接口
NHibernate.Cfg.INamingStrategy 接口允许你为数据库对象和schema elements(译注,不会翻译)指定一个“命名标准”
你可以提供一个从自动生成数据库。这个特性能个帮你你减少冗长的mapping文件,减少烦人的重复(例如,TBL_ 前缀)。
你可以在添加mapping之前通过调用Configuration.SetNamingStrategy()来指定一个不同的策略:
The interface NHibernate.Cfg.INamingStrategy allows you to specify a "naming standard" for database objects and schema elements.
You may provide rules for automatically generating database identifiers from .NET identifiers or for processing "logical" column and table names given in the mapping file into "physical" table and column names. This feature helps reduce the verbosity of the mapping document, eliminating repetitive noise (TBL_ prefixes, for example). The default strategy used by NHibernate is quite minimal.
You may specify a different strategy by calling Configuration.SetNamingStrategy() before adding mappings:
ISessionFactory sf = new Configuration() .SetNamingStrategy(ImprovedNamingStrategy.Instance) .AddFile("Item.hbm.xml") .AddFile("Bid.hbm.xml") .BuildSessionFactory();
XML配置文件
一个其他的配置方法是在一个叫做hibernate.cfg.xml的文件中进行一个完整的配置。这个文件可以被用来替换应用程序配置文件中的<nhibernate;> 或者 <hibernate-configuration>。
XML配置文件默认需要在你的应用程序目录下,这里是一个例子:
<?xml version='1.0' encoding='utf-8'?> <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> <!-- an ISessionFactory instance --> <session-factory> <!-- properties --> <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property> <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property> <property name="connection.connection_string">Server=localhost;initial catalog=nhibernate;User Id=;Password=</property> <property name="show_sql">false</property> <property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property> <!-- mapping files --> <mapping resource="NHibernate.Auction.Item.hbm.xml" assembly="NHibernate.Auction" /> <mapping resource="NHibernate.Auction.Bid.hbm.xml" assembly="NHibernate.Auction" /> </session-factory> </hibernate-configuration>
配置NHibernate就会如此简单:
ISessionFactory sf = new Configuration().Configure().BuildSessionFactory();
你也可以选一个不同的XML配置文件,使用:
ISessionFactory sf = new Configuration() .Configure("/path/to/config.cfg.xml") .BuildSessionFactory();