[TOC]
# Hibernate優化方案
## HQL優化
1.使用參數綁定
1.使用綁定參數的原因是讓數據庫一次解析SQL,對后續的重復請求可以使用用生成好的執行計劃,這樣做節省CPU時間和內存。
2.避免SQL注入
2.盡量少使用NOT
如果where子句中包含not關鍵字,那么執行時該字段的索引失效。
3.盡量使用where來替換having
Having在檢索出所有記錄后才對結果集進行過濾,這個處理需要一定的開銷,而where子句限制記錄的數目,能減少這方面的開銷
4.減少對表的查詢
在含有子查詢的HQL中,盡量減少對表的查詢,降低開銷
5.使用表的別名
當在HQL語句中連接多個表時,使用別名,提高程序閱讀性,并把別名前綴與每個列上,這樣一來,可以減少解析時間并減少列歧義引起的語法錯誤。
6.實體的更新與刪除
在hibernate3以后支持hql的update與delete操作

### 一級緩存優化
一級緩存也叫做session緩存,在一個hibernate session有效,這級緩存的可干預性不強,大多于hibernate自動管理,但它提供清除緩存的方法,這在大批量增加(更新)操作是有效果的,例如,同時增加十萬條記錄,按常規進行,很可能會出現異常,這時可能需要手動清除一級緩存,session.evict以及session.clear.
## 檢索策略(抓取策略)
### 延遲加載
延遲加載 是hibernate為提高程序執行的效率而提供的一種機制,即只有真正使用該對象的數據時才會創建。
load方法采用的策略延遲加載.
get方法采用的策略立即加載。
檢索策略分為兩種:
1. 1. 類級別檢索
2. 2. 關聯級別檢索
### 類級別檢索
類級別檢索是通過session直接檢索某一類對應的數據,例如
Customer c=session.load(Customer.class,1)
Session.createQuery(“from Order”)
類級別檢索策略分為立即檢索與延遲檢索,默認是延遲檢索,類級別的檢索策略可以通過<class>元素的lazy屬性來設置 ,默認值是true
在hbm配置文件中設置

