動機 曾經使用許多方法在數據庫和目標代碼之間傳輸數據
從手動編碼的SQL到JDO
然後再到EJB
我從未找到一種特別喜歡的方法
自從采用測試驅動開發(TDD)作為指導原則以來
這種不滿情緒變得更加強烈
單元測試的障礙應盡可能少
在關系數據庫中
障礙的范圍從外部依賴(數據庫在運行嗎?)到保持關系模型和對象模型同步的速度
由於這些原因
保持數據庫訪問代碼與核心對象模型分離且無需涉及真實數據庫而進行盡可能多的測試是很重要的
通常這會導致我們進入下面兩種模式之一
第一種是具體化所有訪問域對象的數據以及數據與單獨類或接口之間的關系
這就是典型的能夠檢索
編輯
刪除和添加域實體的數據存儲對象
這在單元測試中是最容易模擬出來的
但趨向於把域模型對象作為不帶有任何關系行為的純數據對象
直接從父對象訪問子記錄是最理想的
而不是將父對象處理為第三方類來決定子記錄
其他方法已經使訪問接口的域對象進入數據映射層(一種la Martin Fowler的數據映象模式)
這具有推動域模型中的對象關系的優點
在域模型中
對象關系型接口只需表達一次即可
使用域模型的類不支持持久性機制
因為它本身內在化到域模型中
這使代碼集中在設法解決的業務問題
而很少關注對象關系型映射機制
我的當前項目涉及到處理大量的棒球統計數據
並使用這些數據進行模擬
因為數據已經在關系數據庫中
所以對於我來說
有機會開發Hibernate對象關系型映射系統
我曾對Hibernate有很深刻的印象
但我遇到的一個問題是
在使用Hibernate進行單元測試的數據映射時
設法插入一個間接層
該附加層非常脆弱
編寫起來感到非常困難
實際部署版本簡單地通過了特定於Hibernate的實現
更壞的情況是
模擬版本比真正的
產品級
版本更復雜
只因為模擬版本裡沒有基本對象存儲器和帶有Hibernate的映射
我也使用很多復雜的Hibernate查詢
想要對應用程序的重要部分進行單元測試
然而
對活動的數據庫進行測試不是好主意
因為這幾乎總是產生維護問題
另外
由於測試最好互相獨立
在測試上下文數據中使用相同的主鍵意味著必須在每次測試前創建代碼來清理數據庫
當涉及到大量關系時就成為一個實際問題
通過使用HSQLDB和Hibernate強大的模式生成工具
能夠對應用程序映射層進行單元測試
並在對象查詢中找到不計其數的bug
這在以前手工測試時是做不到的
利用下面的技術概述
可以在開發過程中對整個應用程序進行測試
並且在測試有效區域內沒有損害
設置HSQLDB 以前使用HSQLDB
版
為了使用數據庫的內存版本
需要激活org
hsqldb
jdbcDriver的靜態加載程序
當獲得JDBC連接時
就可以使用JDBC url例如jdbc:hspldb:mem:yourdb
這裡
yourdb
就是想要使用的內存數據庫的名稱
因為使用Hibernate (
beta
)
所以我幾乎無需接觸實際活動的JDBC對象
相反
我可以讓Hibernate完成很多繁重的任務
包括從Hibernate映射文件中自動創建數據庫模式
因為Hibernate創建自身專有的連接池
所以它會基於TestSchema類中的配置代碼自動加載HSQLDB JDBC驅動程序
下面就是該類的靜態的初始化程序
public class TestSchema {
static {
Configuration config = new Configuration()
setProperty(
hibernate
dialect
org
hibernate
dialect
HSQLDialect
)
setProperty(
nnection
driver_class
org
hsqldb
jdbcDriver
)
setProperty(
nnection
url
jdbc:hsqldb:mem:baseball
)
setProperty(
nnection
username
sa
)
setProperty(
nnection
password
)
setProperty(
nnection
pool_size
)
setProperty(
nnection
autocommit
true
)
setProperty(
hibernate
cache
provider_class
org
hibernate
cache
HashtableCacheProvider
)
setProperty(
hibernate
hbm
ddl
auto
create
drop
)
setProperty(
hibernate
show_sql
true
)
addClass(Player
class)
addClass(BattingStint
class)
addClass(FieldingStint
class)
addClass(PitchingStint
class);
HibernateUtil
setSessionFactory(config
buildSessionFactory());
}
Hibernate提供了許多不同的方式來配置該框架
包括程序方面的配置
上述代碼設置了連接池
注意
使用HSQLDB的內存數據庫需要用戶名
sa
還樣要確保指定一個空格作為口令
為了啟動Hibernate的自動模式生成功能
需設置hibernate
hbm
ddl
auto屬性為
creat
drop
實際測試 我的項目是處理將大量的棒球數據
所以我添加了四個進行映射的類(Player
PintchingStint
BattingSint和FieldStint)
最後創建Hibernate的會話工廠
並將其插入HibernateUtil類
該類只為Hibernate會話的整個應用程序提供一個訪問方法
HibernateUtil的代碼如下
import org
hibernate
*;
import org
hibernate
cfg
Configuration;
public class HibernateUtil {
private static SessionFactory factory;
public static synchronized Session getSession() {
if (factory == null) {
factory = new Configuration(nfigure()
buildSessionFactory();
}
return factory
openSession();
}
public static void setSessionFactory(SessionFactory factory) {
HibernateUtil
factory = factory;
}
}
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28592.html