1、使用 Hibernate 操作數(shù)據(jù)庫
1-1、使用 ThreadLocal 控制 Session
應(yīng)用程序根據(jù)配置文件構(gòu)建應(yīng)用程序運行的環(huán)境,建立全局范圍內(nèi)的 SessionFactory 對象。其內(nèi)部包含了 Hibernate 運行的全部細節(jié),是產(chǎn)生 Session 的工廠,它是線程安全的,只能在系統(tǒng)啟動時實例化一次,系統(tǒng)運行期間不可修改。
Session 對象是 Hibernate 操作數(shù)據(jù)的核心,數(shù)據(jù)庫的操作、對象生命周期的管理、應(yīng)用事務(wù)的劃分,都需要在 Session 對象中完成。Session 對象不是線程安全的,如果試圖讓多個線程同時使用一個 Session 對象,將會產(chǎn)生數(shù)據(jù)混亂,造成數(shù)據(jù)庫的數(shù)據(jù)不一致。而且頻繁開關(guān) Session 是巨大的系統(tǒng)消耗。
為了安全地使用 Session 對象,需要應(yīng)用 Java 語言中的線程綁定機制--ThreadLocal,它代表一個線程的私有存取空間,能夠隔離多線程環(huán)境中的并發(fā)機制,減少 Session 對象的創(chuàng)建和銷毀次數(shù),降低系統(tǒng)資源浪費。

