Spring Data Overview
Spring Data の使命 は、基盤 となるデータストアの特性 を維持 しながら、データアクセスのための親 しみやすく一貫性 のある Spring ベースのプログラミングモデルを提供 することです。
JPA
N+1 Query Problem
リンク : Annotations Notes
遅延 関連 をマップされた関連 のメソッド呼 び出 しで初期化 すると、追加 のクエリが発生 します。 パフォーマンス上 の理由 から、これは避 けるべきです。
- 解決策
- SQL :
- JOIN
- JOIN FETCH : (JPQL)
- Eager Fetching
- Entity Graph
- Named Entity Graphs : 定義 したグラフをコードで再利用 する場合 に良 い解決策
- Dynamic Entity Graphs : ユースケース固有 のグラフを定義 する必要 がある場合 により良 い解決策
- DTO projection
- SQL :
NamedEntityGraph
Init
List<Menu> menus = List.of(
Menu.builder().id(1).menuName("System Management").build(),
Menu.builder().id(2).menuName("User Management").parentId(1).build(),
Menu.builder().id(3).menuName("Role Management").parentId(1).build(),
Menu.builder().id(4).menuName("Statistics Report").build(),
Menu.builder().id(5).menuName("Statistics by Month").parentId(4).build()
);
menuRepository.saveAll(menus);Entity
| |
Repository
| |
Queries Problem
| |
output
Hibernate: select m1_0.id,m1_0.menu_name,m1_0.parent_id from menu m1_0 where m1_0.parent_id is null
Parent Id is null - Menu count = 2
Hibernate: select cl1_0.parent_id,cl1_0.id,cl1_0.menu_name from menu cl1_0 where cl1_0.parent_id=?
Menu name = System Management - sub menu count = 2
Hibernate: select cl1_0.parent_id,cl1_0.id,cl1_0.menu_name from menu cl1_0 where cl1_0.parent_id=?
Menu name = Statistics Report - sub menu count = 1Entity
| |
Repository
| |
Solution-1
| |
output
Hibernate: select m1_0.id,cl1_0.parent_id,cl1_0.id,cl1_0.menu_name,m1_0.menu_name,m1_0.parent_id from menu m1_0 left join menu cl1_0 on m1_0.id=cl1_0.parent_id where m1_0.parent_id is null
Parent Id is null - Menu count = 2
Menu name = System Management - sub menu count = 2
Menu name = Statistics Report - sub menu count = 1JOIN FETCH
data.sql
insert into posts (id, title, content, author)
values (1, 'Post Title 1', 'Post content 1', 'Mr. J');
insert into posts (id, title, content, author)
values (2, 'Post Title 2', 'Post content 2', 'Mr. J');
insert into posts (id, title, content, author)
values (3, 'Post Title 3', 'Post content 3', 'Mr. J');
insert into posts (id, title, content, author)
values (4, 'Post Title 4', 'Post content 4', 'Mr. J');
insert into posts (id, title, content, author)
values (5, 'Post Title 5', 'Post content 5', 'Mr. J');
insert into comments (id, content, author, post_id)
values (1, 'Comment on Post-1 ', 'Mr. J', 1);
insert into comments (id, content, author, post_id)
values (2, 'Comment on Post-1 ', 'Mr. J', 1);
insert into comments (id, content, author, post_id)
values (3, 'Comment on Post-2 ', 'Mr. J', 2);
insert into comments (id, content, author, post_id)
values (4, 'Comment on Post-3 ', 'Mr. J', 3);
insert into comments (id, content, author, post_id)
values (5, 'Comment on Post-4 ', 'Mr. J', 4);
insert into comments (id, content, author, post_id)
values (6, 'Comment on Post-4 ', 'Mr. J', 4);
insert into comments (id, content, author, post_id)
values (7, 'Comment on Post-4 ', 'Mr. J', 4);
insert into comments (id, content, author, post_id)
values (8, 'Comment on Post-5 ', 'Mr. J', 5);Entity
| |
Entity
| |
Repository
| |
Queries Problem
| |
output
Hibernate: select c1_0.id,c1_0.author,c1_0.content,c1_0.post_id from comments c1_0
... Comment count = 8
Hibernate: select p1_0.id,p1_0.author,p1_0.content,p1_0.title from posts p1_0 where p1_0.id=?
... Comment [Comment on Post-1 ] from Post [Post Title 1]
... Comment [Comment on Post-1 ] from Post [Post Title 1]
Hibernate: select p1_0.id,p1_0.author,p1_0.content,p1_0.title from posts p1_0 where p1_0.id=?
2024-03-27T12:26:15.217+08:00 ... Comment [Comment on Post-2 ] from Post [Post Title 2]
Hibernate: select p1_0.id,p1_0.author,p1_0.content,p1_0.title from posts p1_0 where p1_0.id=?
... Comment [Comment on Post-3 ] from Post [Post Title 3]
Hibernate: select p1_0.id,p1_0.author,p1_0.content,p1_0.title from posts p1_0 where p1_0.id=?
... Comment [Comment on Post-4 ] from Post [Post Title 4]
... Comment [Comment on Post-4 ] from Post [Post Title 4]
... Comment [Comment on Post-4 ] from Post [Post Title 4]
Hibernate: select p1_0.id,p1_0.author,p1_0.content,p1_0.title from posts p1_0 where p1_0.id=?
... Comment [Comment on Post-5 ] from Post [Post Title 5]Solution-1
| |
output
Hibernate: select c1_0.id,c1_0.author,c1_0.content,p1_0.id,p1_0.author,p1_0.content,p1_0.title from comments c1_0 join posts p1_0 on p1_0.id=c1_0.post_id
...Comment count = 8
...Comment [Comment on Post-1 ] from Post [Post Title 1]
...Comment [Comment on Post-1 ] from Post [Post Title 1]
...Comment [Comment on Post-2 ] from Post [Post Title 2]
...Comment [Comment on Post-3 ] from Post [Post Title 3]
...Comment [Comment on Post-4 ] from Post [Post Title 4]
...Comment [Comment on Post-4 ] from Post [Post Title 4]
...Comment [Comment on Post-4 ] from Post [Post Title 4]
...Comment [Comment on Post-5 ] from Post [Post Title 5]