Hibernate-ORM框架基礎(chǔ)

對象保存在內(nèi)存中,內(nèi)存不能永久保存數(shù)據(jù)翻屈,如果要永久保存就需要對象持久化(將對象存儲到數(shù)據(jù)庫中).
關(guān)系型數(shù)據(jù)庫存放關(guān)系型數(shù)據(jù)陈哑,它是非面向?qū)ο蟮模瑢ο蠛完P(guān)系數(shù)據(jù)都是業(yè)務(wù)實體的兩種表現(xiàn)形式伸眶,業(yè)務(wù)實體在內(nèi)存中表現(xiàn)為對象惊窖,在數(shù)據(jù)庫中表現(xiàn)為關(guān)系數(shù)據(jù).
內(nèi)存中的對象之間存在關(guān)聯(lián)和繼承關(guān)系,而在數(shù)據(jù)庫中厘贼,關(guān)系數(shù)據(jù)無法直接表達多對多關(guān)聯(lián),繼承關(guān)系等
因此界酒,把對象持久化到關(guān)系數(shù)據(jù)庫中,需要進行對象-關(guān)系的映射(Object Relation Mapping)即ORM

持久化為什么不使用JDBC嘴秸?

  • JDBC是java中最原始和最直接的訪問關(guān)系型數(shù)卡的方式
  • JDBC優(yōu)點是運行效率高
  • JDBC缺點是java程序中嵌入大量sql語句,使得項目難以維護
  • 如果關(guān)系型數(shù)據(jù)庫關(guān)系很復雜毁欣,業(yè)務(wù)邏輯很混亂,那么使用JDBC編程實現(xiàn)持久化需要更專業(yè)的知識(比如:緩存機制岳掐,日志等)

hibernate API分類

  • 提供訪問數(shù)據(jù)庫(增刪改查)的接口( Session, Transaction, Query )
  • 配置Hibernate接口:Configuration
  • 使應(yīng)用程序攔截Hibernate內(nèi)部發(fā)生的事情凭疮,不做出反應(yīng),這些接口包括:Interceptor, LoadEventListener, SaveEventListener等
  • 擴展Hibernate功能的接口串述,UserType, CompositeUserType, IndentiFierGenerator等执解,如有需要應(yīng)用程序可以擴展這些接口;
  • hibernate內(nèi)部封裝了JDBC, JTA, JNDI, 其中JTA和JNDI使hibernate能夠和JavaEE應(yīng)用服務(wù)器集成纲酗;

hibernate核心接口

  • Configuration接口:
    Configuration對象用于配置, 啟動hibernate 材鹦,
    hibernatey應(yīng)用通過Configuration對象獲取對象-關(guān)系映射文件中元數(shù)據(jù)庫逝淹,以及動態(tài)配置hibernate屬性;創(chuàng)建SessionFactory對象
  • SessionFactory接口 :
    • 初始化Hibernate, 創(chuàng)建Session對象
    • 是線程安全的桶唐,意味著同一個實例可以被多個線程共享;
    • 重量級的茉兰,不能隨意創(chuàng)建和銷毀他的實例尤泽,如果應(yīng)用只訪問一個數(shù)據(jù)庫,只需要創(chuàng)建一個SessionFactorys實例规脸;
  • 如果同時訪問多個數(shù)據(jù)庫坯约,則需要為每個數(shù)據(jù)庫創(chuàng)建單獨的一個SessionFactorys實例.
  • SessionFactory之所以是重量級別的,是因為它需要一個較大的緩存莫鸭,用來存放預定義的sql語句以及映射元數(shù)據(jù)等.我們還可以為SessionFactory配置一個緩存插件闹丐,該插件叫做Hibernate的第二級緩存,該緩存用來存放被工作單元讀過的數(shù)據(jù)被因,將來其他工作單元可能會重用這些數(shù)據(jù)卿拴,因此這個緩存中的數(shù)據(jù)可以被所有工作單元共享,一個工作單元通常對應(yīng)一個數(shù)據(jù)庫事務(wù)梨与;
  • Session接口:
  • 負責增堕花,刪,改粥鞋,加載/查對象
  • 也稱為持久化管理器
  • 和HttpSession沒有任何關(guān)系
  • 不是線程安全的缘挽,因此在使用過程中應(yīng)避免多個線程共享同一個session實例
  • 輕量級的,創(chuàng)建和銷毀不會銷毀太多資源呻粹,意味著程序中可以經(jīng)常創(chuàng)建和銷毀Session實例壕曼;
  • Session有一個緩存,被稱為Hibernate的第一級緩存等浊,存放的是當前工作單元加載的對象腮郊,每個Session實例都有自己的緩存,該緩存只能被當前工作單元訪問凿掂;
  • Transaction接口:管理事務(wù)
  • Query和Cirteria接口:
  • 執(zhí)行復雜數(shù)據(jù)庫查詢伴榔;
  • Query包裝了HQL查詢語句,與Sql相似庄萎,但是HQL查詢是面向?qū)ο蟮淖偕伲妙惷约皩倜皇潜砻妥侄蚊?/li>
  • Criteria接口封裝了基于字符串的查詢語句糠涛,比query接口更加面向?qū)ο笤荩珻riteria接口擅長進行動態(tài)查詢;
