Hibernate學(xué)習(xí)教程(二)----ORM 概述

什么是JDBC

  • JDBC:Java Database Connectivity,提供一組Java API,用于java程序中訪問(wèn)關(guān)系數(shù)據(jù)庫(kù)。通過(guò)這些API,Java程序能夠執(zhí)行SQL語(yǔ)句并與任何SQL兼容的數(shù)據(jù)庫(kù)進(jìn)行交互。

  • JDBC提供了一種靈活的架構(gòu),可以編寫一個(gè)獨(dú)立于數(shù)據(jù)庫(kù)的應(yīng)用程序,該應(yīng)用程序可以在不同的平臺(tái)上并與不同的DBMS進(jìn)行修改。

JDBC的優(yōu)點(diǎn)和缺點(diǎn)

優(yōu)點(diǎn) 缺點(diǎn)
簡(jiǎn)潔的SQL處理 用于大型應(yīng)用程序時(shí)比較復(fù)雜
處理大量數(shù)據(jù)有著良好的性能 資源占用開銷比較大
非常適用于小型應(yīng)用程序 沒(méi)有進(jìn)行封裝抽象
語(yǔ)法簡(jiǎn)單,學(xué)習(xí)成本較低 很難用于MVC模式開發(fā)
只能用于DBMS查詢

為什么要進(jìn)行ORM關(guān)系映射(Object Relational Mapping)

當(dāng)我們使用面向?qū)ο蟮南到y(tǒng)時(shí),對(duì)象模型與關(guān)系數(shù)據(jù)庫(kù)之間存在不匹配。RDBMS以表格形式表示數(shù)據(jù),而面向?qū)ο蟮恼Z(yǔ)言(如Java和C#)將其表現(xiàn)為對(duì)象的互聯(lián)圖。如下所示:

public class Employee {
   private int id;
   private String first_name; 
   private String last_name;   
   private int salary;  

   public Employee() {}
   public Employee(String fname, String lname, int salary) {
      this.first_name = fname;
      this.last_name = lname;
      this.salary = salary;
   }
   public int getId() {
      return id;
   }
   public String getFirstName() {
      return first_name;
   }
   public String getLastName() {
      return last_name;
   }
   public int getSalary() {
      return salary;
   }
}

上面的對(duì)象需要被存儲(chǔ)和檢索到下面的RDBMS表:

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

那么就會(huì)存在以下兩個(gè)問(wèn)題:

  • 如果我們需要在開發(fā)了幾個(gè)頁(yè)面之后或在應(yīng)用程序中修改數(shù)據(jù)庫(kù)的設(shè)計(jì)時(shí),應(yīng)該怎么處理?
  • 在關(guān)系數(shù)據(jù)庫(kù)加載和存儲(chǔ)對(duì)象會(huì)暴露以下不匹配問(wèn)題:
不匹配問(wèn)題 描述
Granularity(粒度) 有時(shí),您將有一個(gè)對(duì)象模型,它具有比數(shù)據(jù)庫(kù)中對(duì)應(yīng)表數(shù)量更多的類。
Inheritance(繼承) RDBMS不定義類似于繼承的任何東西,它是面向?qū)ο缶幊陶Z(yǔ)言中的自然范例。
Identity(對(duì)象同一性) RDBMS正好定義了“同一性”的一個(gè)概念:主鍵。然而,Java定義了對(duì)象標(biāo)識(shí)(a == b)和對(duì)象相等(a.equals(b))
Associations 面向?qū)ο笳Z(yǔ)言使用對(duì)象引用表示Associations,RDBMS使用外鍵列表示
Navigation 在Java和RDBMS中訪問(wèn)對(duì)象的方式是完全不同的

對(duì)象關(guān)系映射(ORM)是處理所有上述不匹配問(wèn)題的解決方案。

粒度問(wèn)題

  • 粒度:是指你正在使用的類型的大小。

