a物件關聯b物件,a物件進行列表展示時需顯示b物件的關聯屬性,這樣需要先用一條sql將n個a物件查詢出來,再用n條sql將這些物件的關聯屬性查詢出來。違背了減少資料庫互動原則,影響效能。
千萬不要在for迴圈裡面進行sql查詢操作
就像下面我當初寫的破**
trainclassvolist.
foreach
(trainclassvo -
>
}// 取證率%
numberformat numberformat = numberformat.
getinstance()
;// 設定精確到小數點後2位
numberformat.
setmaximumfractiondigits(2
);if(stucertificatenum !=
0&& trainstumun !=0)
else
// 獲取學時未完**數
long count = trainclassstulist.
stream()
.filter
(trainclassstudent -
> trainclassstudent.
getstudystatus()
.equals
("1"))
.count()
; trainclassvo.
settrainstunoendmun
(count)
;}
2.解決方法
方法一:連線查詢,在查詢a物件的時候,將關聯的b物件查詢出來。缺點:1、連線的表增加,sql效能下降;2、如果n個a物件關聯的是同乙個b物件,會使結果集非常龐大,返回結果集需要消耗效能,並且影響排序效能。比如100個employee都關聯dept id 1,本來dept的資料只需出現一次,這裡為了避免n+1,重複出現100次。
方法二:a表中設定冗餘字段。缺點:更新b表需要更新a表。更新a表時需要增加修改b物件屬性的邏輯。這個方法最好別用,有時候會存在忘記更新資料的情況。
方法三:效能最佳,1+1查詢。先用sql查出所有employee查詢出,將他們關聯的deptid放到乙個set中,再發一條sql,deptid in set 將所有dept查出,之後在程式中將deptset 進入employee。
下面是我重構的**,展示部分
list
deptidlist = trainclassvolist.
stream()
.map
(trainclassvo:
:getcreatedept)
.collect
(collectors.
tolist()
);// 培訓機構資訊列表
map> map =
newhashmap
<
>()
;if(deptidlist.
size()
>0)
);}
sql:
"getinfobydeptidlist"
parametertype
="list"
resulttype
="com.gl.train.api.entity.commorgaudit"
>
select
coa.id,coa.dept_id,coa.org_name,coa.org_unit_name
from
comm_org_audit coa
where coa.dept_id in
collection
="list"
separator
=","
open
="("
close
=")"
item
="item"
>
#foreach
>
select
>
Hibernate解決n 1問題
觀點 對於n 1問題的理解。一般而言說n 1意思是,無論在一對多還是多對一當查詢出n條資料之後,每條資料會關聯的查詢1次他的關聯物件,這就叫做n 1。但是我的理解是,本來所有資訊可以一次性查詢出來,也就是簡單的連表查詢,但是hibernate會首先查詢1次得到當前物件,然後當前物件裡面的n個關聯物件...
n 1次select查詢問題
什麼叫n 1次select查詢問題?在session的快取中存放的是相互關聯的物件圖。預設情況下,當hibernate從資料庫中載入customer物件時,會同時載入所有關聯的order物件。以customer和order類為例,假定orders表的customer id外來鍵允許為null,圖1列...
HIBERNATE的N 1查詢問題
在session的快取中存放的是相互關聯的物件圖。預設情況下,當hibernate從資料庫中載入customer物件時,會同時載入所有關聯的order物件。以customer和order類為例,假定orders表的customer id外來鍵允許為null,圖1列出了customers表和order...