第二週

Tomcat運行原理

http://blog.csdn.net/pzxwhc/article/details/47129675 Tomcat執行流程html

http://www.importnew.com/17124.html Tomcat server.xml配置示例java

一、JavaWeb應用的概念

在Sun的Java Servlet規範中,對Java Web應用做了這樣定義:「Java Web應用由一組Servlet、HTML頁、類、以及其它能夠被綁定的資源構成。它能夠在各類供應商提供的實現Servlet規範的 Servlet容器 中運行。」程序員

 

Servlet容器爲JavaWeb應用提供運行時環境,它負責管理Servlet和JSP的生命週期,以及管理它們的共享數據。Servlet容器也稱爲JavaWeb應用容器,或者Servlet/JSP容器。web

目前最流行的Servlet容器軟件括:Tomcat,Resin,J2EE服務器(如Weblogic)中也提供了內置的Servlet容器。sql

二、Tomcat簡介

Tomcat 是一個免費的開放源代碼的 Servlet 容器,它是 Apache 軟件基金會的一個頂級項目,由 Apache,Sun和其餘一些公司及我的共同開發而成。因爲有了 Sun 的參與和支持,最新的 Servlet 和 JSP 規範老是能在 Tomcat 中的到體現。數據庫

 

三、Tomcat Server組件

Tomcat是一個基於組件的服務器,他的構建組件都是能夠配置的,其中最外層的組件是Catalina Servlet容器,其餘組件必定要按照必定的格式要求配置在這個頂層的容器中。apache

<Server> 頂層類元素,可包含多個service編程

<Service> 頂層類元素,可包含一個Engine和多個Connector設計模式

<Connector/> 連接類容器,表明通訊接口數組

<Engine> 容器元素,爲Service處理客戶請求,含多個Host

<Host> 容器元素,爲Host處理客戶請求,含多個Context

<Context/> 容器元素,爲Web應用處理客戶請求

</Host>

</Engine>

</Service>

</Server>

 

1) Server

A Server element represents the entire Catalina servlet Container. (Singleton)單實例的。

2) Service

Service是一個集合。它由一個或者多個Connector組成,以及一個Engine,負責處理全部Connector所得到的客戶請求。

3) Connector  表示客戶端和service之間的鏈接

一個Connector將在某個指定端口上偵聽客戶請求,並將得到的請求交給Engine來處理,從Engine處得到迴應並返回客戶。

 

TOMCAT有兩個典型的Connector,一個直接偵聽來自browser的http請求,一個偵聽來自其它WebServer的請求。

Coyote Http/1.1 Connector 在端口8080處偵聽來自客戶browser的http請求。

Coyote JK2 Connector 在端口8009處偵聽來自其它WebServer(Apache)的servlet/jsp代理請求。

4) Engine  表示指定service中的請求處理機,接收和處理來自Connector的請求

Engine下能夠配置多個虛擬主機Virtual Host,每一個虛擬主機都有一個域名。當Engine得到一個請求時,它把該請求匹配到某個Host上,而後把該請求交給該Host來處理。Engine有一個默認虛擬主機,當請求沒法匹配到任何一個Host上的時候,將交給該默認Host來處理。

5) Host   表示一個虛擬主機

表明一個Virtual Host,虛擬主機,每一個虛擬主機和某個網絡域名Domain Name相匹配。每一個虛擬主機下均可以部署(deploy)一個或者多個Web App,每一個Web App對應於一個Context,有一個Context path

當Host得到一個請求時,將把該請求匹配到某個Context上,而後把該請求交給該Context來處理。匹配的方法是「最長匹配」,因此一個path==""的Context將成爲該Host的默認Context。全部沒法和其它Context的路徑名匹配的請求都將最終和該默認Context匹配。

6) Context   表示一個web應用程序

一個Context對應於一個Web Application,一個Web Application由一個或者多個Servlet組成。

 

四、Web.xml文件

一個Context對應於一個Web App,每一個Web App是由一個或者多個servlet組成的。

當一個Web App被初始化的時候,它將用本身的ClassLoader對象載入「部署配置文件web.xml」中定義的每一個servlet類。

它首先載入在$CATALINA_HOME/conf/web.xml中部署的servlet類

而後載入在本身的Web App根目錄下的WEB-INF/web.xml中部署的servlet類

web.xml文件有兩部分:servlet類定義和servlet映射定義