繼承(子類型問(wèn)題)

  • 在Java中,使用超類(superclass)和子類(subclass)來(lái)實(shí)現(xiàn)繼承模型。
  • 在Java中,繼承是類型繼承(type Inheritance),而數(shù)據(jù)庫(kù)表并不是一種類型。
  • 數(shù)據(jù)庫(kù)產(chǎn)品一般不實(shí)現(xiàn)類型或者表繼承。而且即使實(shí)現(xiàn)了,我們也會(huì)遇到數(shù)據(jù)完整性的問(wèn)題(對(duì)可更新視圖的有限完整性規(guī)則)。
  • 一旦把繼承進(jìn)入到模型當(dāng)中,就有了多態(tài)(polymorphism)的可能。SQL數(shù)據(jù)庫(kù)缺乏一種明顯的表示多態(tài)關(guān)聯(lián)的方式,一個(gè)外鍵約束精確的引用一張目標(biāo)表,定義一個(gè)引用多表的外鍵并不容易。必須編寫一個(gè)程序化的約束來(lái)加強(qiáng)這種完整性規(guī)則。

子類型的這種不匹配的結(jié)果是:模型中的繼承結(jié)構(gòu)必須在一個(gè)不提供繼承策略的SQL數(shù)據(jù)庫(kù)中被持久化。

對(duì)象同一性

如果當(dāng)我們需要檢查兩個(gè)對(duì)象是否為同一個(gè)對(duì)象的時(shí)候。解決方法有三種:

  • 在java中:

    • 對(duì)象同一性(粗略等同于內(nèi)存位置,用a==b檢查)
    • 等同性,通過(guò)equals()方法(也成為值等同)的實(shí)現(xiàn)來(lái)確定。
  • 數(shù)據(jù)庫(kù)的同一性用主鍵值來(lái)表達(dá)。如果使用java中的方法來(lái)判斷,那么主鍵值必然會(huì)不相等。

什么是ORM

ORM(對(duì)象關(guān)系映射),是一種用于關(guān)系數(shù)據(jù)庫(kù)和面向?qū)ο缶幊陶Z(yǔ)言(如Java、C#)之間轉(zhuǎn)換數(shù)據(jù)的編程技術(shù)。相對(duì)于JDBC,ORM具有以下優(yōu)點(diǎn):

序號(hào) 優(yōu)點(diǎn)
1 允許業(yè)務(wù)邏輯代碼訪問(wèn)對(duì)象而不是數(shù)據(jù)庫(kù)表
2 從面向?qū)ο蟮慕嵌瓤紤]隱藏SQL查詢的詳細(xì)信息
3 底層基于JDBC
4 無(wú)需處理數(shù)據(jù)庫(kù)實(shí)現(xiàn)
5 基于業(yè)務(wù)概念而不是數(shù)據(jù)庫(kù)結(jié)構(gòu)的實(shí)體
6 事務(wù)管理和秘鑰自動(dòng)生成
7 應(yīng)用快速開發(fā)

ORM解決方案由以下四個(gè)模塊組成:

序號(hào) 解決方案
1 用于對(duì)持久化類的對(duì)象進(jìn)行基本CRUD操作的API
2 用于指定引用類的類和屬性的查詢的語(yǔ)言或API
3 用于指定映射元數(shù)據(jù)的可配置工具
4 用于實(shí)現(xiàn)ORM的一項(xiàng)技術(shù),與事務(wù)對(duì)象交互,執(zhí)行臟檢查、延遲關(guān)聯(lián)抓取以及其它優(yōu)化功能

Java中的ORM框架

Java中有幾個(gè)持久化框架和ORM選項(xiàng)。持久化框架是一種將對(duì)象存儲(chǔ)和檢索到關(guān)系數(shù)據(jù)庫(kù)中的ORM服務(wù)。

  • Enterprise JavaBeans Entity Beans
  • Java Data Objects
  • Castor
  • TopLink
  • Spring DAO
  • Hibernate
  • ……. etc.

ORM和Hibernate的一些好處

生產(chǎn)力