### 關聯級別檢索
查詢到某個對象,獲得其關聯的對象或屬性,這種稱為關聯級別檢索,例如
c.getOrders().size()
c.getName()
對于關聯級別檢索我們就要研究其檢索策略(抓取策略)
### 抓取策略介紹
指的是查找到某個對象后,通過這個對象去查詢關聯對象的信息時的一種策略。
一對一 `<one-to-one>`
一對多(多對一) `<set>`下有`<one-to-many> <many-to-one>`
多對多` <set>`下有`<many-to- many>`
我們主要是在`<set>`與`<many-to-one>`或`<one-to-one>`上設置fetch lazy
例如:查詢一個客戶,要關聯查詢它的訂單
客戶是一的一方,在客戶中有set集合來描述其訂單,在配置中我們是使用
~~~
<set>
<one-to-many>
</set>..
~~~
可以在set標簽上設置兩個屬性 fetch lazy
Fetch主要描述的是SQL語句的格式(例如是多條,子查詢,多表聯查
Lazy 控制SQL語句何時發送
例如:在查詢一個訂單時,要查詢客戶信息
`<many-to-one> 或<one-to-one>`
也可以設置fetch lazy
Fetch主要描述的是SQL語句的格式(例如是多條,子查詢,多表聯查
Lazy 控制SQL語句何時發送
總結:
講解抓取策略
在兩方面設置
~~~
<set fetch="" lazy="">
<many-to-one fetch="" lazy="">
<one-to-one>
~~~
### 注解配置抓取策略
問題:如何使用注解來設置
在`<setse>`設置的fetch與lazy可以使用下面注解來描述

## set上的fetch與lazy
set上的fetch與lazy它主要是用于設置關聯的集合信息的抓取策略。
Fetch可取值有:
1. SELECT 多條簡單的sql (默認值)
2. JOIN 采用迫切左外連接
3. SUBSELECT 將生成子查詢的SQL
lazy可取值有:
1. TURE 延遲檢索 (默認值)
2. FALSE 立即檢索
3. EXTRA 加強延遲檢索(及其懶惰)

### 第一種組合

### 第二種組合

### 第三種組合

當查詢客戶信息時,不會查詢訂單信息,當需要訂單的個數時,也不會查詢訂單信息,
只會通過count來統計訂單個數。
當我們使用size(),contains()或isEmpty()方法時不會查詢訂單信息。
### 第四種組合
如果fetch選擇的是join方案,那么lazy它會失效。
生成SQl將采用的是迫切左外連接(left outer join fetch)
會立即查詢。

### 第5種組合

會生成子查詢,但是我們在查詢訂單時采用的是延遲加載。
### 第6種組合

會生成子查詢,在查詢客戶信息時,就會將訂單信息也查詢出來
### 第七種組合

在查詢訂單時,只會根據情況來確定是否要訂單信息,如果不需要,例如我們
程序中size操作,那么就會發出`select count(*) from Order where c_customer_id=?`
### 結論


no-session問題解決?
擴大session作用范圍

## One的一言fetch與lazy
`<set fetch lazy>`它主要是設置在獲取到一的一方時,如果去查詢多的一方。
在`<many-to-one>或<one-to-one>`如果去查詢對方。
對于程序 就是在多的一方如何查詢一的主方信息
例如:獲取到一個訂單對象,要查詢客戶信息。
Fetch可取值:
select 默認值,代表發送一條或多條簡單的select語句
join 發送一條迫切左外連接
lazy可取值
false 不采用延遲加載
proxy 默認值 是否采用延遲,需要另一方的類級別延遲策略來決定
no-proxy 不用研究

### 第一種組合

當我們執行時,會首先發送一條sql只查詢訂單信息,客戶信息會延遲,只有真正需要客戶信息時,才會發送sql來查詢客戶信息.
### 第二種組合

### 第三種組合

### 第四種組合

## 批量抓取
我們在查詢多個對象的關聯對象時,可以采用批量抓取方式來對程序進行優化.
要想實現批量抓取:
可以在配置文件中 batch-size屬性來設置
可以使用注解 @BatchSize(size=4)
可以采用批量抓取來解決N+1問題.
抓取客戶的時候一次抓取幾個聯系人
查詢客戶,查詢訂單

查詢訂單,查詢客戶


- 基礎
- 編譯和安裝
- scanner類(鍵盤錄入)
- Random類(隨機數)
- 數組
- 方法
- 類
- ArrayList集合
- char與int
- eclipse
- IDEA
- 變量與常量
- 常用API
- String,StringBuffer,StringBuilder
- 正則,Date,DateFormat,Calendar
- 包裝類,System,Math,Arrays,BigInteger,BigDecimal
- 集合,迭代器,增強for,泛型
- List,set,判斷集合唯一
- map,Entry,HashMap,Collections
- 異常
- IO
- File
- 遞歸
- 字節流
- 字符流
- IO流分類
- 轉換流
- 緩沖流
- 流的操作規律
- properties
- 序列化流與反序列化流
- 打印流
- commons-IO
- IO流總結
- 多線程
- 線程池
- 線程安全
- 線程同步
- 死鎖
- lock接口
- ThreadLoad
- 等待喚醒機制
- 線程狀態
- jdbc
- DBUtils
- 連接池DBCP
- c3p0連接池
- 網絡編程
- 多線程socket上傳圖片
- 反射
- xml
- 設計模式
- 裝飾器模式
- web service
- tomcat
- Servlet
- response
- request
- session和cookie
- JSP
- EL
- JSTL
- 事務
- 監聽器Listener
- 過濾器Filter
- json
- linux安裝軟件
- 反射詳解
- 類加載器和注解
- 動態代理
- jedis
- Hibernate
- 簡介
- 創建映射文件
- Hibernate核心配置文件
- 事務和增刪改查
- HibernateUtils
- 持久化對象的三種狀態
- 檢索方式
- query
- Criteria
- SQLQuery
- 持久化類
- 主鍵生成策略
- 緩存
- 事務管理
- 關系映射
- 注解
- 優化
- struts2
- 搭建
- 配置詳解
- Action
- 結果跳轉方式
- 訪問ServletAPI方式
- 如何獲得參數
- OGNL表達式
- valueStack 值棧
- Interceptor攔截器
- spring
- 導包
- IOC和DI
- Bean獲取與實例化
- Bean屬性注入
- spring注解
- 注解分層
- junit整合
- aop
- 動態代理實現
- cglib代理實現
- aop名詞
- spring的aop
- aop-xml詳解
- aop-注解詳解
- 代理方式選擇
- jdbcTemplate
- spring事務管理
- 回滾注意
- 事務傳播屬性
- MyBatis
- MyBatis簡介
- 入門程序
- 與jdbc hibernate不同
- 原始Dao開發
- Mapper動態代理方式
- SqlMapConfig.xml配置文件
- 輸入參數pojo包裝類
- resultMap
- 動態sql
- 一對一關聯
- 一對多
- 整合spring
- 逆向工程
- maven
- maven簡介
- 倉庫
- maven目錄結構
- maven常用命令
- 生命周期
- eclipse中maven插件
- 入門程序
- 整合struct
- 依賴范圍
- 添加插件
- idea配置
- jar包沖突
- 分模塊開發
- 構建可執行的jar包(包含依賴jar包)
- springMVC
- 處理流程
- java面試
- java版本升級
- java1-8版本變更
- java9新特性
- 鎖
- java資料
- idea
- jdk版本切換
- log4j
- 入門實例
- 基本使用方法
- Web中使用Log4j
- spring中使用log4j
- java代碼優化