每一個被載入的servlet類都有一個名字,且被填入該Context的映射表(mapping table)中,和某種URL PATTERN對應

當該Context得到請求時,將查詢mapping table,找到被請求的servlet,並執行以得到請求迴應

分析一下全部的Context共享的web.xml文件,在其中定義的servlet被全部的Web App載入。

五、處理HTTP請求過程

假設來自客戶的請求爲:

protocol :// hostname[:port] / path / [;parameters][?query]#fragment

http://localhost:8080/wsota/wsota_index.jsp

1) 請求被髮送到本機端口8080,被在那裏偵聽的Coyote HTTP/1.1 Connector得到

2) Connector把該請求交給它所在的Service的Engine來處理,並等待來自Engine的迴應

3) Engine得到請求localhost/wsota/wsota_index.jsp,匹配它所擁有的全部虛擬主機Host

4) Engine匹配到名爲localhost的Host(即便匹配不到也把請求交給該Host處理,由於該Host被定義爲該Engine的默認主機)

5) localhost Host得到請求/wsota/wsota_index.jsp,匹配它所擁有的全部Context

6) Host匹配到路徑爲/wsota的Context(若是匹配不到就把該請求交給路徑名爲""的Context去處理)

7) path="/wsota"的Context得到請求/wsota_index.jsp,在它的mapping table中尋找對應的servlet

8) Context匹配到URL PATTERN爲*.jsp的servlet,對應於JspServlet類

9) 構造HttpServletRequest對象和HttpServletResponse對象,做爲參數調用JspServlet的doGet或doPost方法

10)Context把執行完了以後的HttpServletResponse對象返回給Host

11)Host把HttpServletResponse對象返回給Engine

12)Engine把HttpServletResponse對象返回給Connector

13)Connector把HttpServletResponse對象返回給客戶browser

 

六、tomcat部署一個java應用

創建一個符合web應用目錄的程序結構MyWebContent。須要將類生成文件配置到WEB-INF的classes目錄下。

 

將MyWebContent複製到E:\apache-tomcat-7.0.34-noinstall\webapps目錄下,打開

http://localhost:8080/manager/html

 

打開

 

能夠看到

 

WEB-INF目錄下的classes和lib目錄均可以存放Java的類文件,在Servlet容器運行時,Web應用程序的類加載器將首先加載classes目錄下的,其次纔是lib目錄下的類。若是這兩個目錄下存在同名的類,起做用的將是classes目錄下的類。

JdbcTemplate使用筆記

一、JdbcTemplate簡介

  1. 爲了使 JDBC 更加易於使用,Spring 在 JDBC API 上定義了一個抽象層,以此創建一個 JDBC 存取框架。
  2. 做爲 Spring JDBC 框架的核心,JDBC 模板的設計目的是爲不一樣類型的 JDBC 操做提供模板方法。 每一個模板方法都能控制整個過程,並容許覆蓋過程當中的特定任務。經過這種方式,能夠在儘量保留靈活性的狀況下,將數據庫存取的工做量降到最低。

 

二、用sql更新數據庫

 

例如:

 

三、批量更新數據庫

 

例如:

 

四、查詢單行記錄

 

例如:

 

五、查詢多行記錄

 

例如:

 

六、單值查詢

 

例如:

 

七、調用存儲函數

 

第二種

 

八、調用存儲過程

 

 

 

 

九、返回結果集

返回結果集,經過把遊標做爲一個out參數來返回的。

 

 

Java調用

 

 

 

十、blob和clob處理

BLOB和CLOB都是大字段類型,BLOB是按二進制來存儲的,而CLOB是能夠直接存儲文字的。其實兩個是能夠互換的的,或者能夠直接用LOB字段代替這兩個。可是爲了更好的管理ORACLE數據庫,一般像圖片、文件、音樂等信息就用BLOB字段來存儲,先將文件轉爲二進制再存儲進去。而像文章或者是較長的文字,就用CLOB存儲,這樣對之後的查詢更新存儲等操做都提供很大的方便。

 

 

插入成功!

 

讀取而且複製

 

 

 

Java規範學習筆記

一、Object 的 equals 方法容易拋空指針異常,應使用常量或肯定有值的對象來調用 equals。

       正例: "test".equals(object);

二、關於基本數據類型與包裝數據類型的使用標準以下:

全部的 POJO 類屬性必須使用包裝數據類型。

RPC 方法的返回值和參數必須使用包裝數據類型。

全部的局部變量推薦使用基本數據類型。

三、在集合迭代過程當中,不能直接調用集合的add,remove方法,會報java.util.ConcurrentModificationException異常。應該使用迭代器的移除方法。

       ArrayList<String> list = new ArrayList<String>(Arrays.asList("a","b","c","d"));

//      Iterator<String> iterator = list.iterator();

//      while(iterator.hasNext()){

//          if(iterator.next().equals("a")){

//              iterator.remove();

//          }

//      }

        for(String s : list){

            if(s.equals("a")){

                list.add("bbb");

            }

        }//java.util.ConcurrentModificationException

四、高併發時,同步調用應該去考量鎖的性能損耗。能用無鎖數據結構,就不要用鎖;能鎖區塊,就不要鎖整個方法體;能用對象鎖,就不要用類鎖。

五、併發修改同一記錄時,避免更新丟失,要麼在應用層加鎖,要麼在緩存加鎖,要麼在數據庫層使用樂觀鎖,使用 version 做爲更新依據。

> 說明: 若是每次訪問衝突機率小於 20%,推薦使用樂觀鎖,不然使用悲觀鎖。樂觀鎖的重試次數不得小於 3 次。

悲觀鎖(Pessimistic Lock),顧名思義,就是很悲觀,每次去拿數據的時候都認爲別人會修改,因此每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。傳統的關係型數據庫裏邊就用到了不少這種鎖機制,好比行鎖,表鎖等,讀鎖,寫鎖等,都是在作操做以前先上鎖。

樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿數據的時候都認爲別人不會修改,因此不會上鎖,可是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣能夠提升吞吐量,像數據庫若是提供相似於write_condition機制的其實都是提供的樂觀鎖。

兩種鎖各有優缺點,不可認爲一種好於另外一種,像樂觀鎖適用於寫比較少的狀況下,即衝突真的不多發生的時候,這樣能夠省去了鎖的開銷,加大了系統的整個吞吐量。但若是常常產生衝突,上層應用會不斷的進行retry,這樣反卻是下降了性能,因此這種狀況下用悲觀鎖就比較合適。

六、若是使用要 if-else if-else 方式表達邏輯,【強制】請勿超過 3 層,超過請使用狀態設計模式。

http://blog.csdn.net/hguisu/article/details/7557252   狀態設計模式

 

 

七、避免用 Apache Beanutils 進行屬性的 copy。

> 說明: Apache BeanUtils 性能較差,可使用其餘方案好比 Spring BeanUtils, CglibBeanCopier。

八、後臺輸送給頁面的變量必須加$!{var}——中間的感嘆號。

> 說明: 若是 var=null 或者不存在,那麼${var}會直接顯示在頁面上。

 

Maven學習筆記

一、目前所存在的問題

1.一個項目就是一個工程。項目很是龐大,用package不適合劃分。最好是一個模塊對應一個工程。

    能夠利用maven將一個項目拆分紅多個工程。

2.項目裏面的jar包都是手動複製和添加。這樣,同一個jar包會出如今多個項目中。

3.jar包須要本身下載。Jar包依賴關係。

二、Maven概述

一款服務於java平臺的自動化構建工具。Make、Ant、Maven、Gradle

運行時環境:就是一組jar包的引用。並無正真放入工做目錄。

   

編譯------------部署------------搭建

 

構建過程的各個環節

    1.清理,將之前的字節碼class文件刪除

    2.編譯,將java源程序編譯成class文件

    3.測試,自動測試,調用junit程序

    4.報告,測試結果

    5.打包,web工程打war包,java工程打jar包

    6.安裝,將打包文件複製到倉庫的指定位置

    7.部署,將web動態工程生成的war包複製到severvlet容器的指定目錄下。

 

原工程與編譯結果對比圖

 

三、Maven核心概念

1.約定的目錄結構

2.POM,項目對象模型

3.座標,利用三個向量,在倉庫中定義一個Maven工程

    GroupId: 公司或組織域名倒序+項目名

    ArtifactId:模塊名,好比Hello

    Version:版本,好比1.1.0,release可分離的穩定版,snapshot快照版迭代快

