5.Hibernate

說起hibernate,肯定很多人一肚子苦水谷婆,也肯定很多人滿口稱贊,說大幅提高開發(fā)效率辽聊。

Hibernate是個讓人愛又讓人恨的東西波材。當時Hibernate的創(chuàng)造者的想法非常好,就是利用這個框架來屏蔽數(shù)據(jù)庫的差異身隐,做到無論是mysql、oracle唯灵、sqlserver還是其他贾铝,對開發(fā)都不影響,開發(fā)者只關注業(yè)務處理埠帕。

三種狀態(tài)垢揩,臨時、持久敛瓷、游離

學Hibernate第一個要了解的概念就是Hibernate對象的三種狀態(tài)叁巨。確實非常難以理解,我學了好多年呐籽,也是近些年才慢慢理解的锋勺。我是06年就開始學習Hibernate的蚀瘸,當時是2.0版本,教材是上海交大孫衛(wèi)琴的精通Hibernate庶橱。記憶尤深贮勃,主要是這本書看了好多好多遍,講的太高深苦澀了苏章。
我說一下我對這個狀態(tài)的理解:

  • 臨時:Person person=new Person()寂嘉,這個person就是臨時狀態(tài),跟數(shù)據(jù)庫無關的枫绅,如果線程結束泉孩,對象被垃圾回收,這個對象也就不存在了并淋。
  • 持久:這個好理解寓搬,就是數(shù)據(jù)庫里也有對應的記錄,比如Person person=session.load(1);
  • 游離:這個比較難理解预伺,舉個例子订咸,比如新增person,執(zhí)行完session.save(person);然后還沒有提交數(shù)據(jù)庫酬诀,這個狀態(tài)就是游離狀態(tài)脏嚷,還沒有完全持久化,不過person這個對象已經(jīng)有對應的id主鍵了瞒御。如果繼續(xù)執(zhí)行session.commit();父叙,那這個對象就變?yōu)槌志没恕?/li>

確實好難理解,說著說著我就暈了肴裙。不過沒關系趾唱,真到用起來,碰到問題自然而然就理解了蜻懦。

對象關聯(lián)關系

對象的關聯(lián)關系有1對1甜癞,1對多,多對1宛乃,多對多悠咱,還分有中間表關聯(lián),沒有中間表關聯(lián)等等多種情況征炼∥黾龋基本一本Hibernate的教程至少三分之一是講這些內容。確實很高深谆奥,以純面向對象的理念來開發(fā)數(shù)據(jù)庫編程眼坏。
不過多數(shù)開發(fā)人員搞不清這些關聯(lián)關系,完全對照著數(shù)據(jù)庫表結構建對象酸些。Hibernate設計之初宰译,是先設計領域模型檐蚜,然后根據(jù)領域模型的關系進行反向工程,推出數(shù)據(jù)庫設計囤屹。咱們一般是不相信Hibernate的領域模型的熬甚,或者不相信自己的設計能力,更相信數(shù)據(jù)庫的設計能力肋坚,都是先建表乡括,然后倒推領域模型,最終出的結果就是四不像了智厌。而且myeclipse工具幫了倒忙诲泌,算是Hibernate的神助攻,推出數(shù)據(jù)庫的反向工具铣鹏。
還有一個問題敷扫,多數(shù)項目都會遇到這個問題,為了簡化開發(fā)诚卸,各個對象的關聯(lián)關系都取消了葵第,只是簡單利用Hibernate 的增刪改的簡化方法,核心的查詢反而沒用到合溺。我曾經(jīng)問很多人卒密,項目用到Hibernate了,好處在哪棠赛?僅僅一句話哮奇,不用寫增刪改sql了。這其實會暴露更多的問題睛约,比如update非全字段鼎俘,僅僅幾個字段怎么處理?Hibernate的好處一點沒用到辩涝,反而額外增加了開發(fā)難度贸伐。

Hibernate調優(yōu)

這基本是所有開發(fā)人員后期面對的一個問題,Hibernate性能有問題怔揩,遇到數(shù)據(jù)量大的表棍丐,查詢有問題,或復雜查詢寫不了沧踏,還得依賴原生sql來完成,比如group by巾钉、left join等等翘狱。所以本該數(shù)據(jù)庫要做的事情,拿到程序里來寫了砰苍,而且寫完讓人看不懂潦匈,確實難懂阱高,因為Hibernate會根據(jù)對象映射關系生成自己的sql,全是別名茬缩,很難理解赤惊。

Hibernate的學習曲線

Hibernate的學習非常高,可以毫不夸張的講凰锡,沒幾個月的時間很難深入理解未舟。但是還有很多項目用這個,原因就是如果業(yè)務邏輯不復雜的話掂为,可以快速開發(fā)裕膀,增刪改查基本都不用寫代碼。我以前做過一個項目勇哗,dao層用的泛型dao昼扛,service層用的泛型service,Controller層用的泛型Controller欲诺,全基于接口編程抄谐,只要建好各個類名,一句話都不用寫扰法,整個功能就完成了蛹含,包括增刪改、分頁迹恐、取單條記錄等等挣惰,超級牛逼啊。這不就實現(xiàn)了無招勝有招嗎殴边,一句代碼不寫憎茂,功能全部完成,而且還不可能出錯锤岸。反過來講竖幔,如果要改一個邏輯,肯定蒙圈是偷,沒代碼改什么叭狻!

