亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

利用HSQLDB 進行Hibernate單元測試

2019-11-18 16:11:17
字體:
來源:轉載
供稿:網友

動機
 曾經使用許多方法在數據庫和目標代碼之間傳輸數據。從手動編碼的SQL到JDO,然后再到EJB,我從未找到一種特別喜歡的方法。自從采用測試驅動開發(TDD)作為指導原則以來,這種不滿情緒變得更加強烈。
    單元測試的障礙應盡可能少。在關系數據庫中,障礙的范圍從外部依賴(數據庫在運行嗎?)到保持關系模型和對象模型同步的速度。由于這些原因,保持數據庫訪問代碼與核心對象模型分離且無需涉及真實數據庫而進行盡可能多的測試是很重要的。
    通常這會導致我們進入下面兩種模式之一。第一種是具體化所有訪問域對象的數據以及數據與單獨類或接口之間的關系。這就是典型的能夠檢索、編輯、刪除和添加域實體的數據存儲對象。這在單元測試中是最容易模擬出來的,但趨向于把域模型對象作為不帶有任何關系行為的純數據對象。直接從父對象訪問子記錄是最理想的,而不是將父對象處理為第三方類來決定子記錄。
    其他方法已經使訪問接口的域對象進入數據映射層(一種la Martin Fowler的數據映象模式)。這具有推動域模型中的對象關系的優點,在域模型中,對象關系型接口只需表達一次即可。使用域模型的類不支持持久性機制,因為它本身內在化到域模型中。這使代碼集中在設法解決的業務問題,而很少關注對象關系型映射機制。
    我的當前項目涉及到處理大量的棒球統計數據,并使用這些數據進行模擬。因為數據已經在關系數據庫中,所以對于我來說,有機會開發Hibernate對象關系型映射系統。我曾對Hibernate有很深刻的印象,但我遇到的一個問題是,在使用Hibernate進行單元測試的數據映射時,設法插入一個間接層。該附加層非常脆弱,編寫起來感到非常困難。實際部署版本簡單地通過了特定于Hibernate的實現。更壞的情況是,模擬版本比真正的“產品級”版本更復雜,只因為模擬版本里沒有基本對象存儲器和帶有Hibernate的映射。
    我也使用很多復雜的Hibernate查詢,想要對應用程序的重要部分進行單元測試。然而,對活動的數據庫進行測試不是好主意,因為這幾乎總是產生維護問題。另外,由于測試最好互相獨立,在測試上下文數據中使用相同的主鍵意味著必須在每次測試前創建代碼來清理數據庫,當涉及到大量關系時就成為一個實際問題。
    通過使用HSQLDB和Hibernate強大的模式生成工具,能夠對應用程序映射層進行單元測試,并在對象查詢中找到不計其數的bug,這在以前手工測試時是做不到的。利用下面的技術概述,可以在開發過程中對整個應用程序進行測試,并且在測試有效區域內沒有損害。

設置HSQLDB
   
以前使用HSQLDB 1.7.3.0 版。為了使用數據庫的內存版本,需要激活org.hsqldb.jdbcDriver的靜態加載程序。當獲得JDBC連接時,就可以使用JDBC url例如jdbc:hspldb:mem:yourdb,這里’yourdb’就是想要使用的內存數據庫的名稱。
    因為使用Hibernate (3.0 beta 4),所以我幾乎無需接觸實際活動的JDBC對象。相反,我可以讓Hibernate完成很多繁重的任務,包括從Hibernate映射文件中自動創建數據庫模式。因為Hibernate創建自身專有的連接池,所以它會基于TestSchema類中的配置代碼自動加載HSQLDB JDBC驅動程序。下面就是該類的靜態的初始化程序。