Paste_Image.png

事務(wù)處理接口

當程序通過Hibernate來加載忍捡,保存集漾,更新切黔,刪除對象時,會觸發(fā)Hibernate攔截器以及事件監(jiān)聽器做處理具篇;

映射類型接口

org.hibernate.type.Type接口表示將域?qū)ο髷?shù)據(jù)類型映射為數(shù)據(jù)庫的關(guān)系數(shù)據(jù)纬霞,Hiberate為Type實現(xiàn)了各種實現(xiàn)類,比如:InterType, FloatType等

可擴展的接口

Paste_Image.png

一.hibernate功能

  • hibernate是開源的
  • ORM映射
  • 是java領(lǐng)域的一款開源的ORM框架技術(shù)
  • 對JDBC進行了非常輕量級的對象封裝
  • 是業(yè)務(wù)邏輯和數(shù)據(jù)庫中間的持久化層( 中間件 )
  • 數(shù)據(jù)查詢和緩存
  • 可以應(yīng)用在獨立的java程序和web應(yīng)用中驱显;
  • 可以和多種Web服務(wù)器诗芜,應(yīng)用服務(wù)器良好集成
  • 支持幾乎所有流行的數(shù)據(jù)庫


    Paste_Image.png
  • 點擊查看練習代碼

二.開發(fā)工具介紹以及安裝

開發(fā)工具:Eclipse Standarg Kepler
Hibernate Tools for Eclipse Plugins
Hibernate Tools是JBoss公司推出的一個Eclipse綜合開發(fā)工具插件,該插件可以簡化ORM框架Hibernage, 以及JBoss Seam, EJB3等的開發(fā)工作,所以在Eclipse中安裝Hibernate Tools之前要先確認Eclipse版本埃疫,在找對應(yīng)的Hibernate Tools版本伏恐,我的eclipse版本是Eclipse Mars 4.5.2,以下是具體Hibernage Tools安裝步驟,
參考文章

  • 點擊Eclipse -> Help -> Eclipse Marketplace


    Paste_Image.png
  • 在Find中輸入Hibernate找到JBoos Tools栓霜,選中下一步后只把Hibernate Tools選中翠桦,然后安裝,

  • 安裝完畢后重啟Eclipse胳蛮,選擇File->new->輸入Hibernate销凑,以下圖片代表安裝成功


    Paste_Image.png

三.開發(fā)前準備

  • 導入Hibernate jar包
  • 首先要知道自己的Hibernate版本,我在eclipse目錄下的plugins中找到的hiberate版本為org.hibernate.eclipse.console_5.0.1.Final-v20160331-1852-B88我的理解為5.0.1.Final鹰霍,可以 點擊下載
  • 下載后將hibernate-release-5.0.1.Final.zip解壓闻鉴,hibernate-release-5.0.1.Final/lib/required目錄下就是我們要的Hibernate的jar包
  • 在eclipse中點擊window -> Preferences-> java -> Build Path -> User Liberies -> New,輸入hibernate-core(新建hibernate類庫)確定.
  • 然后導入外部jar包茂洒,點擊Add External Jars孟岛,找到hibernate-release-5.0.1.Final/lib/required下的所有jar包并導入
  • 導入junit4 jar包
  • 點擊下載
  • 下載的包是junit-4.10.jar
  • 下載后,在eclipse中新建junit4類庫督勺,方式參考以上方式(區(qū)別就是junit只有一個jar包)
  • 導入mysql-connector-java-5.1.38.jar
    在eclipse中新建mysql-jdbc類庫方式參考以上方式.

  • 在工程中導入我們以上創(chuàng)建的三個類庫

  • 創(chuàng)建java project名為 hibernate-1
  • hibernate-1 右鍵 -> properties -> java Build Path -> Libraries -> Add Library -> User Library 將剛剛創(chuàng)建的三個類庫選中渠羞,點擊Finsh就可以成功導入了.
  • 導入工程成功的樣子


    Paste_Image.png

