精通Hibernae讀書筆記2

 第二章 java對象持久化技術概述

本章介紹對象持久化的集中模式

1.在業務邏輯層直接通過JDBCAPI來持久化實體域對象,業務邏輯和數據訪問耦合。

2.主動域對象模式

3.ORM模式

4.JDO模式

5.CMP模式

2.1通過JDBC API來持久化實體域對象 

Java應用訪問數據庫的最直接的方式就是直接訪問JDBC APIJDBCJava Database Connectivity的縮寫。

java.sql包提供了JDBC API。在java.sql包中常用的接口和類包括:

DriverManager:驅動程序管理器,負責創建數據庫連接。

Connection:代表數據庫連接。

Statement:負責執行SQL語句。

PreparedStatement:負責執行SQL語句,具有預定義SQL語句的功能。

ResultSet:代表SQL查詢語句的查詢結果集

JDBC驅動程序

Java應用必須通過JDBC驅動程序來和特定的數據庫系統連接。 

JDBC驅動程序由數據庫廠商或第三方提供。

負責持久化Customer對象的BusinessService

saveCustomer():把Customer域對象永久保存到數據庫中。

updateCustomer():更新數據庫中Customer域對象的狀態。

deleteCustomer():從數據庫中刪除一個Customer域對象。

loadCustomer():根據特定的OID,把一個Customer域對象從數據庫加載到內存中。

findCustomerByName():根據特定的客戶姓名,把符合查詢條件的Customer域對象從數據庫加載到內存中。

業務邏輯代碼與數據訪問代碼耦合的saveCustomer()方法

  con=getConnection(); //獲得數據庫連接

      //開始一個數據庫事務

      con.setAutoCommit(false);

      //以下是業務邏輯代碼,檢查客戶姓名是否爲空

      if(customer.getName()==null)

        throw new BusinessException("客戶姓名不允許爲空");

      //以下是數據訪問代碼,持久化Customer對象

      //爲新的CUSTOMERS記錄分配惟一的ID

      long customerId=getNextId(con,"CUSTOMERS");

      //Customer對象映射爲面向關係的SQL語句

      stmt=con.prepareStatement("insert into CUSTOMERS(ID,NAME,AGE) values(?,?,?)");

      stmt.setLong(1,customerId);

      stmt.setString(2,customer.getName());

      stmt.setInt(3,customer.getAge());

      stmt.execute();

業務邏輯代碼與數據訪問代碼耦合的saveCustomer()方法

      Iterator iterator =customer.getOrders().iterator();

      while (iterator.hasNext() ) {

        //以下是業務邏輯代碼,檢查訂單編號是否爲空

        Order order=(Order)iterator.next();

        if(order.getOrderNumber()==null)

          throw new BusinessException("訂單編號不允許爲空");

        //以下是數據訪問代碼,級聯持久化Order對象

        //爲新的ORDERS記錄分配惟一的ID

        long orderId=getNextId(con,"ORDERS");

        //Order對象映射爲面向關係的SQL語句

        stmt=con.prepareStatement("insert into ORDERS(ID,ORDER_NUMBER,PRICE,CUSTOMER_ID)values(?,?,?,?)");

        stmt.setLong(1,orderId);

        stmt.setString(2,order.getOrderNumber());

        stmt.setDouble(3,order.getPrice());

        stmt.setLong(4,customerId);

        stmt.execute();

      }

      //提交數據庫事務

      con.commit();

JDBC編程的缺點

實現業務邏輯的代碼和數據庫訪問代碼摻雜在一起,使程序結構不清晰,可讀性差。

在程序代碼中嵌入面向關係的SQL語句,使開發人員不能完全運用面向對象的思維來編寫程序。

業務邏輯和關係數據模型綁定,如果關係數據模型發生變化,例如修改了CUSTOMERS表的結構,那麼必須手工修改程序代碼中所有相關的SQL語句,這增加了維護軟件的難度。

如果程序代碼中的SQL語句包含語法錯誤,在編譯時不能檢查這種錯誤,只有在運行時才能發現這種錯誤,這增加了調試程序的難度。

數據訪問模式

業務邏輯和數據訪問耦合