4.依賴,

    Maven解析依賴信息時,會到本地倉庫中查找被依賴的jar包。

    對於本身開發的maven工程,使用install命令來安裝,就能夠進入倉庫。

    依賴範圍:<scope>compile</scope>

           Compile  對主程序是否有效,對測試程序是否有效,是否參與打包。

           Test  

           Provided  

 

   

5.倉庫,本地倉庫和遠程倉庫。

6.聲明週期/插件/目標

7.繼承

8.聚合

四、Maven工程目錄結構

    ①目錄結構

           Hello  工程名

           |---src 源碼

           |---|---main 主程序

           |---|---|---java  源碼

           |---|---|---resources  框架和其餘配置文件

           |---|---test  存放測試程序

           |---|---|---java

           |---|---|---resources

           |---pom.xml Maven核心配置文件

    ②POM文件內容

    Project Object Model項目對象模型

    Document Object Model 文檔對象模型DOM

 

import static junit.framework.Assert.*; 靜態導入。類裏全部的靜態資源能夠直接用了。

assertEquals(「….」,results);斷言結果與給定字符串一致。

五、Maven經常使用命令

執行與構建(編譯、測試、打包)過程相關的命令,必須進入pom.xml文件所在目錄。

1.   mvn  clean: 清理

2.   mvn  compile: 編譯

3.   mvn test-compile: 編譯測試程序

4.   mvn test: 執行測試程序

5.   mvn package: 打包

6.   mvn install: 將本地jar包安裝到本地倉庫中

7.   mvn site: 生成站點

先找本地倉庫,沒有相關jar包,就聯網下載。

六、Maven生命週期

各個構建環境執行的順序,順序執行。

定義了抽象聲明週期,具體由插件完成。

自動化構建的特色,不論要執行生命週期的哪個階段,都是從生命週期最初的位置開始執行。

 

能夠將目標看作調用功能的命令。

七、jar包依賴

各個構的環境執行的順序,順序執行。

排除jar包

 

依賴原則:路徑最短優先。路徑相同時,先聲明優先。

傳遞依賴,非compile範圍內的不能傳遞依賴。

引用版本號:方便更改。

 

聚合:因爲有繼承後,須要先安裝父工程。聚合的做用就是一鍵安裝各個參與聚合的模塊。

好比:在Parent模塊中配置以下,

 

八、部署到服務器上

方法1(手動):

能夠將web引用,package先打包成war包。將war包複製到Tomcat安裝的webapps目錄下。

方法2(自動):

    配置build標籤後,最好用cmd來運行deploy命令,不然須要手動關閉Tomcat。

 

 

 

九、下載源碼和javadoc

方法1:命令

命令使用方法:首先進入到相應的pom.xml目錄中,而後執行如下命令:

mvn dependency:sources

mvn dependency:resolve -Dclassifier=javadoc

第一個命令是嘗試下載在pom.xml中依賴的文件的源代碼。

第二個命令是嘗試下載對應的javadocs

可是有可能一些文件沒有源代碼或者javadocs

方法2:配置文件

打開maven配置文件 setting.xml文件(.../.m2/settings.xml) 增長以下配置:

  1. <profiles>  
  2. <profile>  
  3.     <id>downloadSources</id>  
  4.     <properties>  
  5.         <downloadSources>true</downloadSources>  
  6.         <downloadJavadocs>true</downloadJavadocs>             
  7.     </properties>  
  8. </profile>  
  9. </profiles>  
  10. 10.   

11. <activeProfiles>  

  1. 12.   <activeProfile>downloadSources</activeProfile>  

13. </activeProfiles>  

方法3:配置myeclipse    推薦使用

 

十、jar包查找總站

http://mvnrepository.com/

 

 

Hibernate學習筆記

一、hibernate簡介

ORM:Object Relation Mapping  對象/關係映射

ORM 主要解決對象-關係的映射

 

ORM的思想:將關係數據庫中表中的記錄映射成爲對象,以對象的形式展示,程序員能夠把對數據庫的操做轉化爲對對象的操做。

ORM 採用元數據來描述對象-關係映射細節,元數據一般採用 XML 格式, 而且存放在專門的對象-關係映射文件中。(描述類、對象、屬性和表的行列對應關係)

元數據:描述數據的數據。

對象關係映射文件***.hbm.xml

 

二、hibernate開發步驟

1)hibernate配置文件hibernate.cfg.xml

