【简明翻译】Hibernate 5.4 Getting Started Guide 官方入门文档
前言
最近的精力主要集中在Hibernate上,在意识到Hibernate 5 的中文资料并不多的时候,我不得不把目光转向Hibernate的官方doc,学习之余简要翻一下入门文档。
原文地址:https://docs.jboss.org/hibernate/orm/5.4/quickstart/html_single/,勘误请在评论区留言
原文序
使用面向对象软件和关系型数据库可能既麻烦且耗时。开发成本往往会因数据在软件和数据库中的数据范式(paradigm)表现不一而显著地增长,Hibernate就是一种Java语言环境下的一个对象/关系映射 解决方案(ORM框架),对象/关系映射(ORM)的概念,则代指一种将数据的对象模型形式,即在软件中的表现形式,和数据模型形式,即数据库中的表现形式,这两种形式的数据相映射的技术。可以参照Wikipedia上的ORM词条以获得更详细的了解。
虽然Hibernate并不要求用户需要有非常丰富的SQL编程经验,但是对于一些概念的基本理解着实可以让你更快更全面的理解Hibernate,特别是对数据建模原理的理解就显得尤为重要,这两篇文章可以帮助你快速开始理解这些原理dataModeling101 、DataModeling(wiki)。
Hibernate负责Java class和数据库表的映射工作,同时也会处理两者间数据格式的映射。另外,它还提供了数据查询和获取功能。它可以节省开发者原本需要的手动数据处理时间(如果你使用SQL和JDBC这些原生手段的话)Hibernate的设计目标是将开发者从95%的日常持久化编程步骤中解放出来,开发者再无需手册来通过SQL和JDBC手动处理数据。同时,不像其他持久化方案,Hibernate并不会将原生SQL的优点隐藏起来,你依旧可以使用它,意味着你之前所付出的学习和相关知识依然十分有价值。
HIbernate可能不是那些以数据为中心的,重度依赖存储过程的应用的最佳解决方案。它更适合于对于数据相关的应用中间层,这种情况下,它的确可以去除掉那些针对特定数据库而写的SQL,流水化查询的数据集转译到对象表(对于编程语言而言)。
See http://hibernate.org/orm/contribute/ for information on getting involved.
本文章中涉及的项目代码可以从这里下载: hibernate-tutorials.zip
1. 获取 Hibernate
1.1. Hibernate Modules/Artifacts
Hibernate’s 的功能被分成一些不同的 modules/artifacts 用来隔离依赖关系(模块化).
- hibernate-core
-
Hibernate 核心module. 定义了ORM功能和API,还有不同的集成SPIs(方便第三方进行自定义扩展).
- hibernate-envers
-
Hibernate历史实体版本控制功能
- hibernate-spatial
-
Hibernate空间数据集和GIS(地理信息系统)数据类型支持
- hibernate-osgi
-
Hibernate对在OSGi容器中运行的支持。
- hibernate-agroal
-
Hibernate Agroal 连接池支持
- hibernate-c3p0
-
Hibernate C3P0 连接池支持
- hibernate-hikaricp
-
Hibernate HikariCP 连接池支持
- hibernate-vibur
-
Hibernate Vibur DBCP 连接池支持
- hibernate-proxool
-
Hibernate Proxool 连接池支持
- hibernate-jcache
-
Hibernate JCache 缓存支持 , 使得任何兼容的组件成为二级缓存的提供者。
- hibernate-ehcache
-
Hibernate Ehcache 缓存支持。使得Ehache成为二级缓存提供者。
1.2. 发行包下载
Hibernate发行包存放在 SourceForge File Release System, 有 TGZ 和 ZIP 两种格式,两种都包含了JAR文件、文档、源代码和其他一些东西。
你可以从这里下载:https://sourceforge.net/projects/hibernate/files/hibernate-orm/. 以下是发行包目录结构:
lib/required/目录包含hibernate-corejar包和它的依赖。所有的jar包都需要在在classpath下,不论那些功能有没有被用到。lib/envers目录包含hibernate-enversjar包和它的依赖 (先包含lib/required/和lib/jpa/).lib/spatial/目录包含hibernate-spatialjar包和它的依赖 (先包含lib/required/)lib/osgi/目录包含hibernate-osgijar包和它的依赖 (先包含lib/required/和lib/jpa/)lib/jpa-metamodel-generator/目录包含 生成Criteria API类型安全的元模型(Criteria API type-safe Metamodel)所需的jar。lib/optional/目录包含 Hibernate提供的各种连接池和第二级缓存集成所需的jar及其依赖。
1.3. Maven Repository Artifacts
Hibernate artifacts的权威仓库为the JBoss Maven repository. Hibernate artifacts会自动同步到这上面(可能会延迟发布).
负责JBoss Maven仓库的团队维护着许多包含重要信息的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 artifacts发布在org.hibernate groupId下。
2. 使用Hibernate原生 API 和 hbm.xml 映射文件
本示例位于您下载的压缩包中的basic/. |
启动 Hibernate
SessionFactory使用 Hibernate 映射文件(
hbm.xml)来提供映射信息使用Hibernate原生API
2.1. Hibernate配置文件
在本示例中, hibernate.cfg.xml 文件定义了Hibernate配置信息
connection.driver_class, connection.url, connection.username 和connection.password <property/> 元素定义了JDBC连接信息这些示例使用内置的H2 in-memory 数据库,所以所有的属性被设置成H2数据库以在内存中运行connection.pool_size 用来配置内置连接池的大小。
| 内置的Hibernate连接池并不能用于实际应用中,对比实际应用中的的连接池它缺乏一些基本功能 |
dialect元素定义了Hibernate会使用的特定SQL类型
| 绝大多数情况下, Hibernate 能够自动选择数据库的方言(dialect),当你使用多种数据库时这点尤其有用(注:3.x版本不清楚) |
hbm2ddl.auto 属性开启自动生成数据库schema,也即自动建表功能。
最后,添加映射文件到配置文件中, 位于 <mapping/> 元素中的resource 使得Hibernate会尝试去使用用java.lang.ClassLoader 在classpath下进行查找。
有许多方式可以用于启动SessionFactory,详见the Native Bootstrapping topical guide.
2.2. Java类
本示例中的实体类为示例代码中的: org.hibernate.tutorial.hbm.Event
实体类使用标准JavaBean的命名规范,包括getter/setter和私有的变量,虽然这是推荐的用法,但并不强制。
无参构造函数,同样作为JavaBean的规范,则要求必须实现,Hibernate需要通过反射机制(Java Reflection)为你创建实体类(即查询结果时),构造函数不能是私有的,同时,包可见性也要保证,这样才能通过java运行时代理机制(runtime proxy)生成以保证无需通过 字节码检测(bytecode instrumentation)进行代理。
2.3. 映射文件
本示例中的映射文件位于 org/hibernate/tutorial/hbm/Event.hbm.xml (同上文).
Hibernate 使用映射元数据来决定如何加载和存储持久化类,Hibernate 映射文件就是提供元数据的一种方式。
<class name="Event" table="EVENTS">
...
</class>
关于 <varname>class</varname> 映射元素:
name属性 (可在<hibernate-mapping/>中添加package属性来定义包名) 定义了类名table属性定义表名
到此为止,Event类和EVENTS数据库表被关联起来。
<id name="id" column="EVENT_ID">
...
</id>
Hibernate 使用 <id/> 元素来确保行唯一性。
| id元素不需要映射到表的实际主键列,但这是常规约定。在Hibernate中映射的表甚至不需要定义主键。但是,强烈建议所有schema都定义适当的参照完整性。如此一来,id和主键在整个Hibernate中可以互换使用 。 |
此处的<id/> 元素将EVENT_ID列命名为EVENTS表的主键。它还将Event类的id属性标识为包含标识符值的属性。
generator 元素通知Hibernate使用哪种策略为该实体生成主键值。本示例使用简单的递增计数。(注,在其他相关性能调优指南文章中,有提及不要使用id生成器,会那样会阻止批量插入)
<property name="date" type="timestamp" column="EVENT_DATE"/>
<property name="title"/>
这两个 <property/>元素声明了Event 类的其余两个持久属性:date 和title 。date 属性映射包括列属性,但title 不包含。在没有列属性的情况下,Hibernate默认使用属性名称作为列名称。这适用于title,但是由于date 是大多数数据库中的保留关键字,因此您需要为列名指定一个非保留字。
title映射也缺少类型属性。映射文件中声明和使用的类型既不是Java原生数据类型也不是SQL数据库类型。相反,它们是Hibernate映射类型,它们是在Java和SQL数据类型之间转换的转换器。如果未在映射中指定type属性,则Hibernate尝试自动确定正确的转换和映射类型,方法是使用Java反射来确定已声明属性的Java类型,并使用该Java类型的默认映射类型(注:如,BigInteger->Integer)。
在某些情况下,如date 属性所示,此自动检测可能未选择您期望或需要的默认值。 Hibernate无法知道类型为java.util.Date的属性是否应映射到SQL DATE,TIME或TIMESTAMP数据类型。通过将属性映射到timestamp转换器(timestamp converter)来保存完整的日期和时间信息,该转换器标识转换器类org.hibernate.type.TimestampType。
| 处理映射文件时,Hibernate使用反射来确定映射类型。此过程增加了时间和资源方面的开销。如果启动性能( startup performance)很重要,请考虑明确定义要使用的类型。 |
2.4. 示例代码
org.hibernate.tutorial.hbm.NativeApiIllustrationTest 类说明了如何使用Hibernate原生API。
| 为了易于使用,这些教程中的示例以JUnit测试的形式呈现。这种方法的优点之一是setUp() 和tearDown() 大致说明了如何在应用程序启动时创建org.hibernate.SessionFactory并在应用程序生命周期结束时将其关闭。 |
org.hibernate.SessionFactoryprotected 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实例,该实例将配置信息合并到服务(Services,有特指)的工作集中以供SessionFactory使用。在本教程中,我们在hibernate.cfg.xml中定义了所有配置信息。
使用StandardServiceRegistry我们创建org.hibernate.boot.MetadataSources,这是向Hibernate告知您的Domain模型的起点。再一次,因为我们在hibernate.cfg.xml中定义了它,所以这边没什么东西好讲的。 org.hibernate.boot.Metadata表示SessionFactory将基于的应用程序域模型的完整,部分验证的视图。
引导程序的最后一步是构建SessionFactory。 SessionFactory是一个线程安全的对象,实例化一次即可服务整个应用程序。
SessionFactory充当org.hibernate.Session实例的工厂,应将其视为“工作单元”的必然(corollary )结果。
示例 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() 首先使用save() 方法创建一些新的Event对象并将其交给Hibernate进行管理。 Hibernate现在负责为每个Event在数据库上执行INSERT。
session = sessionFactory.openSession();
session.beginTransaction();
List result = session.createQuery( "from Event" ).list();
for ( Event event : (List<Event>) result ) {
System.out.println( "Event (" + event.getDate() + ") : " + event.getTitle() );
}
session.getTransaction().commit();
session.close();
在这里,我们看到一个Hibernate查询语言(HQL)的示例,该示例通过生成适当的SELECT SQL,将其发送到数据库,并使用结果集数据填充Event对象来从数据库加载所有现有的Event对象。
2.5. 下一步!
重新配置示例以连接到您自己的持久关系数据库。
Add an association to the
Evententity to model a message thread.
3. 使用 Hibernate 原生API 和 注解式映射
本示例位于您下载的压缩包中的 annotations/. |
启动 Hibernate
SessionFactory
使用 Java注解来提供映射信息
使用Hibernate原生API
3.1. Hibernate配置文件
内容与上文的Hibernate配置文件相同,但有一个重要区别...最后的<mapping />元素使用class属性命名带注释的实体类。
3.2. 注解的Java类
本示例中的实体类是遵循JavaBean约定的org.hibernate.tutorial.annotations.Event。实际上,该类本身与实体Java类中的类相同,只不过注释用于提供元数据而不是单独的映射文件。
@Entity
@Table( name = "EVENTS" )
public class Event {
...
}
@ javax.persistence.Entity注释用于将类标记为实体。它的功能与映射文件中讨论的<class />映射元素相同。此外,@ javax.persistence.Table注释显式指定了表名。如果没有此规范,默认表名称将为EVENT。
示例8. 标记id属性
@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的增量生成策略。
public String getTitle() {
return title;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "EVENT_DATE")
public Date getDate() {
return date;
}
与映射文件中一样,日期属性需要进行特殊处理以考虑其特殊命名和SQL类型。 带有注释的映射默认情况下将实体的属性视为持久化属性(与数据库字段相同),这就是为什么我们看不到任何与title相关的映射信息的原因。
3.3. 示例代码
org.hibernate.tutorial.annotations.AnnotationsIllustrationTest本质上与示例代码中讨论的org.hibernate.tutorial.hbm.NativeApiIllustrationTest相同。
3.4. 下一步!
向事件实体添加关联以对消息线程进行建模。有关更多详细信息,请使用《用户指南》。
- 添加回调以在创建,更新或删除事件时接收通知。使用事件监听器尝试相同的操作。有关更多详细信息,请使用《用户指南》。
4. 使用 Java Persistence API (JPA)
本示例位于您下载的压缩包中的 entitymanager/. |
启动JPA EntityManagerFactory
使用 Java注解来提供映射信息
使用JPA API
4.1. persistence.xml
之前的教程使用了特定于Hibernate的hibernate.cfg.xml配置文件。但是,JPA定义了一个不同的引导过程,该过程使用其自己的名为persistence.xml的配置文件。该引导过程由JPA规范定义。在Java SE环境中,需要持久性提供程序(在这种情况下为Hibernate)通过META-INF / persistence.xml资源名称的类路径查找来定位所有JPA配置文件。
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="org.hibernate.tutorial.jpa">
...
</persistence-unit>
</persistence>
persistence.xml文件应为每个“持久性单元”提供唯一的名称。在获取javax.persistence.EntityManagerFactory引用时,应用程序使用此名称来引用配置。
Hibernate配置文件中讨论了<properties />元素中定义的设置。这里尽可能使用javax.persistence前缀的变体。请注意,其余特定于Hibernate的配置设置名称现在以hibernate前缀。
此外,<class />元素的功能与我们在Hibernate配置文件中看到的相同。
4.2. 注解的Java类
实体与上节注解的的Java类中的完全相同。
4.3. 示例代码
先前的教程使用了Hibernate原生API。本教程使用JPA API
protected void setUp() throws Exception {
sessionFactory = Persistence.createEntityManagerFactory( "org.hibernate.tutorial.jpa" );
}
再次注意,持久化单元名称是org.hibernate.tutorial.jpa,与persistence.xml相匹配。
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将此操作称为“持久化”(persistence)而不是“保存”(save)。
entityManager = sessionFactory.createEntityManager();
entityManager.getTransaction().begin();
List<Event> 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();
同样,该代码与我们在获取上文的 获取List结果集看到的非常相似。
4.4. 下一步!
开发一个EJB Session bean来研究使用容器管理的持久性上下文的含义。尝试无状态(stateless )和有状态(stateful )两种情况。
将事件监听器(listeners)与基于CDI的注入(CDI-based injection)结合使用,以开发基于JMS的事件消息中心
5. 使用 Envers
本示例位于您下载的压缩包中的 envers/. |
- 将实体注释为历史对象
配置 Envers
- 使用Envers API查看和分析历史数据
5.1. persistence.xml
这个文件在JPA 示例中已提过 persistence.xml, 而且基本是一样的
5.2. 注解的Java类
同样,该实体与上文:注释的Java类中的相同。主要区别在于添加了@ org.hibernate.envers.Audted注释,该注释告诉Envers自动跟踪对此实体的更改。
5.3. 示例代码
该代码保存了一些实体,对其中一个实体进行了更改,然后使用Envers API来查询初始修订(revision)以及更新的修订。修订是指实体的历史快照(snapshot )。
org.hibernate.envers.AuditReaderpublic 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.AuditReaderFactory获得了一个org.hibernate.envers.AuditReader,它包装了javax.persistence.EntityManager。
接下来,find 方法检索实体的特定修订版。第一次调用找到ID为2的事件的修订版本1。第二次调用找到ID为2的事件的修订版本2。
5.4.下一步!
提供自定义修订版本实体,以额外获取进行更改的人员。
写一个只取回符合条件历史数据的查询。 使用 User Guide 查看 Envers 查询如何创建。(Envers用于在自动生成记录更改信息的数据表,用于审计)
- 尝试使用具有各种关系(多对一,多对多等)的审计实体(auditing entities)。尝试查找此类实体的历史版本(修订版)并浏览对象树。
【简明翻译】Hibernate 5.4 Getting Started Guide 官方入门文档的更多相关文章
- Umbraco官方技术文档 中文翻译
Umbraco 官方技术文档中文翻译 http://blog.csdn.net/u014183619/article/details/51919973 http://www.cnblogs.com/m ...
- FMDB官方使用文档-GCD的使用-提高性能(翻译)
FMDB官方使用文档-GCD的使用-提高性能(翻译) 发布于:2013-08-19 10:01阅读数:13395 由于FMDB是建立在SQLite的之上的,所以你至少也该把这篇文章从头到尾读一遍.与此 ...
- [翻译] Autofac 入门文档
原文链接:http://docs.autofac.org/en/latest/getting-started/index.html 在程序中使用Autofac的基本模式是: 用控制反转(IoC)的思想 ...
- iOS FMDB官方使用文档 G-C-D的使用 提高性能(翻译)(转)
由于FMDB是建立在SQLite的之上的,所以你至少也该把这篇文章从头到尾读一遍.与此同时,把SQLite的文档页 http://www.sqlite.org/docs.html 加到你的书签中.自动 ...
- FMDB官方使用文档 G-C-D的使用 提高性能(翻译)
由于FMDB是建立在SQLite的之上的,所以你至少也该把这篇文章从头到尾读一遍.与此同时,把SQLite的文档页 加到你的书签中.自动引用计数(APC)还是手动内存管理呢? 两种都行,FMDB会 ...
- Hibernate配置文档详解
Hibernate配置文档有框架总部署文档hibernate.cfg.xml 和映射类的配置文档 ***.hbm.xml hibernate.cfg.xml(文件位置直接放在src源文件夹即可) (在 ...
- AVFoundation Programming Guide(官方文档翻译4)Editing - 编辑
新博客:完整版 - AVFoundation Programming Guide 分章节版:- 第1章:About AVFoundation - AVFoundation概述- 第2章:Using A ...
- LTE 测试文档(翻译)
Testing Documentation 翻译 (如有不当的地方,欢迎指正!) 1 概述 为了测试和验证 ns-3 LTE 模块,文档提供了几个 test suites (集成在 ns- ...
- 翻译qmake文档 目录
利用空闲时间把qmke的文档翻译出来,翻译水平有限,有些地方翻译的不好,请谅解, 如果您能指出来,我会很感激并在第一时候做出修改. 翻译qmake文档(一) qmake指南和概述 翻译qmake文档( ...
随机推荐
- PHPExcel数据导入(含图片)
PHPExcel是一个PHP类库,用来帮助我们简单.高效实现从Excel读取Excel的数据和导出数据到Excel. 首先下载压缩包: https://codeload.github.com/PHPO ...
- AngularJS: Error reports on $injector:modulerr
Angular JS最常见的问题是,程序启动失败,error为$injector:modulerr 错误是因为加载对应的Module失败,但很难找到需要修改的Module. 一个简单的小技巧是,不要使 ...
- LVM弹性硬盘
LVM机制的基本概念 PV(物理卷) ----由多个pe组成 VG(卷组) LV(逻辑卷) 基本命令: 如: 服务器新增一块大小为1T的SCSI的硬盘(sdb) ,创建一个名字为(ceshi)的逻辑分 ...
- [ch02-01] 线性反向传播
系列博客,原文在笔者所维护的github上:https://aka.ms/beginnerAI, 点击star加星不要吝啬,星越多笔者越努力. 2.1 线性反向传播 2.1.1 正向计算的实例 假设我 ...
- HashSet源码学习,基于HashMap实现
HashSet源码学习 一).Set集合的主要使用类 1). HashSet 基于对HashMap的封装 2). LinkedHashSet 基于对LinkedHashSet的封装 3). TreeS ...
- caffe网络在多线程中无法使用GPU的解决方案 | cpp caffe net run in multiple threads
本文首发于个人博客https://kezunlin.me/post/8d877e63/,欢迎阅读! cpp caffe net run in multiple threads Guide set_mo ...
- WebGL简易教程(十三):帧缓存对象(离屏渲染)
目录 1. 概述 2. 示例 2.1. 着色器部分 2.2. 初始化/准备工作 2.2.1. 着色器切换 2.2.2. 帧缓冲区 2.3. 绘制函数 2.3.1. 初始化顶点数组 2.3.2. 传递非 ...
- sqlserver查询(子查询,全连接,等值连接,自然连接,左右连,交集,并集,差集)
--部门表 create table dept( deptno int primary key,--部门编号 dname ),--部门名 loc )--地址 ); --雇员表 create table ...
- CCNA 之 十三 广域网概述
广域网概述 为什么需要WAN ? 分区或分支机构的员工需要与总部通信并共享数据: 组织经常需要与其他组织远距离共享信息: 经常出差的员工需要访问公司网络信息: 什么事广域网链路? 用于连接LAN的.跨 ...
- 以Python为例的Async / Await的编程基础
来源:Redislabs 作者:Loris Cro 翻译:Kevin (公众号:中间件小哥) 近年来,许多编程语言都在努力改进它们的并发原语.Go 语言有 goroutines,Ruby 有 fibe ...