ORM模式:在單個組件中負責所有實體域對象的持久化,封裝數據訪問細節。 

主動域對象模式:由實體域對象本身負責管理自己的持久化

JDO模式: SUN公司制定的描述對象持久化語義的標準API 

CMP模式:由容器負責管理持久化

2.2ORM簡介

對象-關係映射(Object-Relation Mapping)模式是指在單個組件中負責所有實體域對象的持久化,封轉數據訪問細節。

2.2.1對象-關係映射(Object-Relation Mapping)的概念

ORM解決的主要問題就是對象-關係的映射。域模型和關係模型都分別建立在概念模型的基礎上。域模型是面向對象的,而關係數據模型是面向關係的.

一般情況下,一個持久化類和一個表對應,類的每個實例對應表中的一條記錄。

域模型與關係模型之間存在許多不匹配之處:

域模型中有繼承關係,關係模型不能直接表示繼承關係

域模型中有多對多關聯關係,關係模型通過連接表來表示多對多關聯關係

域模型中有雙向關聯關係,關係模型只有單向參照關係,而且總是many方參照one方。

域模型提倡精粒度模型,而關係模型提倡粗粒度模型

域模型與關係模型之間的不匹配舉例

2.2.3 ORM中間件的使用方法

   ORM中間件採用元數據來描述對象-關係映射文件細節,元數據採用XML格式,而且保存在專門的對象-關係映射文件中。

在圖中Session接口向業務邏輯提供了讀寫和刪除域對象的方法,他不公開任何數據訪問細節,SessionImpl實現這個接口。SessionFactroy負責創建Session實例。Hibernate在初始階段把對象-關係映射文件的映射元數據讀入到SessionFactory中。

Public void deleteCustomer(Customer customer)

{

   Session sesion=getSession();

   Session.delete(customer);

}

Sessiondelete()方法執行以下步驟:

1>運用Java反射機制,獲得customer對象的類型爲Customer.class

2>參考對象-關係映射元數據,瞭解到和Customer類對應的表爲CUSTOMERS表,此外Customers類和Order類關聯,Order類和ORDER表對應,ORDERS表的外鍵CUSTOMER_ID參照CUSTOMER表的ID主鍵

3>根據以上映射信息,生成SQL語句

   Delete from ORDERS where CUSTOMER_ID=

   Delete from CUSTOMERS where ID=

4>通過JDBC API來執行以上SQL語句

2.2.3 常用的ORM中間件

ORM軟件

URL

Hibernate

http://www.hiberante.org

TopLink

http://otn.oracle.com/products/ias/toplink/content.html

Torque

http://jakarta.apache.org/turbine/torque/index.html

ObjectRelatinalBridge

http://db.apacche.org/ojb/

FrontierSuite

http://www.objectfrontier.com

Castor

http://castor.exolab.org

FreeFORM

http://www.chimu.com/projects/form/

Expresso

http://www.jcorporate.com

JRelationalFframework

http://jrf.sourrceforge.net

VBSF

http://www.objectmatter.com

Jgrinder

http://sourceforge.net/projects/jgrinder/

JPA

直接對輕量級的基於JavaBean形式的實體域進行持久化

2.3實體域對象的其他持久化模式

2.3.1主動域對象模式

  主動域是實體域對象的一種形式,在它的實現中封裝了關係數據模型和數據訪問細節。

EJB中分實體Bean分爲:由EJB本身管理持久化,即BMP是主動域對象模型的一個例子,BMP表示有實體EJB本身管理數據訪問細節。

主動域對象模式的優點:

A>在實體域對象中封裝自身的數據訪問細節,過程域對象完全負責業務邏輯,是程序結構清晰

B>如果關係數據模型發生衝突,只需改變主動域對象的代碼,不需要修改過程域對象的業務方法。

主動域對象模式的缺點:

A>在實體域對象的實現中仍然包含sql語句

B>每個實體域對象都負責自身的數據訪問實現。

2.3.2JDO模式

Java Data Objects(JDO)sun制定的描述對象持久化語義的標準API

採用JDO模式的應用的分層結構

JDO支持關係數據庫。面向對象的數據庫.基於XML的數據庫和其他專用存儲系統

2.3.3 CMP模式