2)建立對象-關係映射文件*.hbm.xml

編寫持久化類: POJO + 映射文件

獲取 Configuration 對象

獲取 SessionFactory 對象

獲取 Session,打開事務

用面向對象的方式操做數據庫

關閉事務,關閉 Session

3)Configuration 類負責管理 Hibernate 的配置信息。包括以下內容:

配置1:Hibernate 運行的底層信息:數據庫的URL、用戶名、密碼、JDBC驅動類,數據庫Dialect,數據庫鏈接池等(對應 hibernate.cfg.xml 文件)。

配置2:持久化類與數據表的映射關係(*.hbm.xml 文件)

4)SessionFactory針對單個數據庫映射關係通過編譯後的內存鏡像,是線程安全的。 SessionFactory 對象一旦構造完畢,即被賦予特定的配置信息。SessionFactory是生成Session的工廠。構造 SessionFactory 很消耗資源,通常狀況下一個應用中只初始化一個 SessionFactory 對象。

5)Session 是應用程序與數據庫之間交互操做的一個單線程對象,是 Hibernate 運做的中心,全部持久化對象必須在 session 的管理下才能夠進行持久化操做。此對象的生命週期很短。Session 對象有一個一級緩存,顯式執行 flush 以前,全部的持久層操做的數據都緩存在 session 對象處。至關於 JDBC 中的 Connection。

       取得持久化對象的方法: get() load()

持久化對象都得保存,更新和刪除:save(),update(),saveOrUpdate(),delete()

開啓事務: beginTransaction().

管理 Session 的方法:isOpen(),flush(), clear(), evict(), close()等

 

注意紅色部分,是以斜槓隔斷。

 

三、Session 概述

Session 接口是 Hibernate 嚮應用程序提供的操縱數據庫的最主要的接口,它提供了基本的保存,更新, 刪除和加載 Java 對象的方法.

Session 具備一個緩存,位於緩存中的對象稱爲持久化對象,它和數據庫中的相關記錄對應。Session 可以在某些時間點,按照緩存中對象的變化來執行相關的 SQL 語句,來同步更新數據庫,這一過程被稱爲刷新緩存(flush)。

站在持久化的角度,Hibernate 把對象分爲 4 種狀態:臨時狀態,持久化狀態,遊離狀態,刪除狀態。 Session 的特定方法能使對象從一個狀態轉換到另外一個狀態。

四、Session緩存

在 Session 接口的實現中包含一系列的 Java 集合,這些 Java 集合構成了 Session 緩存。只要 Session 實例沒有結束生命週期,且沒有清理緩存,則存放在它緩存中的對象也不會結束生命週期。

Session 緩存可減小 Hibernate 應用程序訪問數據庫的頻率。

 

Flush使得數據表中的記錄和session緩存中的狀態保持一致,可能會發送對應的SQL語句。

在Transaction的commit()方法中先調用flush方法,再commit。

Flush()方法可能會發送sql語句,可是不會提交事務,也就是數據表的記錄不會改變。

3. 注意: 在未提交事務或顯式的調用 session.flush() 方法以前,也有可能會進行 flush() 操做。

* 1). 執行 HQL 或 QBC 查詢,會先進行 flush() 操做,以獲得數據表的最新的記錄

* 2). 若記錄的 ID 是由底層數據庫使用自增的方式生成的,則在調用 save() 方法時,就會當即發送 INSERT 語句。

* 由於 save 方法後,必須保證對象的 ID 是存在的!

Refresh會強制發送 SELECT 語句,以使 Session 緩存中對象的狀態和數據表中對應的記錄保持一致!

五、持久化對象的狀態

站在持久化的角度,Hibernate 把對象分爲 4 種狀態:Transient,Persist,Detached,Removed。Session 的特定方法能使對象從一個狀態轉換到另外一個狀態。

臨時對象(Transient):

在使用代理主鍵的狀況下,OID 一般爲 null

不處於 Session 的緩存中

在數據庫中沒有對應的記錄

持久化對象(也叫」託管」)(Persist):

OID 不爲 null

位於 Session 緩存中

對應性:若在數據庫中已經有和其對應的記錄,持久化對象和數據庫中的相關記錄對應

同步性:Session 在 flush 緩存時,會根據持久化對象的屬性變化,來同步更新數據庫