public class TestSchema {    static {        Configuration config = new Configuration().            setWord", "").            setProperty("hibernate.connection.pool_size", "1").            setProperty("hibernate.connection.autocommit", "true").            setProperty("hibernate.cache.provider_class", "org.hibernate.cache.HashtableCacheProvider").            setProperty("hibernate.hbm2ddl.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.hbm2ddl.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().configure().buildSessionFactory();        }        return factory.openSession();    }    public static void setSessionFactory(SessionFactory factory) {        HibernateUtil.factory = factory;    }}



  因為所有代碼(經過單元測試的產品級代碼)都是從HibernateUtil獲取Hibernate會話,所以能在同一個位置對其進行配置。為了對代碼的第一位進行單元測試而訪問TestSchema類將會激活靜態初始化程序,該程序將安裝Hibernate并且將測試SessionFactory插入到HibernateUtil中。對于產品級代碼,可以使用標準hibernate.cfg.xml配置機制來初始化 SessionFactory。
  那么單元測試中的外部特征是什么?下面的測試代碼片段是用來檢查邏輯的,決定運動員在棒球聯盟比賽中是哪個位置的人選:

    public void testGetEligiblePositions() throws Exception {        Player player = new Player("playerId");        TestSchema.addPlayer(player);        FieldingStint stint1 = new FieldingStint("playerId", 2004, "SEA", Position.CATCHER);        stint1.setGames(20);        TestSchema.addFieldingStint(stint1);        Set<Position> positions = player.getEligiblePositions(2004);        assertEquals(1, positions.size());        assertTrue(positions.contains(Position.CATCHER));    }


  第一次創建新Player實例并通過addPlayer()方法添加到TestSchema中。必須首先完成此步驟,因為FidldStint類和Player類之間有外鍵關系。如果不首先添加該實例,在設法添加FieldingStint時將會出現外鍵約束違例。一旦測試上下文就位,就可以測試getEligiblePositions()方法來檢索校正數據。下面是在TsetSchema中addPlayer()方法的代碼。您將注意到使用Hibernate而不是bare-metal JDBC代碼:

    public static void addPlayer(Player player) {        if (player.getPlayerId() == null) {            throw new IllegalArgumentException("No primary key specified");        }        Session session = HibernateUtil.getSession();        Transaction transaction = session.beginTransaction();        try {            session.save(player, player.getPlayerId());            transaction.commit();        }        finally {            session.close();        }    }


  在單元測試中最重要的就是要保持測試實例是獨立的。因為該方法仍然涉及數據庫,所以需要一種方法在每個測試實例之前清理數據庫。在我的數據庫架構中有四個表,所以我在TestSchemaz上編寫了reset()方法,該方法從使用JDBC的表中刪除所有行。注意,因為HSQLDB能識別外鍵,刪除表的順序是很重要的,下面是代碼:

    public static void reset() throws SchemaException {        Session session = HibernateUtil.getSession();        try {            Connection connection = session.connection();            try {                Statement statement = connection.createStatement();                try {                    statement.executeUpdate("delete from Batting");                    statement.executeUpdate("delete from Fielding");                    statement.executeUpdate("delete from Pitching");                    statement.executeUpdate("delete from Player");                    connection.commit();                }                finally {                    statement.close();                }            }            catch (HibernateException e) {                connection.rollback();                throw new SchemaException(e);            }            catch (SQLException e) {                connection.rollback();                throw new SchemaException(e);            }        }        catch (SQLException e) {            throw new SchemaException(e);        }        finally {            session.close();        }    }



  當確定在Hibernate 3.0中進行大量刪除操作時,應該能從應用程序中刪除直接JDBC的最后一位。到此時為止,必須獲取數據庫連接并向數據庫直接提交SQL。 在確保沒有關閉連接的情況下,為了釋放資源,只關閉會話就足夠了。出于手工編寫許多JCBC代碼來進行開發的習慣,第一個版本關閉了JDBC連接。因為通過配置Hibernate創建的連接池只帶有一個鏈接,在第一個之后就完全破壞了測試。一定要注意這種情況! 既然在測試類運行時(設想運行所有的測試實例)不能確定數據庫的狀態,應該在setUp()方法中包含數據庫清除,如下所示:

    public void setUp() throws Exception {        TestSchema.reset();    }
結束語
  
在使用像Hibernate這種復雜的O/R映射程序時,必須能夠測試實際存在(real-live)的RDBMS,而不會發生任何針對已部署數據庫的爭論。
雖然Hibernate有內置模式生成工具,讓此類測試特別簡單,但是在這里展示的例子并不排除Hibernate,并且可能與JDO或TopLink一起運行。
使用上面描述的設置,您不必離開舒適的IDE環境,但仍然可以對代碼進行大量測試。