HibernateSessionFactory
1
public class HibernateSessionFactory
{
2

3
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
4

5
6
public static Session getSession() throws HibernateException
{
7
Session session = (Session) threadLocal.get();
8
9
if (session == null || !session.isOpen())
{
10
if (sessionFactory == null)
{
11
rebuildSessionFactory();
12
}
13
session = (sessionFactory != null) ? sessionFactory.openSession()
14
: null;
15
threadLocal.set(session);
16
}
17
18
return session;
19
}
20
21
.
22
23
public static void closeSession() throws HibernateException
{
24
Session session = (Session) threadLocal.get();
25
threadLocal.set(null);
26
27
if (session != null)
{
28
session.close();
29
}
30
}
31
32

33
34
}
1-2、建立數(shù)據(jù)庫結(jié)構(gòu)
使用 Hibernate 時,設(shè)計生成數(shù)據(jù)庫表結(jié)構(gòu)的方式分成兩種。
1、手工用 SQL 語句設(shè)計數(shù)據(jù)表結(jié)構(gòu)
2、使用 Hibernate 根據(jù)映射文件自動構(gòu)建數(shù)據(jù)庫模式
hibernate.cfg.xml:
<property name="hbm2dll.auto">creat</property>
<property name="show_sql">true</property>
log4j.properties
log4j.logger.org.hibernate.tool.hbm2dll=debug
Hibernate 自行管理的數(shù)據(jù)庫表結(jié)構(gòu):
● none:不產(chǎn)生任何動作。
● create:在應(yīng)用啟動時,自動生成數(shù)據(jù)庫表結(jié)構(gòu)并導(dǎo)入到數(shù)據(jù)庫中。
● create-drop:同 create,但在應(yīng)用關(guān)閉時,刪除已生成的數(shù)據(jù)庫表結(jié)構(gòu);此方式常在測試時使用。
● update:在應(yīng)用啟動時,檢查持久化類和映射文件的改變,更新數(shù)據(jù)庫表結(jié)構(gòu),比如:持久化類添加一個屬性后,Hibernate 能自動添加對應(yīng)字段到對應(yīng)的數(shù)據(jù)庫表中。
3、使用 Session 操作數(shù)據(jù)庫
Hibernate 能自動管理系統(tǒng)中的持久化類和數(shù)據(jù)庫模式,通過 Session 對象實現(xiàn)對象模型和關(guān)系模型的相互操作。
Session 提供數(shù)據(jù)訪問的接口:
● get():從數(shù)據(jù)庫獲取數(shù)據(jù)對象,不存在時則返回 null。
● load():從數(shù)據(jù)庫獲取數(shù)據(jù)對象,不存在時則拋出異常。
● createQuery():根據(jù)條件查詢數(shù)據(jù)對象。
● save()、update()、delete() 等方法。
2、Hibernate 基本組件接口
● Configuration(org.hibernate.cfg.Configuration)
Hibernate 應(yīng)用的入口,它使用配置文件初始化運行環(huán)境,是 SessionFactory 的工廠。通常情況下,一個應(yīng)用程序中只允許創(chuàng)建一個單例的 Configuration 實例。
● SessionFactory(org.hibernate.SessionFactory)
是一個線程安全的高速緩存,其中包含了單一數(shù)據(jù)庫和已編譯映射文件的元數(shù)據(jù),在運行環(huán)境不可改變。它是 Session 的工廠,并能從 ConnectionProvider 中獲取 JDBC 連接。它可能持有一個可選的能在進程級別或者集群級別事務(wù)間重用的數(shù)據(jù)緩存(二級緩存)。SessionFactory 從 Configuration 中獲取,在一個應(yīng)用范圍中,不允許改變。
● Session(org.hibernate.Session)
單線程的短生命周期的對象,是應(yīng)用程序和持久化存儲的一次對話。封裝了一個 JDBC 連接,也是 Transaction 的工廠。它保持一個持久化對象的強制緩存(一級緩存),用來遍歷對象圖或者根據(jù)標識符查詢對象。Session 提供了一系列方法,可以方便地實現(xiàn)對象持久化操作。
● Transcation(org.hibernate.Transcation)
可選,單線程、短生命周期的對象,應(yīng)用程序用它來表示一批任務(wù)的原子操作。是底層 JDBC,JTA 或者 CORBA 事務(wù)的抽象。一個 Session 在某些情況下可能跨越多個 Transcation 事務(wù)。
● ConnectionProvider(org.hibernate.connection.ConnectionProvider)
可選,JDBC 連接的工廠和連接池,是底層 Datasource 或 DriverManager 的抽象應(yīng)用,對應(yīng)用程序不可見。可擴展實現(xiàn)。
● TranscationFactory(org.hibernate.TranscationFactory)
可選,事務(wù)實例工廠。對應(yīng)用程序不可見??蓴U展實現(xiàn)。
在最小集合應(yīng)用框架中,應(yīng)用程序直接使用 JDBC/JTA,并自行完成事務(wù)處理。
conn = DriverManager.getConnection(xxx);
conn.setAutoCommit(false);
...
conn.commit();
3、Hibernate 生命周期
① Configuration 對象根據(jù)配置文件的設(shè)置,讀取屬性配置信息。
② Configuration 對象根據(jù)配置信息,按照映射文件、類緩存、集合緩存、監(jiān)聽器、事件的順序依次讀取并解析。
③ 通過調(diào)用 Configuration 對象構(gòu)建 SessionFactory。
④ 調(diào)用 SessionFactory 實例獲得 Session 對象。
⑤ 啟動事務(wù)。
⑥ 提交事務(wù)。
⑦ 關(guān)閉應(yīng)用(Session 和 SessionFactory)。
4、Hibernate 中對象的狀態(tài)
為了區(qū)分持久化類的實例對象,根據(jù)對象和會話的關(guān)聯(lián)狀態(tài),可以分為三種情況:
● 暫態(tài)狀態(tài)。對象剛建立,還沒有使用 Hibernate 進行保存。該對象在數(shù)據(jù)庫中沒有記錄,也不在 session 緩存中。如果該對象是自動生成主鍵,則該對象的對象標識符為空。
● 持久化對象。對象已經(jīng)通過 Hibernate 進行了持久化,數(shù)據(jù)庫中已經(jīng)存在對應(yīng)的記錄。如果該對象是自動生成主鍵,則該對象的對象標識符已被賦值。
● 托管對象。該對象是經(jīng)過 Hibernate 保存過或者從數(shù)據(jù)庫中取出的,但是與之關(guān)聯(lián)的 session 已經(jīng)被關(guān)閉。雖然它擁有對象標識符,且數(shù)據(jù)庫中存在對應(yīng)的記錄,但是已經(jīng)不再被 Hibernate 管理。
ps. [轉(zhuǎn)] PO BO VO DTO POJO DAO概念及其作用(附轉(zhuǎn)換圖)
5、對象標識符
關(guān)系數(shù)據(jù)庫表的主鍵在 Java 應(yīng)用環(huán)境中的體現(xiàn)。
5-1、關(guān)系型數(shù)據(jù)庫的主鍵生成機制
序列生成主鍵,整數(shù)
自動增長組件,整數(shù)
全局統(tǒng)一標識符 GUID(Globally Unique Identifier),字符串主鍵
5-2、Java 環(huán)境中的對象識別機制
引用比較,比地址 “==”
內(nèi)容比較,比數(shù)據(jù) equals() 方法
5-3、Hibernate 對象識別符的作用
在生成 Java 對象時,給標識屬性分配一個唯一的值,用于區(qū)分同一個類的多個不同的實例。體現(xiàn)在 Hibernate 中就是對象標識符。
5-4、Hibernate 內(nèi)置標識符生成器的使用方法
org.hibernate.id.IdentifierGenerator 接口。
ps. 映射對象標識符
5-5、使用復(fù)合主鍵時組合標識符的使用方法(常用于遺留的系統(tǒng)中)
嵌入式組合標識符/映射式組合標識符,映射多個主鍵字段和持久化類的多個屬性。
6、配置 Hibernate
6-1、配置方式
可編程還是文件配置方式
Hibernate JDBC 配置屬性
hibernate.jdbc.fatch_size:指定 JDBC 抓取數(shù)據(jù)的數(shù)量大小,非零值
hibernate.jdbc.batach_size:允許 Hibernate 使用 JDBC2 的批量更新,非零值,建議 5 到 30
hibernate.jdbc.provider_class:自定義的 ConnectionProvider 類名,用于向 Hibernate 提供 JDBC 連接
hibernate.jdbc.autocommit:確認是否開啟 JDBC 自動提交功能,默認為 false 不自動提交
6-2、方言
屏蔽底層數(shù)據(jù)庫系統(tǒng)的方言機制,方便與數(shù)據(jù)庫間遷移。
MySQL:org.hibernate.dialect.MySQLDialect
MySQL with InnoDB:org.hibernate.dialect.MySQLInnoDBDialect
MySQL with MyISAM:org.hibernate.dialect.MySQLMyISAMDialect
6-3、Hibernate 日志系統(tǒng)
使用 Log4J 作為 Hibernate 的日志系統(tǒng),需要將 Log4J 的庫文件 log4j.jar 放置到類路徑下(其發(fā)布包以包含 Log4J 的庫文件)。然后編寫日志配置文件 log4j.properties 并放到 classpath 路徑中。
Log4J 中,幾個日志輸出級別的順序是:只輸出高于或等于 設(shè)定級別 的記錄。
trace < debug < info < warn < error < fatal
在開發(fā)模式中,可以選擇 DEBUG 級別的輸出;應(yīng)用部署后,可以配置為 ERROR。

