<class name="Event" table="EVENTS"> ... </class>
關於 <varname>class</varname> 映射元素:
最近的精力主要集中在Hibernate上,在乎識到Hibernate 5 的中文資料並很少的時候,我不得不把目光轉向Hibernate的官方doc,學習之餘簡要翻一下入門文檔。html
原文地址:https://docs.jboss.org/hibernate/orm/5.4/quickstart/html_single/,勘誤請在評論區留言java
使用面向對象軟件和關係型數據庫可能既麻煩且耗時。開發成本每每會因數據在軟件和數據庫中的數據範式(paradigm)表現不一而顯著地增加,Hibernate就是一種Java語言環境下的一個對象/關係映射 解決方案(ORM框架),對象/關係映射(ORM)的概念,則代指一種將數據的對象模型形式,即在軟件中的表現形式,和數據模型形式,即數據庫中的表現形式,這兩種形式的數據相映射的技術。能夠參照Wikipedia上的ORM詞條以得到更詳細的瞭解。git
雖然Hibernate並不要求用戶須要有很是豐富的SQL編程經驗,可是對於一些概念的基本理解着實可讓你更快更全面的理解Hibernate,特別是對數據建模原理的理解就顯得尤其重要,這兩篇文章能夠幫助你快速開始理解這些原理dataModeling101 、DataModeling(wiki)。github
Hibernate負責Java class和數據庫表的映射工做,同時也會處理二者間數據格式的映射。另外,它還提供了數據查詢和獲取功能。它能夠節省開發者本來須要的手動數據處理時間(若是你使用SQL和JDBC這些原生手段的話)Hibernate的設計目標是將開發者從95%的平常持久化編程步驟中解放出來,開發者再無需手冊來經過SQL和JDBC手動處理數據。同時,不像其餘持久化方案,Hibernate並不會將原生SQL的優勢隱藏起來,你依舊可使用它,意味着你以前所付出的學習和相關知識依然十分有價值。數據庫
HIbernate可能不是那些以數據爲中心的,重度依賴存儲過程的應用的最佳解決方案。它更適合於對於數據相關的應用中間層,這種狀況下,它的確能夠去除掉那些針對特定數據庫而寫的SQL,流水化查詢的數據集轉譯到對象表(對於編程語言而言)。編程
See http://hibernate.org/orm/contribute/ for information on getting involved.api
本文章中涉及的項目代碼能夠從這裏下載: hibernate-tutorials.zip緩存
Hibernate’s 的功能被分紅一些不一樣的 modules/artifacts 用來隔離依賴關係(模塊化).安全
Hibernate 核心module. 定義了ORM功能和API,還有不一樣的集成SPIs(方便第三方進行自定義擴展).session
Hibernate歷史實體版本控制功能
Hibernate空間數據集和GIS(地理信息系統)數據類型支持
Hibernate對在OSGi容器中運行的支持。
Hibernate Agroal 鏈接池支持
Hibernate C3P0 鏈接池支持
Hibernate HikariCP 鏈接池支持
Hibernate Vibur DBCP 鏈接池支持
Hibernate Proxool 鏈接池支持
Hibernate JCache 緩存支持 , 使得任何兼容的組件成爲二級緩存的提供者。
Hibernate Ehcache 緩存支持。使得Ehache成爲二級緩存提供者。
1.2. 發行包下載
Hibernate發行包存放在 SourceForge File Release System, 有 TGZ
和 ZIP
兩種格式,兩種都包含了JAR文件、文檔、源代碼和其餘一些東西。
你能夠從這裏下載:https://sourceforge.net/projects/hibernate/files/hibernate-orm/. 如下是發行包目錄結構:
lib/required/
目錄包含 hibernate-core
jar包和它的依賴。全部的jar包都須要在在classpath下,不論那些功能有沒有被用到。
lib/envers
目錄包含 hibernate-envers
jar包和它的依賴 (先包含lib/required/
和 lib/jpa/
).
lib/spatial/
目錄包含 hibernate-spatial
jar包和它的依賴 (先包含 lib/required/
)
lib/osgi/
目錄包含 hibernate-osgi
jar包和它的依賴 (先包含 lib/required/
和lib/jpa/
)
lib/jpa-metamodel-generator/
目錄包含 生成Criteria API類型安全的元模型(Criteria API type-safe Metamodel)所需的jar。
lib/optional/
目錄包含 Hibernate提供的各類鏈接池和第二級緩存集成所需的jar及其依賴。
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下。
本示例位於您下載的壓縮包中的basic/ . |
啓動 Hibernate SessionFactory
使用 Hibernate 映射文件(hbm.xml
)來提供映射信息
使用Hibernate原生API
在本示例中, 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.
本示例中的實體類爲示例代碼中的: org.hibernate.tutorial.hbm.Event
實體類使用標準JavaBean的命名規範,包括getter/setter和私有的變量,雖然這是推薦的用法,但並不強制。
無參構造函數,一樣做爲JavaBean的規範,則要求必須實現,Hibernate須要經過反射機制(Java Reflection)爲你建立實體類(即查詢結果時),構造函數不能是私有的,同時,包可見性也要保證,這樣才能經過java運行時代理機制(runtime proxy)生成以保證無需經過 字節碼檢測(bytecode instrumentation)進行代理。
本示例中的映射文件位於 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)很重要,請考慮明肯定義要使用的類型。 |
org.hibernate.tutorial.hbm.NativeApiIllustrationTest
類說明了如何使用Hibernate原生API。
爲了易於使用,這些教程中的示例以JUnit測試的形式呈現。這種方法的優勢之一是setUp() 和tearDown() 大體說明了如何在應用程序啓動時建立org.hibernate.SessionFactory並在應用程序生命週期結束時將其關閉。 |
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實例,該實例將配置信息合併到服務(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對象。
從新配置示例以鏈接到您本身的持久關係數據庫。
Add an association to the Event
entity to model a message thread.
本示例位於您下載的壓縮包中的 annotations/ . |
啓動 Hibernate SessionFactory
使用 Java註解來提供映射信息
使用Hibernate原生API
內容與上文的Hibernate配置文件相同,但有一個重要區別...最後的<mapping />元素使用class屬性命名帶註釋的實體類。
本示例中的實體類是遵循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相關的映射信息的緣由。
org.hibernate.tutorial.annotations.AnnotationsIllustrationTest本質上與示例代碼中討論的org.hibernate.tutorial.hbm.NativeApiIllustrationTest相同。
3.4. 下一步!
向事件實體添加關聯以對消息線程進行建模。有關更多詳細信息,請使用《用戶指南》。
本示例位於您下載的壓縮包中的 entitymanager/ . |
啓動JPA EntityManagerFactory
使用 Java註解來提供映射信息
使用JPA API
以前的教程使用了特定於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配置文件中看到的相同。
實體與上節註解的的Java類中的徹底相同。
先前的教程使用了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結果集看到的很是類似。
開發一個EJB Session bean來研究使用容器管理的持久性上下文的含義。嘗試無狀態(stateless )和有狀態(stateful )兩種狀況。
將事件監聽器(listeners)與基於CDI的注入(CDI-based injection)結合使用,以開發基於JMS的事件消息中心
本示例位於您下載的壓縮包中的 envers/ . |
配置 Envers
這個文件在JPA 示例中已提過 persistence.xml, 並且基本是同樣的
一樣,該實體與上文:註釋的Java類中的相同。主要區別在於添加了@ org.hibernate.envers.Audted註釋,該註釋告訴Envers自動跟蹤對此實體的更改。
該代碼保存了一些實體,對其中一個實體進行了更改,而後使用Envers API來查詢初始修訂(revision)以及更新的修訂。修訂是指實體的歷史快照(snapshot )。
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.AuditReaderFactory得到了一個org.hibernate.envers.AuditReader,它包裝了javax.persistence.EntityManager。
接下來,find
方法檢索實體的特定修訂版。第一次調用找到ID爲2的事件的修訂版本1。第二次調用找到ID爲2的事件的修訂版本2。
提供自定義修訂版本實體,以額外獲取進行更改的人員。
寫一個只取回符合條件歷史數據的查詢。 使用 User Guide 查看 Envers 查詢如何建立。(Envers用於在自動生成記錄更改信息的數據表,用於審計)