與持久化相關(guān)的代碼可能會(huì)是java中最冗長(zhǎng)的一部分代碼,Hibernate除去了許多瑣碎的工作,讓我們可以把更多的精力集中于業(yè)務(wù)問(wèn)題的處理上。
無(wú)論我們喜歡哪一種應(yīng)用程序開發(fā)策略——自上而下,從一個(gè)領(lǐng)域模型開始;或者自底而上,從一個(gè)現(xiàn)有的數(shù)據(jù)庫(kù)Schema開始——Hibernate與適當(dāng)?shù)墓ぞ咭黄鹗褂?,將明顯減少開發(fā)時(shí)間。

可維護(hù)性

更少的代碼行使得系統(tǒng)更易于理解,因?yàn)樗鼜?qiáng)調(diào)業(yè)務(wù)邏輯甚于那些費(fèi)力的基礎(chǔ)性工作。更重要的是,系統(tǒng)包含的代碼越少則越利于重構(gòu)。自動(dòng)的對(duì)象/關(guān)系持久化充分減少了代碼行。

Hibernate更易于維護(hù)還有其它原因,在手工編碼的持久化系統(tǒng)中,關(guān)系表示法和對(duì)象模型實(shí)現(xiàn)領(lǐng)域之間存在一種必然的壓力。改變一個(gè),通常都要改變另一個(gè),并且一個(gè)表示法設(shè)計(jì)通常需要妥協(xié)以便適應(yīng)另一個(gè)的存在。ORM提供了兩個(gè)模型之間的一個(gè)緩沖,允許面向?qū)ο笤贘ava方面進(jìn)行更優(yōu)雅的利用,并且每個(gè)模型的微小變化都不會(huì)傳遞到另一個(gè)模型。

性能

手工編碼的持久化和自動(dòng)的持久化相比總是可以一樣快,并且經(jīng)常更快。這是事實(shí)。但是在實(shí)際開發(fā)中,會(huì)受到時(shí)間和預(yù)算的約束。

在有限時(shí)間的項(xiàng)目中,手工編碼的持久化通常允許你進(jìn)行一些優(yōu)化;Hibernate始終允許使用更多的優(yōu)化。

自動(dòng)的持久化能夠大大提高開發(fā)人員的工作效率,使得開發(fā)人員能夠花更多的時(shí)間對(duì)其它少數(shù)瓶頸進(jìn)行手工優(yōu)化。

實(shí)現(xiàn)ORM框架的人,可能在性能優(yōu)化方面比我們做的更好。

供應(yīng)商獨(dú)立性

ORM從底層的SQL數(shù)據(jù)庫(kù)和SQL方言中把應(yīng)用程序抽象出來(lái)。如果這個(gè)工具支持不同的數(shù)據(jù)庫(kù),這會(huì)給我們的應(yīng)用程序帶來(lái)一定程度的可移植性??梢詭臀覀儨p少一些被供應(yīng)商鎖定的風(fēng)險(xiǎn)。

數(shù)據(jù)庫(kù)的獨(dú)立性使得我們可以在開發(fā)時(shí)選擇一些輕量級(jí)的數(shù)據(jù)庫(kù),在部署時(shí),將實(shí)際的產(chǎn)品部署在不同的數(shù)據(jù)庫(kù)上。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 本文中我們介紹并比較兩種最流行的開源持久框架:iBATIS和Hibernate,我們還會(huì)討論到Java Persi...
    大同若魚閱讀 4,345評(píng)論 4 27
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 31,767評(píng)論 18 399
  • Hibernate: 一個(gè)持久化框架 一個(gè)ORM框架 加載:根據(jù)特定的OID,把一個(gè)對(duì)象從數(shù)據(jù)庫(kù)加載到內(nèi)存中OID...
    JHMichael閱讀 2,000評(píng)論 0 27
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,837評(píng)論 0 11
  • 我算得上是一個(gè)友情至上的人吧,不過(guò)在這種情感中我也受過(guò)不少傷。 我是一個(gè)很相信緣分的人,或許有的時(shí)候你和誰(shuí)成為了朋...
    Hello唐小杺閱讀 299評(píng)論 4 3