CMP模式表示由EJB容器來管理實體EJB持久化,EJB容器封裝了對象-關係的映射及數據訪問細節。

2.4HibernateAPI簡介

1.提供訪問數據庫的操作(如保存.跟新.刪除和查詢對象)的接口。包括Session.TransacctionQuery接口。

2.用於配置Hibernate的接口。包括Configuration

3.使應用程序攔截Hibernate內部發生事件,並做出相關的反應。這些接口:Interceptor.LoadEventListenerSaveEventListener

4.用於擴展Hibernate的功能接口。如UserType.CompositeUserTypeIdentifierGenerator接口。

Hibernate內部封裝了JDBCJTA(JAVA Naming and Directory Interface).JDBC提供底層的數據訪問操作,只要用戶提供相應的JDBC驅動程序,Hibernate可以訪問任何數據庫。JNDIJTA使Hibernate能夠和j2ee應用服務器集成。

2.4.1hibernate的核心接口

1.Configuration接口是配置Hibernate並且根啓動Hibernate,創建SessionFactory對象。Hiberante應用通過Configuration實例來獲得對象-關係映射文件中文件的元數據,以及動態配置Hibernate的屬性,然後創建sessionFactory的實例

2.SessionFactory接口:初始化hiberante,充當數據存儲源的代理,創建Session對象。一個SessionFactory實例對應一個數據存儲源,應用以SessionFctory中獲取Session實例。

SessionFctory的特點:

  1.它是線程安全的,意味着它的同一實例可以被應用的 多個線程共享。

  2.它是重量級,這意味着不能隨意的創建或者銷燬它的實例。訪問一個數據庫創建一個SessionFactory,訪問多個就創建多個。(被稱爲重量級的是因爲:1。它需要很大的緩存存放預定義的SQL語句及映射元數據等。還可以配置SessionFactory的緩存插件,被稱爲Hibernate的二次緩存,用來存放被工作單元讀過的數據,將來其他工作單元會重用這些數據,因此這個緩存中的數據能夠被所有工作單元共享,一個工作單元對應一個數據庫事務。)

3.Session接口:負責保存.更新.加載和查詢對象,被稱爲持久化管理器

  特點:1。不是線程安全的

        2.。是輕量級的,是指創建和銷燬不需要消耗太多的資源

  注意:Session有一個緩存,被稱爲Hibernate的一級緩存,它用來存放當前工作單元加載的對象。每個session實例都有自己的緩存,這個session實例的緩存只能被當前工作單元鎖使用

4.Transaction:管理事務。是hibernate的數據庫事務接口,它對底層的事務接口做了封裝,這些遞呈的事務接口包括:

   1JDBCAPI

   2JTA(Java Transaction API)

   3.CORBA(Common Object Requet Broker Architecture)API

5.QueryCriteria:執行數據庫查詢.Qurey包裝了一個HQl查詢語句,Criteria接口封裝了基於字符串形式的查詢語句,擅長執行動態的查詢

                Hibernte核心接口的類框圖

2.4.2時間處理接口

   當程序通過hibernate來加載.保存.跟新和刪除對象時,會觸發Hibernate的攔截器及事件監聽器做出的惡性一處理:

1.事件及事件監聽接口:在HibernateAPI,針對每一種事件都有相應的事件監聽器,如加載對象會觸發org.hibernate.event.LoadEven事件,該事件有org.hibernate.event.LoadeventListener監聽器處理。保存對象觸發org.hibernate.event.SaveEvent事件,該事件由org.hibernate.event.SaveEventListener監聽器處理

2.org.hibernate.Interceptor接口:應用程序可以定義實現Interceptor接口的類,Interceptor實現類負責響應持久化類的實例被加載.保存更新或者刪除的事件。

2.4.3映射類型接口

org.hibernate.type.Type接口表示Hibernate映射類型,用於把域對象映射爲數據庫的關係數據。HiberanteType接口提供了各種實現類:

1.PrimitiveType類型:映射java的基本類型:ByteTypeshortTypeIntegerTypeLongType

FloatTypeDoubleTypecharacterTypeBooleanType這八個類

2.DateType:映射Java日期類型

3.BinaryType:硬塞Byte[]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章