四.創(chuàng)建第一個Hibernate

  • 創(chuàng)建hibernate配置文檔
    src-> New -> other -> Hibernate -> cfg.xml


    Paste_Image.png
  • 創(chuàng)建持久化類( 實體類 )Students
    javaBeans類創(chuàng)建原則:

    • 類必須是公有的
    • 提供公有的不帶參數(shù)的默認的構(gòu)造方法
    • 屬性私有
    • 屬性setter/getter封裝
  • 創(chuàng)建關(guān)系對象映射文件(該文件是做數(shù)據(jù)庫字段和實體類屬性映射所用)
    src-> New -> other -> Hibernate -> hbm.xml


    Paste_Image.png

    點擊下一步找到我們剛才建立的實體類(Student)


    Paste_Image.png

    最后Finsh完成;
  • 使用junit單元測試
    注解小執(zhí)行方法的順序為:

    • 1.@Before: 初始化方法
    • 2.@Test : 測試方法
    • 3.@After : 釋放資源
      建立測試項目:在Hibernate-1項目名右擊 -> New -> Source Folder ->輸入Test,在該目錄下創(chuàng)建StudentsTest類:
package firstTest;
import java.util.Date;
import javax.print.attribute.standard.MediaPrintableArea;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import entity.Students;

/**
 * 測試類
 * @author lxf
 *
 */

public class StudentsTest {
    private SessionFactory sessionFactory;
    private Session session;
    private Transaction transaction;
    @Before
    //初始化配置
    public void init()
    {
        /*
         * 注意:我的hibernate是5.0和慕課網(wǎng)上講的Hibernate4.2.4(就是4.0)兩個版本的配置方法不一樣
         */     
        //創(chuàng)建服務(wù)注冊對象
        //如果.cfg.xml取了其他的名字智哀,要改為.configure("名字.cfg.xml")
        StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
        //創(chuàng)建會話工廠對象
         sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();       
         //創(chuàng)建會話對象
         session = sessionFactory.openSession();
        //開啟事務(wù)
         transaction = session.beginTransaction();      
    }
    
    @Test
    //真實的單元測試
    public void testSaveStudent()
    {
        Students st = new Students(1,"張三豐", "nan", new Date(), "wds");
        //保存對象進入數(shù)據(jù)庫
        session.save(st);   
    }
    
    @After
    //釋放資源
    public void destroy()
    {
        //提交事務(wù)
        transaction.commit();
        //關(guān)閉會話
        session.close();
        //關(guān)閉會話工廠
        sessionFactory.close(); 
    }
}

在StudentsTest.java右鍵Run as -> Junit Test執(zhí)行次询,程序執(zhí)行testSaveStudent羅輯,判斷數(shù)據(jù)庫hibernate中是否有students表瓷叫,如果有則刪除屯吊,沒有則創(chuàng)建,然后將new Students(1,"張三豐", "nan", new Date(), "wds");對象屬性insert到數(shù)據(jù)庫的字段中摹菠;

