Hibernate参考手册(第二章)

    技术2022-05-11  102

    Hibernate参考手册

    第二章 SessionFactory配置

    2.1 系统配置

           net.sf.hibernate.Configuration对象的实例描述了由应用程序的Java类型向关系数据库类型进行映射的完整集合。这些映射从各式各样的XML映射文件编译而来。你可以通过直接建立实例来获得Configuration对象的实例。下面有一个从两个XML配置文件所定义的映射中建立数据存储的例子:

    Configuration cfg = new Configuration()

                                                     .addFile("vertex.hbm.xml")

                                                     .addFile("edge.hbm.xml");

    另一个可供选择的方法(更好?)是让Hibernate使用getResourceAsStream()来加载映射文件。

    Configuration cfg = new Configuration()

                                                     .addClass(eg.Vertex.class)

                                                     .addClass(eg.Edge.class);

    调用后,Hibernate会自动在CLASSPATH中寻找名字为/eg/Vertex.hbm.xml/eg/Edge.hbm.xml的映射文件。这种方法消除了所有硬编码的文件名称。

    系统配置也可以指定若干个可选的参数。

    Properties props = new Properties();

    ……

    Configuration cfg = new Configuration()

                                                     .addClass(eg.Vertex.class)

                                                     .addClass(eg.Edge.class)

                                                     .setProperties(props);

           Configuration被设计成“配置过程”对象,一旦SessionFactory建立,配置对象就会被丢弃。

    2.2 获得SessionFactory

           当所有的映射都通过Configuration解析后,应用程序程序必须为会话实例而获得一个会话工厂。这个工厂被设计为被所有的应用线程所共享。但是,Hibernate也允许你的应用程序实例化多个SessionFactory,这种特性在你使用多个数据库时,将非常有用。

    SessionFactory sessions = cfg.buildSessionFactory();

    2.3 用户提供JDBC连接

           SessionFactory能够在用户提供的JDBC上打开一个会话。这种设计能够使应用程序自由选择其合意的JDBC连接。应用程序必须注意,不能在同一个连接上打开两个并发会话。

    java.sql.Connection conn = datasource.getConnection();

    Session sess = sessions.openSession(conn);

          

    // start a new transaction (optional)

    Transaction tx = sess.beginTransaction();

    最后一行在这里是可选的——应用程序能够选择直接利用JTAJDBC的事务来管理事务。然而,如果你使用Hibernate事务,你的客户端代码从底层实现中抽象出来。(例如:你可以在将来某个时间选择切换到CORBA事务服务,而无需改变应用代码)

    2.4 Hibernate提供JDBC连接

           另外一种选择,你能够使用SessionFactory来打开数据库连接,但是前提是必须按照下面的方法提供连接属性:

    l        传递一个java.util.Properties实例给Configuration.setProperties()

    l        hibernate.properties文件放在CLASSPATH的根目录中

    l        使用java -Dproperty=value来设置系统属性

    l        hibernate.cfg.xml文件中包含<property>元素(见下文)

    如果你设置了下面的属性,Hibernate将使用java.sql.DriverManager来获得连接(或连接池):

    hibernate.connection.driver_class = jdbc driver class

    hibernate.connection.url = jdbc url

    hibernate.connection.username = database user

    hibernate.connection.password = user password

    hibernate.connection.pool_size = maximum number of pooled connections

    hibernate.statement_cache.size=maximum number of cached PreparedStatements ( must be 0 for Interbase )

    hibernate.connection.isolation = transaction isolation level (optional)

    hibernate.connection.xxxx=pass the JDBC property xxxx to DriverManager.getConnection()

           hibernate.connection.isolation必须指定一个整数值。(查阅java.sql.Connection以获得该值的解释,但是大多数数据库都不支持所有的隔离层次)

           通过定义以“hibernate.connnection”为前缀的属性名字,可以传递任何连接属性。例如,你可以通过hibernate.connnection.charSet来指定charSet属性。

           Hibernate自己的连接池运算法则根本没有开发。C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布。如果你设置下面的属性,Hibernate将使用C3P0来提供连接池功能:

    hibernate.c3p0.max_size = maximum connection pool size

    hibernate.c3p0.min_size = minimum connection pool size

    hibernate.c3p0.timeout = maximum idle time

    hibernate.c3p0.max_statements = size of statement cache

           不过,除了上面的设置以外你仍然需要设置hibernate.connection.driver_class hibernate.connection.urlhibernate.connection.usernamehibernate.connection.password属性。

           Hibernate也内置支持Apache DBCP连接池。你需要通过设置hibernate.dbcp.*属性(DBCP连接池属性)和hibernate.dbcp.ps.*DBCP语句缓冲属性)来启用DBCPConnectionProvider。请参考Apache commons-pool的文档来获取这些属性的详细说明。所有的Hibernate属性名字都定义在net.sf.hibernate.Environment类中。

           如果用户使用内置的应用服务器,Hibernate也可以通过注册在JNDI中的javax.sql.Datasource来获得数据库连接。设置下列属性:

    hibernate.connection.datasource = datasource JNDI name

    hibernate.jndi.url = url of the JNDI provider (optional)

    hibernate.jndi.class = class of the JNDI InitialContextFactory (optional)

    hibernate.jndi.xxxx = pass the property xxxx to the JNDI InitialContextFactory (optional)

    hibernate.connection.username = database user

    hibernate.connection.password = user password

    然后,像下面一样简单地打开会话:

    Session sess = sessions.openSession(); // obtain a JDBC connection and

                                       // instantiate a new Session

    // start a new transaction (optional)

    Transaction tx = sess.beginTransaction();

    2.5 其他属性

           还有一些可选的其它属性:

          

    属性名字

    属性值

    说明

    hibernate.dialect

    full.classname.of.Dialect

    classname of a Hibernate Dialect - enables certain platform dependent features

    hibernate.default_schema

    SCHEMA_NAME

    qualify unqualified tablenames with the given schema / tablespace in generated SQL

    hibernate.session_factory_name jndi/composite/name bind this name to the SessionFactory

    hibernate.use_outer_join

    true | false

    enables outer join fetching

    hibernate.jdbc.fetch_size

    a non-zero value

    determines the JDBC fetch size ( calls Statement.setFetchSize() )

    hibernate.jdbc.batch_size

    recommended values between 5 and 30 a nonzero value

    enables use of JDBC2 batch updates by Hibernate

    hibernate.jdbc.use_scrollable_resultset

    true | false

    enables use of JDBC2 scrollable resultsets by Hibernate. This property is only necessary when using user supplied connections. Hibernate uses connection metadata otherwise.

    hibernate.jdbc.use_streams_for_binary

    true | false

    use streams when writing / reading binary or serializable types to / from JDBC

    hibernate.connection.provider_class

    full.classname.of.ConnectionProvider

    classname of a custom ConnectionProvider

    hibernate.transaction.factory_class

    full.classname.of.TransactionFactory

    classname of a TransactionFactory to use with Hibernate Transaction API

    jta.UserTransaction

    ndi/composite/name

    A JNDI name used by JTATransactionFactory to obtain the JTA UserTransaction

    hibernate.transaction.manager_lookup_class

    full.classname.of.TransactionManagerLookup

    classname of a TransactionManagerLookup - needed when JVM-level caching is enabled in a JTA environment

    hibernate.query.imports

    package.name, other.package.name

    A list of packages containing persistent classes. If the package is listed here, your Hibernate queries need not specify the full class name of a persistent class. (You can use from foo in class Foo as an alternative to from foo in class eg.foo.Foo.)

    hibernate.query.substitutions

    hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC

    mapping from tokens in Hibernate queries to SQL tokens ( tokens might be function or literal names, for example )

    hibernate.show_sql

    true | false

    write all SQL statements to console ( as an alternative to use of the logging functionality )

     

    你应该始终为了你的数据库而将hibernate.dialect属性设置为正确的net.sf.hibernate.dialect.Dialect子类。除非你想使用nativesequence生成主键或者悲观锁定(Session.lock(), Session.loadWithLock()),否则这些设置基本上讲不需要很严格。但是,如果你指定了dialectHibernate将智能地使用上述属性的默认设置。保存你手工设置的结果。

           下表列出了hibernate.dialect属性可选的值:

    DB2 net.sf.hibernate.dialect.DB2Dialect

    MySQL net.sf.hibernate.dialect.MySQLDialect

    SAP DB net.sf.hibernate.dialect.SAPDBDialect

    Oracle net.sf.hibernate.dialect.OracleDialect

    Sybase net.sf.hibernate.dialect.SybaseDialect

    Progress net.sf.hibernate.dialect.ProgressDialect

    Mckoi SQL net.sf.hibernate.dialect.McKoiDialect

    Interbase net.sf.hibernate.dialect.InterbaseDialect

    Pointbase net.sf.hibernate.dialect.PointbaseDialect

    PostgreSQL net.sf.hibernate.dialect.PostgreSQLDialect

    HypersonicSQL net.sf.hibernate.dialect.HSQLDialect

    Microsoft SQL Server net.sf.hibernate.dialect.SybaseDialect

           如果你的数据库支持ANSIOracle类型的外部连接,则它会通过限制与数据库间数据往返的次数来提高外部连接获取结果的性能(这是以数据库执行更多的工作为代价的)。使用外部连接获取的结果允许在单一的选择查询中得到多对一或一对一关系的对象图表。获取的图表在对象换页、对象代理或循环参考发生时结束。(The fetched graph ends at leaf objects, objects with proxies or where circular references occur)。这种特别的关联行为可以通过设置outer-join属性为false来禁止。

           Oracle限制了数据库与JDBC驱动程序之间传递的字节数组的大小。如果你想使用大的二进制类型或持续类型,你应该启动属性hibernate.jdbc.use_streams_for_binary。而它仅仅是一个JVM级别的设置。

           hibernate.show_sql属性强制Hibernate在控制台上显示SQL语句。这种做法提供了一种的启用日志的简单选择。

           你可以通过实现接口net.sf.hibernate.connection.ConnectionProvider来定义获取JDBC连接策略的插件。你可以设置hibernate.connection.provider_class属性来设置自定义的实现。

           如果你想使用Hibernates事务编程接口,你需要通过设置hibernate.transaction.factory_class属性来为事务实例指定工厂类。有两种标准(内建)的选择:

    net.sf.hibernate.transaction.JDBCTransactionFactory 委派给JDBC事务

    net.sf.hibernate.transaction.JTATransactionFactory 委派给JTA(如果有事务正在执行,则会话会在他的上下文中执行任务,否则将启动一个新事务)

    你还可以自定义事务。

    如果你希望使用JTA环境中易变数据缓存(JVM级别),那你就必须指定获取JTA TransactionManager的策略。

    net.sf.hibernate.transaction.JBossTransactionManagerLookup           for JBoss

    net.sf.hibernate.transaction.WeblogicTransactionManagerLookup      for Weblogic

    net.sf.hibernate.transaction.WebSphereTransactionManagerLookup for WebSphere

    net.sf.hibernate.transaction.OrionTransactionManagerLookup            for Orion

    net.sf.hibernate.transaction.ResinTransactionManagerLookup            for Resin

           如果你希望将SessionFactory绑定到JNDI的名字空间,则可以使用属性hibernate.session_factory_name,并为它指定一个名字(如:hibernate/session_factory)。例:今后EJBs就可以通过查找JNDI来获得SessionFactoryHibernate将使用hibernate.jndi.urlhibernate.jndi.class属性来建立初始的上下文环境。

           用户能够使用hibernate.query.substitutions属性定义新的Hibernate查询符号。例如:

    hibernate.query.substitutions true=1, false=0

    这在生成SQL语句时,会将“true”和“flase”符号翻译成整数字符。

    hibernate.query.substitutions toLowercase=LOWER

    该句将使你重新命名SQL语句中的lower 函数。

    2.6 XML配置文件

    还有一种配置方法,就是将所有的配置信息设置在文件hibernate.cfg.xml中。这个文件必须放在CLASSPATH的根目录中。

    <?xml version='1.0' encoding='utf-8'?>

    <!DOCTYPE hibernate-configuration PUBLIC

            "-//Hibernate/Hibernate Configuration DTD//EN"

     "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">

    <hibernate-configuration>

        <!-- a SessionFactory instance listed as /jndi/name -->

        <session-factory name="/jndi/name">

            <!-- properties -->

            <property name="connection.datasource">my/first/datasource</property>

            <property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>

            <property name="show_sql">false</property>

            <property name="use_outer_join">true</property>

            <property name="jta.UserTransaction">java:comp/UserTransaction/

            </property>

     

            <!-- mapping files -->

            <mapping resource="eg/Foo.hbm.xml"/>

            <mapping resource="eg/Bar.hbm.xml"/>

     

        </session-factory>

    </hibernate-configuration>

    可以简单地按照下面的方法配置Hibernate

    SessionFactory sf = new Configuration()

                                                     .configure()

                                                     .buildSessionFactory();

    2.7 日志

           Hibernate使用Apache commons-logging记录各种事件。commons-logging日志服务将直接输出到Apache log4(如果你将log4j.jar放置在CLASSPATH中)或JDK1.4 logging中(如果运行在JDK1.4或以上版本上)。你可以从http://jakarta.apache.org上下载log4j。为了使用log4j,你需要将log4j.properties文件放在CLASSPATH的目录中。有一个属性文件的例子随Hibernate一起发布。

     

    待续……


    最新回复(0)