惟一性:在同一個 Session 實例的緩存中,數據庫表中的每條記錄只對應惟一的持久化對象。若是一個session的數據庫記錄有兩個對象,那麼以哪一個更新呢?因此是隻有一個。

遊離對象(也叫」脫管」) (Detached):相似於公司中員工請假了,不受公司管理,可是還屬於公司

OID 不爲 null

再也不處於 Session 緩存中

通常狀況需下,遊離對象是由持久化對象轉變過來的,所以在數據庫中可能還存在與它對應的記錄

刪除對象(Removed)

在數據庫中沒有和其 OID 對應的記錄

再也不處於 Session 緩存中

通常狀況下,應用程序不應再使用被刪除的對象

 

1. save() 方法

        * 1). 使一個臨時對象變爲持久化對象

        * 2). 爲對象分配 ID.

        * 3). 在 flush 緩存時會發送一條 INSERT 語句.

        * 4). 在 save 方法以前的 id 是無效的

        * 5). 持久化對象的 ID 是不能被修改的!

2. persist(): 也會執行 INSERT 操做

        * 和 save() 的區別 :

        * 在調用 persist 方法以前,若對象已經有 id 了,則不會執行 INSERT,而拋出異常

3. get VS load:

        * 1. 執行 get 方法:會當即加載對象

        *    執行 load 方法:若不使用該對象,則不會當即執行查詢操做,而返回一個代理對象

        *    get 是 當即檢索,load 是延遲檢索

        * 2. load 方法可能會拋出 LazyInitializationException 異常:在須要初始化

        * 代理對象以前已經關閉了 Session

        * 3. 若數據表中沒有對應的記錄,Session 也沒有被關閉

        *    get 返回 null

        *    load 若不使用該對象的任何屬性,沒問題。若須要初始化了,拋出異常

4. update:

        * 1. 若更新一個持久化對象,不須要顯示的調用 update 方法。由於在調用 Transaction的 commit() 方法時,會先執行 session 的 flush 方法

        * 2. 更新一個遊離對象,須要顯式的調用 session 的 update 方法。能夠把一個遊離對象變爲持久化對象

        * 須要注意的:

        * 1. 不管要更新的遊離對象和數據表的記錄是否一致,都會發送 UPDATE 語句

        *    如何能讓 update 方法再也不盲目的出發 update 語句呢 ? 在 .hbm.xml 文件的 class 節點設置

        *    select-before-update=true (默認爲 false)。但一般不須要設置該屬性

        * 2. 若數據表中沒有對應的記錄,但還調用了 update 方法,會拋出異常

        * 3. 當 update() 方法關聯一個遊離對象時

        * 若是在 Session 的緩存中已經存在相同 OID 的持久化對象,會拋出異常。由於在 Session 緩存中

        * 不能有兩個 OID 相同的對象!

5. saveOrUpdate:同時包含了save和update方法

 

6.delete: 執行刪除操做。只要 OID 和數據表中一條記錄對應,就會準備執行 delete 操做

        * 若 OID 在數據表中沒有對應的記錄,則拋出異常

        * 能夠經過設置 hibernate 配置文件 hibernate.use_identifier_rollback 爲 true

        * 使刪除對象後,把其 OID 置爲  null

       能夠在刪除方法調用後,將OID當即置爲null

7.evict: 從 session 緩存中把指定的持久化對象移除

六、調用存儲過程

Work 接口: 直接經過 JDBC API 來訪問數據庫的操做。

 

Session 的 doWork(Work) 方法用於執行 Work 對象指定的操做,即調用 Work 對象的 execute() 方法。Session 會把當前使用的數據庫鏈接傳遞給 execute() 方法

 

七、觸發器協同工做

Hibernate 與數據庫中的觸發器協同工做時,會形成兩類問題:

1)觸發器使 Session 的緩存中的持久化對象與數據庫中對應的數據不一致:觸發器運行在數據庫中,它執行的操做對 Session 是透明的。

即,session操做致使觸發器更改了數據庫內容,須要同步,要當即調用flush和refresh方法

2)Session 的 update() 方法盲目地激發觸發器:不管遊離對象的屬性是否發生變化,都會執行 update 語句,而 update 語句會激發數據庫中相應的觸發器。

所以,須要在映射文件的<class>元素中設置select-before-update屬性:當 Session 的 update 或 saveOrUpdate() 方法更新一個遊離對象時,會先執行 Select 語句,得到當前遊離對象在數據庫中的最新數據,只有在不一致的狀況下才會執行 update 語句。