五.Hibernate常用配置

  • hibernate.cfg.xml常用配置


    Paste_Image.png
  • Hibernate執(zhí)行流程


    Paste_Image.png
  • transaction簡介

  • hibernate對數(shù)據(jù)庫的操作都是封裝在事務(wù)中盒卸,并且默認是非自動提交的方式,所以用session保存對象時次氨,如果不開啟事務(wù)蔽介,并且手工提交事務(wù),對象并不會真正保存到數(shù)據(jù)庫中;
  • 如果想讓hibernate自動提交事務(wù)虹蓄,必須調(diào)用session.doWork()方法獲取jdbc的connection后犀呼,設(shè)置為自動提交,(不推薦使用
    @Test
    //真實的單元測試
    public void testSaveStudent()
    {
        Students st = new Students(1,"張三豐", "nan", new Date(), "wds");
        session.doWork(new Work(){
            @Override
            public void execute(Connection connection) throws SQLException {
                // TODO Auto-generated method stub
                //開啟關(guān)系型數(shù)據(jù)庫的自動提交
                connection.setAutoCommit(true);
            }   
        });
        //保存對象進入數(shù)據(jù)庫
        session.save(st);   
        session.flush();
    }
  • session簡介
  • Hibernate是對JDBC的一個封裝薇组,所以不建議使用jdbc的connection操作數(shù)據(jù)庫外臂,而是通過使用session操作數(shù)據(jù)庫;
  • 可以session就是操作數(shù)據(jù)庫的對象
  • session與connection是多對一的關(guān)系体箕,每個session都有一個與之對應(yīng)的connection, 一個connection不同時刻可以提供多個session使用专钉;
  • 所以想把對象保存在關(guān)系型數(shù)據(jù)庫中需要調(diào)用session的各種方法,如:save(), update(), delete(), createQuery()等等累铅;
  • 如果獲取session對象的兩種方式

    • (1). sessionFactory.openSession()
    • (2). sessionFactory.getCurrentSession()


      Paste_Image.png
  • openSession 和getCurrentSession區(qū)別

  • openSession每次創(chuàng)建新的session對象, 而getCurrentSession使用現(xiàn)有的session對象(單例模式)
  • getCurrentSession對象在事務(wù)提交或回滾后自動關(guān)閉,而openSession需要手動關(guān)閉站叼,(如果使用openSession沒有手動關(guān)閉娃兽,則會導致連接池溢出)
  • 對象關(guān)系配置文檔hbm常用配置
    參考文章

  • 單表映射

  • 基本類型


    Paste_Image.png
  • 日期類型


    Paste_Image.png
  • 對象類型


    Paste_Image.png
  • 組件屬性


    Paste_Image.png
  • 單表CURD操作
  • 獲取單條數(shù)據(jù)有session.get()和session.load()
  • get和load區(qū)別是:
    (1) 在不考慮緩存的情況下,get方法會在調(diào)用之后立刻向數(shù)據(jù)庫發(fā)出sql語句尽楔,返回持久化對象投储;
    (2)而load方法會在調(diào)用后返回一個代理對象,該代理對象只保存實體對象的id阔馋,直到使用對象的非主鍵屬性時菜會發(fā)出sql語句查詢數(shù)據(jù)庫玛荞;
    (3)查詢數(shù)據(jù)庫中不存在的數(shù)據(jù)庫時,get方法返回null呕寝,而load方法則會拋出異常:org.hibernate.ObjectNotFoundException
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勋眯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子下梢,更是在濱河造成了極大的恐慌客蹋,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孽江,死亡現(xiàn)場離奇詭異讶坯,居然都是意外死亡,警方通過查閱死者的電腦和手機岗屏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門辆琅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人这刷,你說我怎么就攤上這事婉烟。” “怎么了崭歧?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵隅很,是天一觀的道長。 經(jīng)常有香客問我,道長叔营,這世上最難降的妖魔是什么屋彪? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮绒尊,結(jié)果婚禮上畜挥,老公的妹妹穿的比我還像新娘。我一直安慰自己婴谱,他們只是感情好蟹但,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谭羔,像睡著了一般华糖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瘟裸,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天客叉,我揣著相機與錄音,去河邊找鬼话告。 笑死兼搏,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的沙郭。 我是一名探鬼主播佛呻,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼病线!你這毒婦竟也來了吓著?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤氧苍,失蹤者是張志新(化名)和其女友劉穎夜矗,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體让虐,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡紊撕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赡突。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片对扶。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖惭缰,靈堂內(nèi)的尸體忽然破棺而出浪南,到底是詐尸還是另有隱情,我是刑警寧澤漱受,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布络凿,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏絮记。R本人自食惡果不足惜摔踱,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怨愤。 院中可真熱鬧派敷,春花似錦、人聲如沸撰洗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽差导。三九已至试躏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間设褐,已是汗流浹背冗酿。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留络断,地道東北人。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓项玛,卻偏偏與公主長得像貌笨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子襟沮,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法锥惋,類相關(guān)的語法,內(nèi)部類的語法开伏,繼承相關(guān)的語法膀跌,異常的語法,線程的語...
    子非魚_t_閱讀 31,633評論 18 399
  • Hibernate中配置主要分為兩種:一種包含了Hibernate與數(shù)據(jù)庫的基本連接信息固灵,在Hibernate工作...
    FTOLsXD閱讀 2,045評論 0 10
  • Hibernate: 一個持久化框架 一個ORM框架 加載:根據(jù)特定的OID,把一個對象從數(shù)據(jù)庫加載到內(nèi)存中OID...
    JHMichael閱讀 1,972評論 0 27
  • 我回望捅伤、懷緬 嘗過世間酸甜苦辣 我漫步、嬉戲 不問紛亂世事 未來還有多久 流年就有多長 給心找個棲息的地方 將青春...
    阿木普拉梅閱讀 79評論 0 2
  • 使用方法http://www.reibang.com/p/1e402922ee32/ 顏色http://blog....
    puppyb2m閱讀 338評論 0 0