(出處:http://www.49028c.com)



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品www色诱视频| 国产成人精品在线播放| 91av国产在线| 国产精品老女人视频| 午夜精品在线观看| 一区二区三区日韩在线| 欧亚精品在线观看| 91最新国产视频| 神马久久桃色视频| 久久69精品久久久久久国产越南| 国产精品久久久久久久久久久久久| 亚洲性日韩精品一区二区| 欧美亚洲在线播放| 亚洲人成啪啪网站| 亚洲国产欧美在线成人app| 人妖精品videosex性欧美| 国产香蕉97碰碰久久人人| 91精品国产综合久久久久久蜜臀| 久操成人在线视频| 精品亚洲va在线va天堂资源站| 欧美日韩一区二区三区在线免费观看| 亚洲色图日韩av| 97人人模人人爽人人喊中文字| 久久91精品国产91久久跳| 亚洲国产精品久久久久秋霞蜜臀| 亚洲韩国青草视频| 日韩中文字幕在线| 欧美极品美女视频网站在线观看免费| 欧美尺度大的性做爰视频| 欧美电影免费观看网站| 一区二区国产精品视频| 久久久久久亚洲精品不卡| 亚洲免费中文字幕| 97视频国产在线| 国产狼人综合免费视频| 91精品久久久久久综合乱菊| 国产精品r级在线| 亚州精品天堂中文字幕| 91成人在线视频| 亚洲a在线观看| 精品国产老师黑色丝袜高跟鞋| 欧美日韩不卡合集视频| 欧美男插女视频| 亚洲久久久久久久久久久| 精品少妇v888av| 国产亚洲精品成人av久久ww| 欧美亚洲日本黄色| 午夜免费日韩视频| 国产精品久久久久久五月尺| 亚洲性69xxxbbb| 日韩欧美在线观看| 国产亚洲精品美女| 亚洲国产欧美在线成人app| 日韩电影在线观看免费| 日本精品久久中文字幕佐佐木| 日韩一级黄色av| 国产成人精品网站| 91精品国产高清自在线| 福利视频导航一区| 精品亚洲永久免费精品| 中文字幕综合在线| 成人亚洲综合色就1024| 欧美最猛性xxxxx免费| 成人欧美一区二区三区在线湿哒哒| 2019亚洲男人天堂| 国产精品久久在线观看| 日本精品久久久久久久| 亚洲毛茸茸少妇高潮呻吟| 亚洲嫩模很污视频| 欧美日韩中文在线| 久久精品视频亚洲| 在线观看精品国产视频| 久久99久久久久久久噜噜| 亚洲人免费视频| 国产91热爆ts人妖在线| 久久久噜噜噜久久久| 亚洲视频专区在线| 久久视频国产精品免费视频在线| 欧美色播在线播放| 亚洲r级在线观看| 亚洲欧美制服综合另类| 中国日韩欧美久久久久久久久| 97视频网站入口| 欧美猛男性生活免费| 久久综合网hezyo| 久久精品人人爽| 欧美成人午夜免费视在线看片| 亚洲天堂av高清| 91夜夜未满十八勿入爽爽影院| 久久久久久亚洲精品中文字幕| 久久久99免费视频| 久久久久久久久久久久久久久久久久av| 国产免费一区视频观看免费| 欧洲亚洲妇女av| 欧美电影免费观看大全| 欧美激情免费在线| 中文字幕亚洲精品| 国产精品精品视频一区二区三区| 欧美在线观看网址综合| 一区二区中文字幕| 国产精品视频白浆免费视频| 亚洲美女在线观看| 国产91精品久久久久| 国内精品中文字幕| 亚洲精品按摩视频| 精品久久久91| 日韩专区在线播放| 欧美精品久久久久| www.日韩av.com| 另类视频在线观看| 91国内在线视频| 亚洲a∨日韩av高清在线观看| 欧美日韩国产中文字幕| 国产丝袜精品第一页| 国产在线拍揄自揄视频不卡99| 成人精品网站在线观看| 国产精品视频导航| 久久精品99久久香蕉国产色戒| 久久亚洲影音av资源网| 久久视频精品在线| 国产精品久久久久久av福利| 91精品国产91久久久久久最新| 欧美在线免费看| 久久久久久国产精品久久| 欧美精品精品精品精品免费| 国产中文欧美精品| 国产精品网址在线| 国产丝袜一区视频在线观看| 国产精品www色诱视频| 性欧美办公室18xxxxhd| www.日韩不卡电影av| 51久久精品夜色国产麻豆| 亚洲美腿欧美激情另类| 亚洲欧美日韩网| 欧美午夜激情小视频| 成人a级免费视频| 日韩av一区在线| 91亚洲精品久久久久久久久久久久| 91久久精品视频| 亚洲精品成人久久| 久久九九有精品国产23| 精品一区二区三区四区在线| 亚洲自拍高清视频网站| 日韩中文字幕第一页| 精品丝袜一区二区三区| 日韩二区三区在线| 午夜精品久久久久久久99热| 久久久噜噜噜久久久| 亚洲伊人一本大道中文字幕| 国产区精品视频| 国产精品爽黄69| 日本精品久久久久久久| 国产精品美腿一区在线看| 亚洲欧美在线免费观看| 蜜臀久久99精品久久久久久宅男| 欧美有码在线视频| 欧美一区二区视频97| 国产精品日韩在线| 一个人看的www欧美| 国产精品欧美一区二区三区奶水| 精品久久久香蕉免费精品视频| 国产精品99久久久久久久久久久久| 国产精品狼人色视频一区| 亚洲在线第一页|