八、hbm.xml文件

hibernate-mapping.xml

類層次:class

主鍵:id

基本類型:property

實體引用類: many-to-one  |  one-to-one

集合:set | list | map | array

one-to-many

many-to-many

子類:subclass | joined-subclass

其它:component | any 等

查詢語句:query(用來放置查詢語句,便於對數據庫查詢的統一管理和優化)

每一個Hibernate-mapping中能夠同時定義多個類。但更推薦爲每一個類都建立一個單獨的映射文件

 

1)class標籤中,dynamic-update:若設置爲 true,表示當更新一個對象時,會動態生成 update 語句,update 語句中僅包含全部取值須要更新的字段。默認值爲 false。

2)類型映射

 

 

九、時間類型的映射

在 Java 中,表明時間和日期的類型包括: java.util.Date 和 java.util.Calendar. 此外,在 JDBC API 中還提供了 3 個擴展了 java.util.Date 類的子類: java.sql.Date,java.sql.Time 和 java.sql.Timestamp,這三個類分別和標準 SQL 類型中的 DATE,TIME 和 TIMESTAMP 類型對應。

因此在持久化類中,應設置爲java.util.Date類型,這樣就能夠接收數據庫全部類型。

如何映射:type設置爲date、time、timestamp三類Hibernate類型

 

十、blob類型的映射

在 Java 中, java.lang.String 可用於表示長字符串(長度超過 255),字節數組 byte[] 可用於存放圖片或文件的二進制數據。此外,在 JDBC API 中還提供了 java.sql.Clob 和 java.sql.Blob 類型,它們分別和標準 SQL 中的 CLOB 和 BLOB 類型對應。CLOB 表示字符串大對象(Character Large Object),BLOB表示二進制對象(Binary Large Object)。

 

 

 

 

 

十一、組成關係映射

問題來源:創建域模型和關係數據模型有着不一樣的出發點:

域模型:由程序代碼組成,經過細化持久化類的粒度可提升代碼的可重用性,簡化編程。

類,越多越細化越好

 

在沒有數據冗餘的狀況下,應該儘量減小表的數目,簡化表之間的參照關係,以便提升數據的訪問速度。

數據表,越少越好

 

Hibernate 把持久化類的屬性分爲兩種:

值(value)類型:沒有 OID,不能被單獨持久化,生命週期依賴於所屬的持久化類的對象的生命週期

實體(entity)類型:有 OID,能夠被單獨持久化,有獨立的生命週期

顯然沒法直接用 property 映射 pay 屬性

Hibernate 使用 <component> 元素來映射組成關係,該元素表名 pay 屬性是 Worker 類一個組成部分,在 Hibernate 中稱之爲組件。

 

十二、一對多關聯關係

在領域模型中,類與類之間最廣泛的關係就是關聯關係。

在 UML 中,關聯是有方向的。以 Customer 和 Order 爲例: 一個用戶能發出多個訂單,而一個訂單隻能屬於一個客戶。從 Order 到 Customer 的關聯是多對一關聯;而從 Customer 到 Order 是一對多關聯。

單向關聯

n-1:order裏面有一個對customer的引用

1-n:customer中有order的集合的引用

雙向關聯

 

 

1)單向n-1

單向 n-1 關聯只需從 n 的一端能夠訪問 1 的一端。

域模型:從 Order 到 Customer 的多對一單向關聯須要在Order 類中定義一個 Customer 屬性,而在 Customer 類中無需定義存放 Order 對象的集合屬性。

 

關係數據模型:ORDERS 表中的 CUSTOMER_ID 參照 CUSTOMER 表的主鍵

 

在order.hbm.xml中配置

 

Session.save()保存的時候須要先保存一customer的一端。

查詢多的一端order的時候,進行了延遲加載,沒有查出一的customer一端。若先關閉了session再使用customer會報懶加載異常LazyInitalizationException。

在不設定級聯關係下,刪除一的customer一端會報錯。

2)雙向n-1

雙向 1-n 與 雙向 n-1 是徹底相同的兩種情形

雙向 1-n 須要在 1 的一端能夠訪問 n 的一端,反之依然.

