目录
前言
1.获取Hibernate
1.1.Hibernate模块/工件
1.2.发行包下载
1.3.Maven仓库文物
2.教程使用本机Hibernate API和hbm.xml映射
2.1.Hibernate配置文件
2.2.实体Java类
2.3.映射文件
2.4.示例代码
2.5.往前走!
3.使用本机Hibernate API和注释映射的教程
3.1.Hibernate配置文件
3.2.带注释的实体Java类
3.3.示例代码
3.4.往前走!
4.教程使用Java持久性API(JPA)
4.1. persistence.xml
4.2.带注释的实体Java类
4.3.示例代码
4.4.往前走!
5.使用Envers的教程
5.1. persistence.xml
5.2.带注释的实体Java类
5.3.示例代码
5.4.往前走!
使用面向对象的软件和关系数据库既麻烦又费时.由于在对象中表示数据的方式与关系数据库之间的范式不匹配,开发成本要高得多。Hibernate是面向Java环境的对象/关系映射(ORM)解决方案。对象/关系映射一词是指在对象模型表示到关系数据模型表示之间映射数据的技术。看见http://en.wikipedia.org/wiki/Object-relational_mapping好的高层讨论。还有马丁·福勒的奥姆哈特文章讨论了许多不匹配问题。
虽然使用Hibernate并不需要有强大的SQL背景,但是对这些概念有一个基本的理解可以帮助您更快、更全面地理解Hibernate。对数据建模原理的理解尤为重要。双管齐下http://www.agiledata.org/essays/dataModeling101.html和http://en.wikipedia.org/wiki/Data_modeling是理解这些数据建模原则的良好起点。
Hibernate负责从Java类到数据库表的映射,以及从Java数据类型到SQL数据类型的映射。此外,它还提供数据查询和检索功能。它可以显著减少在SQL和JDBC中用于手工数据处理的开发时间。Hibernate的设计目标是通过消除使用SQL和JDBC手工构建的数据处理的需要,使开发人员摆脱95%的与数据持久性相关的常见编程任务。然而,与许多其他持久性解决方案不同,Hibernate并不对您隐藏SQL的强大功能,并保证您对关系技术和知识的投资与以往一样有效。
对于只使用存储过程在数据库中实现业务逻辑的以数据为中心的应用程序,Hibernate可能不是最好的解决方案,它对基于Java的中间层中的面向对象域模型和业务逻辑最有用。然而,Hibernate当然可以帮助您删除或封装特定于供应商的SQL代码,并简化将结果集从表格表示形式转换为对象图的常见任务。
看见http://hibernate.org/orm/contribute/关于参与的信息。
本指南中引用的教程的项目和代码可参见hibernate-tutorials.zip |
Hibernate的功能被分成许多模块/构件,用于分离依赖关系(模块化)。
Hibernate-核
主(核心)Hibernate模块。定义其ORM特性和API以及各种集成Spis。
hibernate-envers
Hibernate的历史实体版本特性
Hibernate-空间
Hibernate的空间/GIS数据类型支持
Hibernate-OSGi
Hibernate支持在OSGi容器中运行。
hibernate-agroal
集成 Agroal 连接池库进入Hibernate
Hibernate-C3P0
集成C3P0连接池库进入Hibernate
Hibernate-hikaricp
集成HikariCP连接池库进入Hibernate
hibernate-vibur
集成Vibur DBCP连接池库进入Hibernate
hibernate-proxool
集成Proxool 连接池库进入Hibernate
Hibernate-jcache
集成JCache将规范缓存到Hibernate,使任何兼容的实现都能成为二级缓存提供程序。
Hibernate-ehcache
集成Ehcache将库缓存到Hibernate作为二级缓存提供程序。
Hibernate团队提供托管在SourceForge文件发布系统上的发行包,在这两个版本中TGZ
和ZIP
格式。每个发行包含JAR
文件、文档、源代码和其他优点。
您可以从以下列表下载已选择格式的Hibernate版本https://sourceforge.net/projects/hibernate/files/hibernate-orm/。发行包的结构如下:
lib/required/
目录包含hibernate-core
JAR及其所有依赖项。不管使用Hibernate的哪些特性,所有这些JAR都必须在类路径上可用。
lib/envers
目录包含hibernate-envers
和它的所有依赖项(除了lib/required/
和lib/jpa/
).
lib/spatial/
目录包含hibernate-spatial
和它的所有依赖项(除了lib/required/
)
lib/osgi/
目录包含hibernate-osgi
和它的所有依赖项(除了lib/required/
和lib/jpa/
)
lib/jpa-metamodel-generator/
目录包含生成条件API类型安全元模型所需的JAR。
lib/optional/
目录包含Hibernate提供的各种连接池和二级缓存集成所需的JAR以及它们的依赖项。
Hibernate工件的权威存储库是JBossMaven存储库。Hibernate工件作为自动化作业的一部分与Maven Central同步(可能会出现一些小延迟)。
负责JBossMaven存储库的团队维护了一些包含重要信息的Wiki页面:
http://community.jboss.org/docs/DOC-14900-关于储存库的一般资料。
http://community.jboss.org/docs/DOC-15170-关于建立JBoss储存库以便为JBoss项目本身开展开发工作的信息。
http://community.jboss.org/docs/DOC-15169-有关设置对存储库的访问以将JBoss项目作为您自己软件的一部分的信息。
Hibernate ORM构件发布在org.hibernate
团体。
本教程位于下面的下载包中basic/ . |
目标
引导HibernateSessionFactory
使用Hibernate映射(hbm.xml
)提供映射信息的文件
使用Hibernate本机api
对于本教程,hibernate.cfg.xml
文件定义Hibernate配置信息。
connection.driver_class
, connection.url
, connection.username
和connection.password
元素定义JDBC连接信息。这些教程利用内存中的h2数据库,因此这些属性的值都是特定于在内存模式下运行h2的。connection.pool_size
用于配置Hibernate内置连接池中的连接数。
内置的Hibernate连接池绝不打算用于生产。它缺乏在生产准备好的连接池中找到的几个特性。 |
dialect
属性指定Hibernate将使用的特定SQL变量。
在大多数情况下,Hibernate能够正确地确定使用哪种方言。如果应用程序以多个数据库为目标,这尤其有用。 |
hbm2ddl.auto
属性允许直接将数据库架构自动生成到数据库中。
最后,将持久类的映射文件添加到配置中。resource
属性的
元素使Hibernate尝试使用java.lang.ClassLoader
查一下。
有许多方法和选项来引导Hibernate。SessionFactory
。有关其他详细信息,请参阅本机自举专题指南。
本教程的实体类是org.hibernate.tutorial.hbm.Event
关于实体的说明
该类为属性getter和setter方法使用标准JavaBean命名约定,以及字段的私有可见性。虽然这是推荐的设计,但不是必需的。
没有参数的构造函数,也是JavaBean约定,是所有持久类的必要条件。Hibernate需要使用Java反射为您创建对象。构造函数可以是私有的。但是,在没有字节码检测的情况下,运行时代理生成和高效的数据检索需要包或公共可见性。
本教程的映射文件是类路径资源。org/hibernate/tutorial/hbm/Event.hbm.xml
(如上文所述)。
Hibernate使用映射元数据来确定如何加载和存储持久类的对象。Hibernate映射文件是为Hibernate提供此元数据的一种选择。
例1.类映射元素
...
类映射元素的函数
name
属性(此处与package
属性的
元素)将要定义为实体的类的FQN命名为。
table
属性命名数据库表,该表包含该实体的数据。
的实例Event
类映射到EVENTS
数据库表
例2.id映射元素
...
Hibernate使用由
元素来唯一标识表中的行。
id元素不需要映射到表的实际主键列,但这是正常的约定。Hibernate中映射的表甚至不需要定义主键。但是,强烈建议所有架构都定义正确的引用完整性。因此,在Hibernate文档中,id和主键可以互换使用。 |
元素将Event_ID列命名为Events表的主键。它还标识了id
的属性Event
类作为包含标识符值的属性初始化。
generator
元素通知Hibernate使用哪种策略为该实体生成主键值。此示例使用简单的递增计数。
例3.属性映射元素
两人
元素的其余两个持久属性。Event
班级:date
和title
。date
属性映射包括column
属性,但是title
不会的。在没有column
属性时,Hibernate使用属性名作为列名。这是合适的title
但是自从date
是大多数数据库中的保留关键字,您需要为列名指定一个非保留字。
title
映射也缺乏类型属性。在映射文件中声明和使用的类型既不是Java数据类型,也不是SQL数据库类型。相反,他们是Hibernate映射类型,它们是在Java和SQL数据类型之间转换的转换器。Hibernate试图在映射中未指定类型属性时自动确定正确的转换和映射类型,方法是使用Java反射来确定声明属性的Java类型,并使用该Java类型的默认映射类型。
在某些情况下,这种自动检测可能不会选择您期望或需要的默认值,如date
财产。Hibernate无法知道类型为java.util.Date
,应该映射到sql。日期, 时间,或时间戳数据类型。保存完整的日期和时间信息,方法是将属性映射到时间戳转换器,它标识转换器类。org.hibernate.type.TimestampType
.
Hibernate在处理映射文件时使用反射确定映射类型。这个过程增加了时间和资源的开销。如果启动性能很重要,请考虑显式定义要使用的类型。 |
org.hibernate.tutorial.hbm.NativeApiIllustrationTest
类说明如何使用Hibernate本机API。
为了便于使用,这些教程中的示例作为JUnit测试提供。这种方法的一个好处是setUp 和tearDown 粗略地说明了org.hibernate.SessionFactory 在应用程序启动时创建,并在应用程序生命周期结束时关闭。 |
例4。获取org.hibernate.SessionFactory
protected void setUp() throws Exception {
// A SessionFactory is set up once for an application!
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure() // configures settings from hibernate.cfg.xml
.build();
try {
sessionFactory = new MetadataSources( registry ).buildMetadata().buildSessionFactory();
}
catch (Exception e) {
// The registry would be destroyed by the SessionFactory, but we had trouble building the SessionFactory
// so destroy it manually.
StandardServiceRegistryBuilder.destroy( registry );
}
}
setUp
方法首先构建一个org.hibernate.boot.registry.StandardServiceRegistry
实例,它将配置信息集成到一组服务中,供SessionFactory使用。在本教程中,我们定义了hibernate.cfg.xml
所以这里没什么有趣的东西。
使用StandardServiceRegistry
我们创建org.hibernate.boot.MetadataSources
这是告诉Hibernate有关域模型的起点。同样,因为我们定义了hibernate.cfg.xml
所以这里没什么有趣的东西。
org.hibernate.boot.Metadata
表示应用程序域模型的完整、部分验证的视图。SessionFactory
都是基于。
引导过程中的最后一步是构建SessionFactory
。SessionFactory
是一个线程安全对象,实例化一次以服务于整个应用程序。
SessionFactory
作为工厂org.hibernate.Session
实例,应该被认为是“工作单位”的必然结果。
例5.储蓄实体
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save( new Event( "Our very first event!", new Date() ) );
session.save( new Event( "A follow up event", new Date() ) );
session.getTransaction().commit();
session.close();
testBasicUsage()
首先创建一些新的Event
对象并将它们交给Hibernate进行管理,使用save()
方法。Hibernate现在负责执行插入在每个Event
.
例6.获取实体清单
session = sessionFactory.openSession();
session.beginTransaction();
List result = session.createQuery( "from Event" ).list();
for ( Event event : (List) result ) {
System.out.println( "Event (" + event.getDate() + ") : " + event.getTitle() );
}
session.getTransaction().commit();
session.close();
在这里,我们看到一个Hibernate查询语言(HQL)的示例来加载所有现有的Event
通过生成适当的选择,将其发送到数据库并填充Event
具有结果集数据的。
练习练习
重新配置示例以连接到您自己的持久关系数据库。
将关联添加到Event
实体来建模消息线程。
本教程位于下面的下载包中annotations/ . |
目标
引导HibernateSessionFactory
使用注释提供映射信息
使用Hibernate本机api
内容与Hibernate配置文件有一个重要的区别-…
元素的末尾使用class
属性。
本教程中的实体类是org.hibernate.tutorial.annotations.Event
它遵循JavaBean的约定。实际上,类本身与实体Java类,只是注释用于提供元数据,而不是单独的映射文件。
例7.将类标识为实体
@Entity
@Table( name = "EVENTS" )
public class Event {
...
}
@javax.persistence.Entity
注释用于将类标记为实体。它的功能与
中讨论的映射元素映射文件。此外,@javax.persistence.Table
注释显式指定表名。如果没有此规范,默认的表名将是事件.
例8.标识符属性
@Id
@GeneratedValue(generator="increment")
@GenericGenerator(name="increment", strategy = "increment")
public Long getId() {
return id;
}
@javax.persistence.Id
标记定义实体标识符的属性。
@javax.persistence.GeneratedValue
和@org.hibernate.annotations.GenericGenerator
协同工作,表明Hibernate应该使用Hibernate的increment
此实体的标识符值的生成策略。
例9.识别基本属性
public String getTitle() {
return title;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "EVENT_DATE")
public Date getDate() {
return date;
}
如映射文件,date
属性需要特殊处理来说明其特殊命名和SQL类型。
在使用注释进行映射时,默认情况下,实体的属性被认为是持久化的,这就是为什么我们没有看到任何与title
.
org.hibernate.tutorial.annotations.AnnotationsIllustrationTest
本质上与org.hibernate.tutorial.hbm.NativeApiIllustrationTest
讨论示例代码.
练习练习
将关联添加到Event
实体来建模消息线程。使用用户指南更多细节。
对象时添加回调以接收通知。Event
被创建、更新或删除。对事件侦听器也进行同样的尝试。使用用户指南更多细节。
本教程位于下面的下载包中entitymanager/ . |
目标
引导JPAEntityManagerFactory
使用注释提供映射信息
使用JPAAPI调用
前面的教程使用了Hibernate特定的hibernate.cfg.xml
配置文件然而,jpa定义了一个不同的引导过程,它使用自己的配置文件名为persistence.xml
。此引导过程由JPA规范定义。在JavaJPA SE环境中,需要持久化提供程序(在本例中为Hibernate)才能通过对™配置文件的类路径查找来定位所有JPA配置文件。META-INF/persistence.xml
资源名称。
Example 10. persistence.xml
...
persistence.xml
文件应该为每个“持久性单元”提供唯一的名称。时,应用程序使用此名称引用配置。javax.persistence.EntityManagerFactory
推荐信。
中定义的设置。
元素在Hibernate配置文件。在这里javax.persistence
-在可能的情况下使用前缀品种。请注意,其余的Hibernate特定配置设置名称现在以hibernate.
.
此外,
元素的功能与我们在Hibernate配置文件.
该实体与带注释的实体Java类.
前面的教程使用了Hibernate本地API。本教程使用JPAAPI。
Example 11. Obtaining the javax.persistence.EntityManagerFactory
protected void setUp() throws Exception {
sessionFactory = Persistence.createEntityManagerFactory( "org.hibernate.tutorial.jpa" );
}
再次注意,持久性单元名称是org.hibernate.tutorial.jpa
,匹配persistence.xml.
例12.保存(持久化)实体
EntityManager entityManager = sessionFactory.createEntityManager();
entityManager.getTransaction().begin();
entityManager.persist( new Event( "Our very first event!", new Date() ) );
entityManager.persist( new Event( "A follow up event", new Date() ) );
entityManager.getTransaction().commit();
entityManager.close();
代码类似于储蓄实体。 javax.persistence.EntityManager
接口,而不是使用org.hibernate.Session
接口。JPA称此操作为“持久化”,而不是“保存”。
例13.获取实体清单
entityManager = sessionFactory.createEntityManager();
entityManager.getTransaction().begin();
List result = entityManager.createQuery( "from Event", Event.class ).getResultList();
for ( Event event : result ) {
System.out.println( "Event (" + event.getDate() + ") : " + event.getTitle() );
}
entityManager.getTransaction().commit();
entityManager.close();
同样,代码与我们所看到的非常相似。获取实体清单.
练习练习
开发EJB会话bean,以研究使用容器管理的持久性上下文的含义。尝试无状态和有状态用例。
使用侦听器与基于cdi的注入一起开发基于JMS的事件消息中心。
本教程位于下面的下载包中envers/ . |
目标
将实体注释为历史
配置envers
使用enversapi查看和分析历史数据。
此文件在jpa教程中进行了讨论。persistence.xml在这里基本上是一样的。
同样,该实体在很大程度上与带注释的实体Java类。主要区别在于添加了@org.hibernate.envers.Audited
注释,它告诉envers自动跟踪对该实体的更改。
代码保存一些实体,对其中一个实体进行更改,然后使用enversAPI来撤回初始修订以及更新的修订。修订是指实体的历史快照。
例14。使用org.hibernate.envers.AuditReader
public void testBasicUsage() {
...
AuditReader reader = AuditReaderFactory.get( entityManager );
Event firstRevision = reader.find( Event.class, 2L, 1 );
...
Event secondRevision = reader.find( Event.class, 2L, 2 );
...
}
我们看到org.hibernate.envers.AuditReader
从org.hibernate.envers.AuditReaderFactory
它封装了javax.persistence.EntityManager
.
接下来,find
方法检索实体的特定修订。第一个电话是用id 2查找事件的修改号1。第二个电话说要用id 2查找事件的修改号2。
练习练习
提供一个自定义修订实体,以另外捕获做出更改的人。
编写一个只检索满足某些条件的历史数据的查询。使用用户指南若要查看Envers查询是如何构造的,请执行以下操作。
对具有不同关系形式(多对一、多对多等)的审计实体进行实验。尝试检索此类实体的历史版本(修订)并导航对象树。
翻译自:http://docs.jboss.org/hibernate/orm/5.3/quickstart/html_single/