log4j.properties
1
#設(shè)置日志根級別和輸出路徑
2
log4j.rootLogger=INFO,CONSOLE,FILE
3
4
#日志輸出路徑——控制臺
5
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
6
log4j.appender.stdout.Target=System.out
7
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
8
log4j.appender.CONSOLE.layout.ConversionPattern=%d|ABSOLUTE %5p %c|1|:%L - %m%n
9
10
#日志輸出路徑——文件
11
log4j.appender.FILE=org.apache.log4j.FileAppender
12
log4j.appender.FILE.File=hibernate.log
13
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
14
log4j.appender.FILE.layout.ConversionPattern=%d|ABSOLUTE %5p %c|1|:%L - %m%n
15
16
#日志輸出級別
17
log4j.logger.org.hibernate=INFO
18
19
#日志輸出類別
20
log4j.logger.org.hibernate.hql.ast.AST=WARN
21
log4j.logger.net.sf.ehcache=INFO
22
log4j.logger.org.hibernate.SQL=DEBUG
7、Hibernate 映射類型
7-1、時間日期映射類型(內(nèi)置映射類型)
Java 語言提供了 java.util.Date 和 java.util.Calendar 兩個類實現(xiàn)時間的運算。此外,JDBC 還提供了 java.util.Date 的三個擴展類 java.sql.Timestamp、java.sql.Time 和 java.sql.Date 分別對應(yīng)標準 SQL 數(shù)據(jù)類型中的 TIMESPAME/DATETIME(時間日期)、TIME(時間)、DATE(日期)。
java.util.Date/java.sql.Date H:date SQL:DATE
java.util.Time/java.sql.Time H:time SQL:TIME
java.util.Date/java.sql.Timestamp H:timestamp SQL:TIMESTAMP/DATETIME
java.util.Calendar H:calendar SQL:TIMESTAMP/DATETIME
java.util.Calendar H:calendar_date SQL:DATE
7-2、自定義映射類型
posted on 2009-04-11 10:45
黃小二 閱讀(494)
評論(0) 編輯 收藏 所屬分類:
S/S2SH 、
J2EE 、
J2SE