域模型:從 Order 到 Customer 的多對一雙向關聯須要在Order 類中定義一個 Customer 屬性,而在 Customer 類中需定義存放 Order 對象的集合屬性。

 

關係數據模型:ORDERS 表中的 CUSTOMER_ID 參照 CUSTOMER 表的主鍵。和上面的數據表設計同樣。

 

 

在java,Customer類中這樣設置:

 

在Customer.hbm.xml中這樣配置:

 

3)1-1

1對1關聯關係,利用了多對一關聯關係來創建。域模型:一個部門只能有一個領導,一個領導也只能管理一個部門。

 

關係數據庫模型,有兩種:

1、按照外鍵映射,利用多對一,可是多的那一端須要加上unique關鍵字。即在配置many-to-one那一端會有一個外鍵生成。

 

配置以下:

Department.hbm.xml

 

Manager.hbm.xml,注意須要property-ref屬性指定出了所關聯實體主鍵之外的關聯字段!!!左外鏈接

 

2、按照主鍵映射

 

基於主鍵的映射策略:指一端的主鍵生成器使用 foreign 策略,代表根據」對方」的主鍵來生成本身的主鍵,本身並不能獨立生成主鍵。 <param> 子元素指定使用當前持久化類的哪一個屬性做爲 「對方」。

Department.hbm.xml中配置。注意是當前持久化類的哪個屬性做爲主鍵配置!!!

 

在Manager.hbm.xml中配置

 

3)單向多對多

域模型:商品,列表。一個商品能夠屬於多個列表類,一個列表類也能夠有多個商品。

 

關係數據模型:

 

 

 

 

 

在Category.hbm.xml中配置

 

在Item.hbm.xml中配置

 

1三、繼承關係映射

子類和父類公用一張數據表。父類中沒有的字段值爲空。有一列爲TYPE辨別者列,做爲類型區分。

對於面向對象的程序設計語言而言,繼承和多態是兩個最基本的概念。Hibernate 的繼承映射能夠理解持久化類之間的繼承關係。例如:人和學生之間的關係。學生繼承了人,能夠認爲學生是一個特殊的人,若是對人進行查詢,學生的實例也將被獲得。

1)使用 subclass 進行映射:將域模型中的每個實體對象映射到一個獨立的表中,也就是說不用在關係數據模型中考慮域模型中的繼承關係和多態。

只用配置父類Person.hbm.xml文件

 

 

 

 

2)使用 joined-subclass 進行映射: 對於繼承關係中的子類使用同一個表,這就須要在數據庫表中增長額外的區分子類類型的字段。

 

 

 

3)使用  union-subclass 進行映射:域模型中的每一個類映射到一個表,經過關係數據模型中的外鍵來描述表之間的繼承關係。這也就至關於按照域模型的結構來創建數據庫中的表,並經過外鍵來創建表之間的繼承關係。

 

 

1四、hibernate檢索方式

導航對象圖檢索方式:根據已經加載的對象導航到其餘對象。好比,customer獲得order

OID 檢索方式:按照對象的 OID 來檢索對象,get,lod

HQL 檢索方式:使用面向對象的 HQL 查詢語言

QBC 檢索方式:使用 QBC(Query By Criteria) API 來檢索對象。這種 API 封裝了基於字符串形式的查詢語句,提供了更加面向對象的查詢接口。

本地 SQL 檢索方式:使用本地數據庫的 SQL 查詢語句。

 

1)HQL

HQL(Hibernate Query Language) 是面向對象的查詢語言,它和 SQL 查詢語言有些類似。在 Hibernate 提供的各類檢索方式中,HQL 是使用最廣的一種檢索方式。它有以下功能:

在查詢語句中設定各類查詢條件

支持投影查詢,即僅檢索出對象的部分屬性

支持分頁查詢

支持鏈接查詢

支持分組查詢,容許使用 HAVING 和 GROUP BY 關鍵字

提供內置彙集函數,如 sum(),min() 和 max()

支持子查詢

支持動態綁定參數

可以調用 用戶定義的 SQL 函數或標準的 SQL 函數

 

 

2)QBC 查詢就是經過使用 Hibernate 提供的 Query By Criteria API 來查詢對象,這種 API 封裝了 SQL 語句的動態拼裝,對查詢提供了更加面向對象的功能接口

3)本地SQL查詢來完善HQL不能涵蓋全部的查詢特性

相關文章
相關標籤/搜索