說了很多蛋铆,下面還是得寫個例子來講解一下什么是Hibernate的馋评。

pom.xml添加依賴

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.18</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.6.10.Final</version>
        </dependency>
        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.12.1.GA</version>
        </dependency>

這里版本用的比較老,我也沒辦法刺啦,因為Hibernate變化太快留特,現(xiàn)在都是5點幾版本了,我是好幾年沒用,跟不上時代了蜕青,不過沒關系苟蹈,原理都沒變。
這里強調一下右核,Hibernate3.6以后持久化是基于Hibernate-jpa-2.0,這個東西和WebLogic自帶的有沖突慧脱,強烈建議如果選用Hibernate,一定要先在weblogic部署贺喝,看有沒有問題菱鸥。我有幾次就是掉進坑了

hibernate.cfg.xml 連接數(shù)據(jù)庫的配置

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost/test</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">2</property>
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- Enable Hibernate's automatic session context management <property name="current_session_context_class">thread</property> -->
        <!-- Disable the second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">update</property>
        <!-- <mapping resource="com/critc/model/Staff.hbm.xml" /> -->
        <mapping class="com.critc.model.Staff" />
    </session-factory>
</hibernate-configuration>

這里面的屬性都比較好理解,稍微看下書就能明白意思搜变。

model

@Entity
@Table(name = "staff")
public class Staff {
    private int id;
    private String name;//
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

這里是采用注解來實現(xiàn)的采缚,現(xiàn)在都采用注解了,配置的時代早過去了挠他。
記住幾點扳抽,必須有@ID,字段的注解盡量寫在get方法上殖侵,當時講過原因贸呢,不過寫在字段上更好理解一些,也起作用拢军。

具體操作類

public class HibernateTest {
    public static void main(String[] args) {

        Configuration cfg = new Configuration();
        SessionFactory sessionFactory = cfg.configure().buildSessionFactory();
        Session session = sessionFactory.openSession();
        session.beginTransaction();

        //新增
        Staff staff = new Staff();
        staff.setName("Hibernate");
        session.save(staff);
        //獲取單個
        Staff staff2 = (Staff) session.get(Staff.class, staff.getId());
        if (staff2 != null)
            System.out.println(staff2.getName());
        //修改
        staff2.setName("改后名字Hibernate2");
        session.save(staff2);

        //查詢 HQL
        Query q = session.createQuery("from Staff");
        List<Staff> list = q.list();
        for (Staff staff3 : list) {
            System.out.println(staff3.getName());
        }

        //刪除
//      session.delete(staff2);
        session.getTransaction().commit();
        session.close();
        sessionFactory.close();
    }
}

上面是舉個例子楞陷,簡單的增刪改查。

寫這篇文章的目的不是教給大家Hibernate怎么用茉唉,而是說Hibernate學起來會很難固蛾,如果你有信心,有毅力度陆,完全可以一戰(zhàn)艾凯!

源碼下載

本工程詳細源碼

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市懂傀,隨后出現(xiàn)的幾起案子趾诗,更是在濱河造成了極大的恐慌,老刑警劉巖蹬蚁,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恃泪,死亡現(xiàn)場離奇詭異,居然都是意外死亡犀斋,警方通過查閱死者的電腦和手機贝乎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叽粹,“玉大人览效,你說我怎么就攤上這事蒙具。” “怎么了朽肥?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長持钉。 經(jīng)常有香客問我大州,道長局劲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮仁连,結果婚禮上,老公的妹妹穿的比我還像新娘改备。我一直安慰自己婴梧,他們只是感情好,可當我...
    茶點故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布辨绊。 她就那樣靜靜地躺著奶栖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪门坷。 梳的紋絲不亂的頭發(fā)上宣鄙,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天,我揣著相機與錄音默蚌,去河邊找鬼冻晤。 笑死,一個胖子當著我的面吹牛绸吸,可吹牛的內容都是我干的鼻弧。 我是一名探鬼主播,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼锦茁,長吁一口氣:“原來是場噩夢啊……” “哼攘轩!你這毒婦竟也來了?” 一聲冷哼從身側響起蜻势,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤撑刺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后握玛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體够傍,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年挠铲,在試婚紗的時候發(fā)現(xiàn)自己被綠了冕屯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,926評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡拂苹,死狀恐怖安聘,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤浴韭,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布丘喻,位于F島的核電站,受9級特大地震影響念颈,放射性物質發(fā)生泄漏泉粉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一榴芳、第九天 我趴在偏房一處隱蔽的房頂上張望嗡靡。 院中可真熱鬧,春花似錦窟感、人聲如沸讨彼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哈误。三九已至,卻和暖如春谍夭,著一層夾襖步出監(jiān)牢的瞬間黑滴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工紧索, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留袁辈,地道東北人。 一個月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓珠漂,卻偏偏與公主長得像晚缩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子媳危,可洞房花燭夜當晚...
    茶點故事閱讀 45,930評論 2 361

推薦閱讀更多精彩內容