本章将讲述与JPA实现框架相关的知识,主要包括常用的开源JPA实现框架Hibernate 、OpenJPA 和Toplink。JPA作为Java EE的规范,它只是提供了一种标准的API。程序员若要使用JPA,仍需要选择JPA的实现框架。通过本章的学习,读者将能够了解与不同的JPA实现框架 相关的知识,以便在实际的项目中做出合适的选择。
Hibernate是最流行的ORM框架之一,也是 最早实现JPA的规范框架之一。它被JBoss收购后,目前作为JBoss的一个开源框架,它遵循LGPL v2.1开源许可协议,官方主页是http://www.hibernate.org/。
Hibernate 3.2以及以后的版本开始支持JPA,如图14-1所示为Hibernate框架包含的所有子项目。其中,涉及JPA的子项目有三个,它们分别是:
— Hibernate Core:Hibernate框架的核心实现。
— Hibernate Annotations:支持JDK 5.0的注释。
— Hibernate EntityManager:支持JPA的实现。
图14-1 Hibernate框架
如果使用JBoss应用服务器,由于JBoss中已 经集成了Hibernate,所以不需要额外下载Hibernate类包。若在其他的环境中使用Hibernate实现,则需要下载其使用的类包。
目前最新版本为Hibernate Core 3.2.5.GA、Hibernate Annotations 3.3.0 GA和Hibernate EntityManager 3.3.1 GA。使用浏览器打开http://hibernate.org/30.html,进入到Hibernate的下载页面,如图14-2所示。
分别下载后找到hibernate3.jar、 hibernate-entitymanager.jar和hibernate-annotations.jar三个JAR包文件,这三个JAR包文件是 Hibernate 实现JPA所必需的类包。运行时还要导入运行Hibernate所依赖的第三方类库,请参阅Hibernate官方手册。
若下载了旧版本的Hibernate Core,要注意下载兼容的Hibernate EntityManager版本和Hibernate Annotations版本。如图14-3所示为Hibernate各个模块不同版本的兼容性。
图14-2 Hibernate下载页面
图14-3 Hibernate不同版本的兼容性比较
Hibernate JPA自定义配置可以通过多种方式进行配置,如下面列举的几种方法。
方法一:在 persistence.xml文件中配置,如下所示。
value="com.mysql.jdbc.Driver" /> value="jdbc:mysql://localhost:3306/jpademo" /> 其 中,“hibernate.show_sql ”为可配置的属性,Hibernate JPA还提供很多不同属性的配置。 — 方法二:通过代码,在创建EntityManagerFactory时指定,如下所示。 Map configOverrides = new HashMap(); configOverrides.put("hibernate.format_sql ", true); EntityManagerFactory programmaticEmf = Persistence.createEntityManagerFactory("jpaUnit", configOverrides); 当同时使用方法一和方法二设置时,方法二的方式为有效的配置。 — 方法三:使用Hibernate 专有的配置文件来配置,但首先要在persistence.xml文件中配置“hibernate.ejb.cfgfile”指定配置文件的位置,如下所 示。 value="com.mysql.jdbc.Driver" /> value="jdbc:mysql://localhost:3306/jpademo" /> < property name="hibernate.ejb.cfgfile" value="/com/fengmanfei/jpa/hibernate.cfg.xml"/ > 其中,“/com /fengmanfei/jpa/hibernate.cfg.xml”为Hibernate配置文件的保存位置。使用这种方式,适用于将现有 Hibernate应用移植到JPA应用中来。但要注意,方法三的优先级最低,如果与方法一和方法二冲突,则方法一或方法二中的配置有效。 方法一和方法二是JPA的标准配置,方法三是 Hibernate特有的配置。并不是所有的属性都可以通过这三种方式配置,其中一些属性必须通过方法一和方法二来配置,这些属性的详细说明如下所示。 — 属性名:hibernate.ejb.classcache. 描述:指定缓存实体对 象, 示例如下: value="read-write"/> — 属性名:hibernate.ejb.collectioncache. 描述:指定集合实体类缓存,设置同 上。 示例如下: value="read-write , RegionName "/> ★ 提示 ★ 读者若想了解更多的缓存设置,请参阅JBoss Cache的相关文档。 — 属性名:hibernate.ejb.cfgfile 描述:指定使用Hibernate配置文件中的配 置。 示例如下: < property name="hibernate.ejb.cfgfile" value="/com/fengmanfei/jpa/hibernate.cfg.xml"/ > — 属性名:hibernate.archieve.autodetection 描述:创建Entity Manager时搜索文件的类型,多个值之间用逗号分隔。 可选值: — class:.class类文件。 — hbm:Hibernate 配置文件。 默认两个都搜索。 示例如下: — 属性名:hibernate.ejb.interceptor 描述:自定义拦截器类名,拦截器必须实现了 org.hibernate.Interceptor接口,并且有无参的构造方法。 示例如下: value="com.fengmanfei.jpa.interceptor.MyInterceptor"/> — 属性名:hibernate.ejb.naming_strategy 描述:设置注释命名策略。 可选值: — EJB3NamingStrategy(默认):EJB3规范的命名实现。 — DefaultComponentSafeNamingStrategy:在默认的EJB3NamingStrategy上进行了扩展,允许在同一实体中 使用两个同类型的嵌入对象而无须额外的声明。 示例如下: value=" DefaultComponentSafeNamingStrategy "/> — 属性名:hibernate.ejb.event. 描述:配置事件监听器,其 中 表14-1 可选的监听事件类型 事 件类型 监 听器类 flush org.hibernate.ejb.event.EJB3FlushEventListener auto-flush org.hibernate.ejb.event.EJB3AutoFlushEventListener delete org.hibernate.ejb.event.EJB3DeleteEventListener flush-entity org.hibernate.ejb.event.EJB3FlushEntityEventListener merge org.hibernate.ejb.event.EJB3MergeEventListener create org.hibernate.ejb.event.EJB3PersistEventListener create-onflush org.hibernate.ejb.event.EJB3PersistOnFlushEventListener save org.hibernate.ejb.event.EJB3SaveEventListener save-update org.hibernate.ejb.event.EJB3SaveOrUpdateEventListener 续表 事 件类型 监听器类 pre-insert org.hibernate.secure.JACCPreInsertEventListener,org.hibernate.valitator.event.ValidateEventListener pre-update org.hibernate.secure.JACCPreUpdateEventListener,org.hibernate.valitator.event.ValidateEventListener pre-delete org.hibernate.secure.JACCPreDeleteEventListener pre-load org.hibernate.secure.JACCPreLoadEventListener post-delete org.hibernate.ejb.event.EJB3PostDeleteEventListener post-insert org.hibernate.ejb.event.EJB3PostInsertEventListener post-load org.hibernate.ejb.event.EJB3PostLoadEventListener post-update org.hibernate.ejb.event.EJB3PostUpdateEventListener 示例如下: 其 中,CreateListener继承org.hibernate.ejb.event.EJB3PersistEventListener类,代码如下 所示。 package com.fengmanfei.listener; import org.hibernate.HibernateException; import org.hibernate.ejb.event.EJB3PersistEventListener; import org.hibernate.event.PersistEvent; public class CreateListener extends EJB3PersistEventListener { // 覆盖父类中的方法 @Override public void onPersist(PersistEvent event) throws HibernateException { super.onPersist(event); //代码处理 } } — 属性名:hibernate.ejb.use_class_enhancer 描述:是否启用应用服务器扩展类。 可选值: — true:启用扩展类。 — false(默认):禁用扩展类。 示例如下: — 属性名:hibernate.ejb.discard_pc_on_close 描述:是否在执行clear()时脱离持久化上下 文。 可选值: — true:执行clear()时脱离持久化上下文。 — false(默认):执行clear()时不脱离持久化上下文。 示例如下: Hibernate使用Apache commons-logging来为各种事件记录日志。commons-logging将直接将日志输出到Apache Log4j(如果在类路径中包括log4j.jar)或 JDK1.4 logging (如果运行在JDK1.4或以上的环境下)。 如果使用Log4j,需要将 log4j.properties文件保存在类路径中。Hibernate根据对日志进行了详细的分类,以便能够控制日志的的输出信息,这些日志类别如表 14-2所示。 表14-2 Hibernate JPA实现日志类别 属 性名 描 述 org.hibernate.SQL 记录SQL DML语句 org.hibernate.type 记录JDBC参数 org.hibernate.tool.hbm2ddl 记录SQL DDL语句 org.hibernate.pretty 记录提交实体时,相关联的20个实体的状 态 org.hibernate.cache 记录所有二级缓存 org.hibernate.transaction 记录事务相关的操作 org.hibernate.jdbc 记录获取JDBC资源的操作 org.hibernate.hql.ast.AST 记录HQL 和SQL AST的查询语句 org.hibernate.secure 记录JAAS认证请求 org.hibernate 记录所有信息,建议在调试开发阶段设置 例如,下面为 log4j.properties配置日志的示例代码。 ### log4j基本配置 ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=hibernate.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### 设置日志级别### log4j.rootLogger=info, stdout ###输出hibernate调试过程中的错误日志 log4j.logger.org.hibernate=debug ###输出HQL查询调试日志 log4j.logger.org.hibernate.hql.ast.AST=debug ### 输出SQL语句调试日志 log4j.logger.org.hibernate.SQL=debug ### 输出 JDBC参数查询的日志 ### log4j.logger.org.hibernate.type=info ### 输出缓存日志 ### log4j.logger.org.hibernate.cache=debug ### 输出事务日志### log4j.logger.org.hibernate.transaction=debug ###输出获取JDBC资源日志### log4j.logger.org.hibernate.jdbc=debug Hibernate除了自动对Session级别的 事务进行一级缓存外,二级缓存的优化是Hibernate实现的一个亮点之一,有关二级缓存的属性如下所示。 — 属性名:hibernate.cache.provider_class 描述:二级缓存实现的类全名,所使用的缓存都需要实 现org.hibernate.cache. CacheProvider接口,Hibernate已经实现了一些缓存,开发人员可以直接配置使用,同时要启用二级缓存,配置 hibernate.cache.use_second_level_cache为true。 可选值: org.hibernate.cache.HashtableCacheProvide、 org.hibernate.cache.EhCacheProvider、org.hibernate. cache.OSCacheProvider、 org.hibernate.cache.SwarmCacheProvider和org.hibernate. cache.Tree CacheProvider等。 示例如下: value=" org.hibernate.cache.HashtableCacheProvide "/> ★ 提示 ★ 有关各种缓存实现的详细区别,读者可以参阅Hiberante Core的相关文档。 — 属性名:hibernate.cache.use_minimal_puts 描述:是否优化二级缓存来最小化读写操作,集群时的 缓存优化。 可选值: — true(默认):启用最小化读写操作。 — false:禁用最小化读写操作。 示例如下: — 属性名:hibernate.cache.use_query_cache 描述:是否缓存查询结果。 可选值: — true:缓存查询结果。 — false:不缓存查询结果。 示例如下: — 属性名:hibernate.cache.use_second_level_cache 描述:是否启用二级缓存。 可选值: — true:启用二级缓存。 — false:不使用二级缓存。 示例如下: — 属性名:hibernate.cache.query_cache_factory 描述:设置自定义的查询缓存类全名,缓存类必须实现 org.hibernate.cache.QueryCache接口。 可选值: — org.hibernate.cache.StandardQueryCache(默认)。 — 自定义缓存实现类。 示例如下: value=" com.fengmanfei.cache.MyCache”/> — 属性名:hibernate.cache.region_prefix 描述:二级缓存的前缀名称。 示例如下: — 属性名:hibernate.cache.use_structured_entries 描述:是否使用结构化的方式缓存对象。 可选值: — true:结构化方式缓存对象。 — false:不使用结构化的方式缓存对象。 示例如下: Hibernate自定义JDBC和数据库配置属性 如下所示。 — 属性名:hibernate.jdbc.fetch_size 描述:JDBC抓取记录的大小,相当于设置 Statement.setFetchSize(),默认值为25。 示例如下: — 属性名:hibernate.jdbc.batch_size 描述:JDBC2批量更新的大小,建议设置为 5~30之间的值,默认为5。 示例如下: — 属性名:hibernate.jdbc.batch_versioned_data 描述:JDBC执行批量操作时,是否同时更新版本数 据。 可选值: — true(默认):执行批量操作executeBatch()返回成功的记录数,并且更新版本数据。 — false:批量操作后不更新版本数据。 示例如下: — 属性名:hibernate.jdbc.batch_versioned_data 描述:JDBC执行批量操作时,是否同时更新版本数 据。 可选值: — true(默认):执行批量操作executeBatch()返回成功的记录数,并且更新版本数据。 — false:批量操作后不更新版本数据。 示例如下: — 属性名:hibernate.jdbc.use_scrollable_resultset 描述:是否允许Hibernate使用JDBC2的 可滚动结果集。 可选值: — true(默认):可使用可滚动结果集,只有在使用用户提供的JDBC连接时,才需要设置为启用。 — false:不可使用滚动结果集。 示例如下: — 属性名:hibernate.jdbc.use_streams_for_binary 描述:是否JDBC以二进制方式读取。 可选值: — true(默认):以二进制方式读取。 — false:以二进制方式读取,而以序列化方式读取。 示例如下: — 属性名:hibernate.jdbc.use_get_generated_keys 描述:是否使用JDBC3插入记录时使用 PreparedStatement.getGeneratedKeys()生成主键。 可选值: — true:使用PreparedStatement.getGeneratedKeys()生成主键。 — false(默认):使用Hibernate自定义的生成策略。 示例如下: — 属性名:hibernate.connection.isolation 描述:JDBC事务隔离级别,请读者查阅 java.sql.Connection文档了解各个级别的类型,例如1、2、4(默认)、8。 示例 如下: — 属性名:hibernate.connection.autocommit 描述:是否使用JDBC自动提交。 可选值: — true(默认):自动提交。 — false:不自动提交。 示例如下: — 属性名:hibernate.connection.driver_class 描述:数据连接的驱动类的全称,不同的数据库实现类 不同。 示例如下: — 属性名:hibernate.connection.url 描述:数据连接的URL。 示例如下: — 属性名:hibernate.connection.username 描述:数据连接的用户名。 示例如下: — 属性名:hibernate.connection.password 描述:数据连接的密码。 示例如下: — 属性名:hibernate.dialect 描述:指定不同的数据库,Hibernate底层会 根据不同的数据库生成的SQL进行优化,取值如表14-3所示。 表14-3 Hibernate JPA实现不同数据库相关配置的属性 属 性名 描 述 DB2 org.hibernate.dialect.DB2Dialect DB2 AS/400 org.hibernate.dialect.DB2400Dialect DB2 OS390 org.hibernate.dialect.DB2390Dialect PostgreSQL org.hibernate.dialect.PostgreSQLDialect MySQL org.hibernate.dialect.MySQLDialect MySQL InnoDB org.hibernate.dialect.MySQLInnoDBDialect MySQL with MyISAM org.hibernate.dialect.MySQLMyISAMDialect Oracle org.hibernate.dialect.OracleDialect Oracle 9i/10g org.hibernate.dialect.Oracle9Dialect Sybase org.hibernate.dialect.SybaseDialect Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect Microsoft SQL Server org.hibernate.dialect.SQLServerDialect SAP DB org.hibernate.dialect.SAPDBDialect Informix org.hibernate.dialect.InformixDialect HypersonicSQL org.hibernate.dialect.HSQLDialect 续表 属 性名 描 述 Ingres org.hibernate.dialect.IngresDialect Progress org.hibernate.dialect.ProgressDialect Mckoi SQL org.hibernate.dialect.MckoiDialect Interbase org.hibernate.dialect.InterbaseDialect Pointbase org.hibernate.dialect.PointbaseDialect 示例如下: 除了前面几节列举的配置外,Hibernate的 JPA实现还有一些常用的配置,如下所示。 — 属性名:hibernate.show_sql 描述:是否输出SQL语句。 可选值: — true(默认):输出SQL,相当于日志中设置org.hibernate.SQL的类别值为debug。 — false:不输出SQL。 示例如下: — 属性名:hibernate.format_sql 描述:是否格式化输出SQL语句。 可选值: — true(默认):格式化输出SQL。 — false:不格式化输出SQL。 示例如下: — 属性名:hibernate.use_sql_comments 描述:是否输出SQL注释。 可选值: — true(默认):输出SQL注释,有助于调试。 — false:不输出SQL注释。 示例如下: — 属性名:hibernate.generate_statistics 描述:是否收集与运行性能有关的参数。 可选值: — true(默认):收集与运行性能有关的参数。 — false:不收集与运行性能有关的参数。 示例如下: — 属性名:hibernate.hbm2ddl.auto 描述:对DDL的自动生成方式。 可选值: — create-drop:删除后重新创建。 — create:只创建新的。 — update:更新。 — validate:只进行验证。 示例如下: — 属性名:hibernate.default_schema 描述:生成的SQL默认的schema名称。 示例如下: — 属性名:hibernate.default_catalog 描述:生成的SQL默认的catalog名称。 示例如下: — 属性名:hibernate.max_fetch_depth 描述:一对一和多对一映射时,实体加载的最大深 度,0表示不抓取相关实体。建议值在0~3之间,默认为1。 示例如下: — 属性名:hibernate.default_batch_fetch_size 描述:加载相关联的实体集合时,所加载的相关实体个 数。建议使用2的倍数值,例如4、8(默认)、16。 示例如下: 大多数情况 下,Hibernate JPA中使用默认的设置就能基本满足需求,但当需求变化时,需要进行一些特殊的优化时,就可以通过自定义的一些属性来实现目标。14.1.4 基本配置
14.1.5 配置日志
14.1.6 配置缓存
14.1.7 配置JDBC和数据库
14.1.8 其他的常用配置