QueryDSL์ ์ด์ฉํด ๋ค์ค ํด์ํ๊ทธ ์กฐํํ๊ธฐ
ํดํผํ์ฐ์ค ๋์ ๋์ผํ๊ฒ ํ๊ทธ ์๋น์ค๋ฅผ ์ ๊ณตํ์ฌ ํํฐ๋ฃธ ํ ๋ง๋ฅผ ๊ตฌ๋ถํ๊ณ ๋ชฉ์ ์ ๋ฐ๋ฅธ ์กฐํ๋ฅผ ์ฝ๊ฒ ๋ง๋ค๊ณ ์ถ์๋ค.
Spring + JPA ํ๊ฒฝ์์ ํ๊ทธ ์๋น์ค๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด ๊ณ ๋ คํด์ผ ํ ๋ถ๋ถ์ด 2๊ฐ์ง๊ฐ ์๋๋ฐ ๋ฐ๋ก ๋ค๋๋ค ๊ด๊ณ๋ฅผ ์งํค๋ ๊ฒ, ๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ jpa์ ๋ง๊ฒ ๋งคํํ๋ ๊ฒ์ด๋ผ๊ณ ๋งํ๊ณ ์ถ๋ค.
๊ฐ๋จํด ๋ณด์ฌ๋ ๋ง์ ๊ตฌํํ๋ค๋ณด๋ฉด ๋ณต์กํ๋ ์ด๋ฒ์ ์ ์ ๋ฆฌํด๋๊ณ ๋ค์์ ๋ค์ ์ฐพ์๋ณด๊ณ ์ ํ๋ค!
ํ ์ด๋ธ ๊ตฌ์ฑํ๊ธฐ
์ฐ๊ฒฐ ํ ์ด๋ธ(Join Table)
์ฐฌ์ฐฌํ ์๊ฐํด๋ณด์.
ํํฐ๋ฃธ์ ์ค๋ช ํ๊ธฐ ์ํ ์๋จ์ผ๋ก ํด์ํ๊ทธ๋ฅผ ์ค์ ํ๊ธฐ ์ํด์๋ ํ๋์ ํํฐ๋ฃธ์ ์ฌ๋ฌ๊ฐ์ ํด์ํ๊ทธ๋ฅผ ๊ฑธ์ด ๊ฐ๊ฐ์ ํด์ํ๊ทธ๊ฐ ๊ฐ์ง ์๋ฏธ๋ฅผ ์กฐํฉํด ํํฐ๋ฃธ์ ์๊ฐํ๋ ๊ฒ์ด ์ข๋ค. ์ฆ, ํ๋์ ํํฐ๋ฃธ์ ์ฌ๋ฌ๊ฐ์ ํด์ํ๊ทธ๋ฅผ ๋ฌ๊ณ ์ถ๋ค๋ ๋ง์ด๋ค.
๋ฐ๋๋ก ํ๋์ ํด์ํ๊ทธ๋ฅผ ๋๊ณ ๋ณด๋ฉด ์ด๋จ๊น? #๋ถ๊ธ
์ด๋ผ๋ ํด์ํ๊ทธ๊ฐ ๊ผญ ํ๋์ ํํฐ๋ฃธ์์๋ง ์ฌ์ฉ๋์ด์ผํ ๊น? ๋ง์ฝ ๊ทธ๋ ๋ค๋ฉด #๋ถ๊ธ
ํด์ํ๊ทธ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์ฌ๋๋ค์ ์์์ผ๋ถํฐ ๋ฏธ๋ฆฌ ํํฐ๋ฃธ์ ๋ง๋ค์ด๋์์ผ ํ ์ง๋ ๋ชจ๋ฅธ๋ค. ํด์ํ๊ทธ ์
์ฅ์์ ๋ณด๋ฉด ํ๋์ ํด์ํ๊ทธ๋ ์ฌ๋ฌ๊ฐ์ ํํฐ๋ฃธ์ ์ค์ ๋ ์ ์์ ๊ฒ์ด๋ค.
๋ฐ๋ผ์ ํํฐ๋ฃธ๊ณผ ํด์ํ๊ทธ๋ ๋ค๋๋ค(n:m) ๊ด๊ณ๋ฅผ ๊ฐ์ง๋ค. ๋ค๋๋ค ๊ด๊ณ๋ ํด์๋์ด์ผํ๋ค. ํ ์ด๋ธ ๋ด์์ ๋ฐ์ดํฐ์ ์ค๋ณต์ด ๋ฐ์ํ๊ณ ํ ์ด๋ธ์ด ๋ณต์กํด์ง๋ฉฐ ์กฐํ๊ฐ ์ด๋ ค์์ง๊ธฐ๋๋ฌธ์ด๋ค. ์ด ๊ด๊ณ๋ฅผ ํด์ํ๊ธฐ ์ํด์๋ ํํฐ๋ฃธ๊ณผ ํด์ํ๊ทธ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ฐ ํ๋์ฉ ์ฐ๊ฒฐํด์ฃผ๋ ์ญํ ์ด ํ์ํ๊ณ , ์ด ์ญํ ์ ํ๋ ๊ฒ์ด ์ฐ๊ฒฐ ํ ์ด๋ธ(์กฐ์ธ ํ ์ด๋ธ)์ด๋ค. ๊ณ ์ ๋ ํ ์ด๋ธ์ ์ฐ๊ฒฐํด์ฃผ๋ ์ฉ๋๋ก ํ ์ด๋ธ์ ์๋กญ๊ฒ ๋ง๋๋ ๊ฒ์ด ์ด์ํ๊ฒ ๋ค๋ฆด์ง ๋ชฐ๋ผ๋ ์ด ํ ์ด๋ธ์ ์ญํ ์ ์ด๋ง์ด๋งํ๋ค.
์ฐ๊ฒฐ ํ ์ด๋ธ ๋๋ถ์ ํํฐ๋ฃธ๊ณผ ํด์ํ๊ทธ ๋ด๋ถ์๋ ๋ณต์กํ ๋์ ๊ด๊ณ๋ ๋นผ๋ด๊ณ ๊ฐ๊ฐ ์์ ์ ๊ณ ์ ํ ์ ๋ณด๋ง์ ๋ณด์ ํ ์ ์๋ค. room_tag ํ ์ด๋ธ์๋ ํํฐ๋ฃธ id์ ํด์ํ๊ทธ id๋ฅผ ํ๋์ฉ ์ฐ๊ฒฐํ์ฌ ํ๋์ ๋ฐฉ์ ์ค์ ๋๋ ํด์ํ๊ทธ๋ฅผ ๋ชจ๋ ์ ์ฅํ๊ณ , ๋ฐ๋๋ก ํ๋์ ํด์ํ๊ทธ๋ ์ฌ๋ฌ ํํฐ๋ฃธ์ ์ค์ ๋์๋ ๊ด๊ณ๋ฅผ ํํํ์ฌ ์ ์ฅํ ์ ์๋ค.
์ฟผ๋ฆฌ๋ฌธ ์์ฑ
์ํ๊น๊ฒ๋ ๋ฌธ์ ์ ์์์ ์ฌ๊ธฐ์๋ถํฐ๋ค.
์๋น์ค๋ฅผ ์ด์ฉํ๋ ์ฌ์ฉ์๋ #๋ถ๊ธ
์ด๋ผ๋ ํด์ํ๊ทธ์ #์ผ๊ทผ
์ด๋ผ๋ ํด์ํ๊ทธ๋ฅผ ์กฐํฉํ์ฌ ๋น๋ก ๊ธ์์ผ์ ์ผ๊ทผ ์ค์ด์ง๋ง ์์ ๊ณผ ๊ฐ์ ์ฒ์ง์ ์ฌ๋๋ค๊ณผ ๋ด์ ํฅ ๋ฐ์ฐ ํํฐ๋ฅผ ์ฆ๊ธฐ๊ณ ์ถ์ ์ ์๋ค. ๋ง์ฝ #๋ถ๊ธ
๋๋ #์ผ๊ทผ
์ด๋ผ๋ ํด์ํ๊ทธ๋ฅผ ์ค์ ํ ํํฐ๋ฃธ์ ๋ชจ๋ ๋ฐํํ๋ค๋ฉด ์ด๋ค ํํฐ๋ฃธ์ ๋ค์ด๊ฐ ์๋ ์์ ์ ๋๋ก ์๋๋ฌ์ธ ๊ฒ์ด๊ณ , ์ด๋ค ํํฐ๋ฃธ์ ํํฐ๋ฃธ์ ๊ฐ์ฅํ ์ฌ๋ด ํ์๋ฅผ ์งํํ๊ณ ์์ ์๋ ์๋ค. #๋ถ๊ธ
ํํฐ๋ฃธ๋ง ๋ฐํํด์๋ ์ ๋๊ณ #์ผ๊ทผ
ํํฐ๋ฃธ๋ง ๋ฐํํด์๋ ์ ๋๋ค. #๋ถ๊ธ
๊ณผ #์ผ๊ทผ
์ด๋ผ๋ ํ๊ทธ๋ฅผ ๋์์ ์ค์ ํ ํํฐ๋ฃธ๋ง ๋ฐํํด์ผ ํ๋ค. ์ฌ๊ธฐ์ ์ถ๊ฐ์ ์ผ๋ก ๋ค๋ฅธ ํ๊ทธ๊ฐ ๋ถ์ด์๋ ๊ฒ์ ์๊ด์ด ์๋ค.
roomtag ์ฐ๊ฒฐ ํ
์ด๋ธ์์ ํํฐ๋ฃธ์ ์กฐํํ๊ณ ์ถ์ง๋ง #๋ถ๊ธ
๊ณผ #์ผ๊ทผ
์ด๋ผ๋ ํ๊ทธ๋ฅผ ๋ชจ๋ ์ค์ ํ ํํฐ๋ฃธ์ด์ด์ผ ํ๋ค. ํฉ์งํฉ์ด ์๋๋ผ ๊ต์งํฉ์ด์ด์ผ ํ๋ ๊ฒ์ด๋ค. roomtag ํ
์ด๋ธ์ ๊ฐ ํ์ ํ๋์ ๋ฐฉ๊ณผ ํ๋์ ํด์ํ๊ทธ๋ง์ ์ฐ๊ฒฐํ๊ณ ์๊ธฐ๋๋ฌธ์ ๋จ์ํ AND
์ฐ์ฐ์ ์ทจํ๋ค๊ณ ํด๊ฒฐ๋ ์ผ์ด ์๋๋ค. ๊ฐ ํ์ #๋ถ๊ธ
๊ณผ #์ผ๊ทผ
์ด๋ผ๋ ํด์ํ๊ทธ๋ฅผ ๋์์ ์๋ฏธํ ์ ์๋ค(์ ์ด์ ๋ค๋๋ค ๊ด๊ณ๋ฅผ ํด์ํ๊ธฐ ์ํ ๋ชฉ์ ์ด์์ผ๋ฏ๋ก ๋น์ฐํ๋ค).
๊ทธ๋ ๋ค๋ฉด ๋ค์์ผ๋ก ์๊ฐํ๋ ๋ฐฉ๋ฒ์ #๋ถ๊ธ
ํ๊ทธ๋ฅผ ํฌํจํ๋ ๋ฐฉ ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ ๊ฐ์ ธ์ค๊ณ #์ผ๊ทผ
ํ๊ทธ๋ฅผ ํฌํจํ๋ ๋ฐฉ ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ ๊ฐ์ ธ์ JOIN
ํ๋ ๋ฐฉ๋ฒ์ด๋ค. ํ์ง๋ง ์ด ๋ฐฉ๋ฒ๋ ๋ถ๊ฐ๋ฅํ๋ค. ์ฌ์ฉ์๊ฐ ์กฐํฉํ๊ณ ์ถ์ ํ๊ทธ๊ฐ 2๊ฐ๋ฟ์ด๋ผ๋ ๋ณด์ฅ์ด ์์ผ๋ฉฐ ํ๊ทธ๊ฐ ๋์ด๋ ์๋ก JOIN
์ฐ์ฐ๋ ๋์ ์ผ๋ก ๋์ด๋์ผํ๋ค. ๐ฃโฆ
๊ฒฐ๊ตญ ์ฑํํ ์ ์๋ ์ฟผ๋ฆฌ๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ ํํ๊ฐ ๋๋ค.
SELECT room_id
FROM room_tag
WHERE tag_id in (1, 2, 3)
GROUP BY room_id
HAVING count(room_id) = 3;
WHERE
๋ฌธ์ in
์ฐ์ฐ์ ํตํด ์ํ๋ ํด์ํ๊ทธ์ ๊ด๋ จ๋ room_tag ์ ๋ณด๋ฅผ ๋ชจ๋ ๊ฐ์ ธ์จ๋ค. ์ฟผ๋ฆฌ๋ฌธ 3๋ฒ์งธ ๋ผ์ธ์ธ WHERE
๋ฌธ ๊น์ง๋ง ์คํํ๋ฉด A๋ฐฉ์์ 1, 2, 3์ ๋ชจ๋ ์ค์ ํ ๊ฒฝ์ฐ (A, 1), (A, 2), (A, 3)์ ํํ๋ก ๋ฐฉ ๋ฒํธ๊ฐ ์ค๋ณต์ ์ผ๋ก ์กฐํ๋ ๊ฒ์ด๋ค. B๋ฐฉ์์ 1, 2๋ฅผ ์ค์ ํ ๊ฒฝ์ฐ (B, 1), (B, 2)์ ๋ฐ์ดํฐ๊ฐ ์ถ๊ฐ๋์ด ์กฐํ๋ ๊ฒ์ด๋ค.
์คํ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ค๋ณด๋ฉด ํ๊ฐ์ง ์๊ฐ์ด ๋ ์ค๋ฅธ๋ค. ๋ฐฉ ๋ฒํธ๋ก ๋ฌถ์ด๋ฒ๋ฆฌ๊ณ ์ถ๋ค! (A, 1 2 3), (B, 1 2) ์ด๋ ๊ฒ ๋ง์ด๋ค. ์ด๋ฅผ ์ํ ์ฟผ๋ฆฌ๊ฐ ์ฟผ๋ฆฌ๋ฌธ 4๋ฒ์งธ ๋ผ์ธ์ธ GROUP BY
์ด๋ค.
์ฌ๊ธฐ์ ๋ฉ์ถ๋ค๋ฉด B๋ฐฉ์ 1, 2 ๋ฒ ํ๊ทธ๋ง ์ค์ ํ๋๋ฐ๋ ์กฐํ ๊ฒฐ๊ณผ์ ์ถ๊ฐ๋ ๊ฒ์ด๋ค. ๋ฐ๋ผ์ ์ค๋ก์ง 3๊ฐ์ง ํ๊ทธ๋ง์ ์ค์ ํ ๋ฐฉ์ ์ถ์ถํ๊ธฐ ์ํด HAVING
์กฐ๊ฑด์ ์ถ๊ฐํ๋ค. GROUP BY
๋ก ๊ทธ๋ฃนํํ ๊ฒฐ๊ณผ์ ์กฐ๊ฑด์ ์ถ๊ฐํ๋ ์ฉ๋์ด๋ค. ๊ฐ ๋ฐฉ์ผ๋ก ๊ทธ๋ฃนํํ ์ํ๋ก ๊ฐ ๋ฐฉ์ ํ๊ทธ ๊ฐ์๋ฅผ ๊ตฌํ๋ค๋ฉด ๊ฐ ๋ฐฉ์ ํ๊ทธ 1, 2, 3 ์ค ๋ช ๊ฐ์ง์ ํ๊ทธ๋ฅผ ์ค์ ํ๋์ง ์ ์ ์๋ค.
์กฐ๊ธ ๋ณต์กํ์ง๋ง join์ด๋ ์๋ธ์ฟผ๋ฆฌ ์ฐ์ฐ ์์ด ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ์ ์์๋ค.
JPA QueryDSL ๊ตฌํํ๊ธฐ
QueryDsl ๋ฐฉ์์ผ๋ก ์กฐํํ๊ธฐ
์์ ์ฟผ๋ฆฌ๋ฌธ์ ์์ฃผ ๋จ์ํ ํํ๋ ์๋๋ค. ์์ฃผ ๋จ์ํ ์กฐํ ์ฟผ๋ฆฌ๋ Query Method ๋ฐฉ์์ ์ด์ฉํด ๋ฉ์๋ ๋ช ์ผ๋ก ์๋์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค๋ฉด ์ฝ์ง๋ง, ์์ ์ฟผ๋ฆฌ๋ in ์ฒดํฌ๋ ํด์ผํ๊ณ ๊ทธ๋ฃนํ๋ ํด์ผํ๋ฉฐ ๊ทธ๋ฃนํ ๊ฒฐ๊ณผ์ ์กฐ๊ฑด๊น์ง ์ถ๊ฐ์ ์ผ๋ก ๋ฌ์์ค์ผ ํ๋ค. ๋ฐ๋ผ์ JPA๋ฅผ ํ์ฉํ ๋ฐฉ๋ฒ ์ค QueryDsl์ ์ด์ฉํ์ฌ ๊ฐ ์ฐ์ฐ์ ๋ฉ์๋๋ก ์ฒด์ด๋ํ์ฌ ๊ตฌํํ๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
JPA๋ ๋จ์ ์ฟผ๋ฆฌ mapper๊ฐ ์๋๋ค. ์ข ๋ ๊ฐ์ฒด์งํฅ์ ์ผ๋ก ์ ๊ทผํ์ฌ ์๋น์ค ํ๋ก๊ทธ๋จ์ ๊ฐ์ฒด์ DB ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ฒฐํด์ฃผ๋ ORM ์ด๋ค. ๊ทธ๋ฌ๋ฏ๋ก ์ฐ๋ฆฌ๋ ํ ์ด๋ธ์ pk ์ปฌ๋ผ์ด๋ id๋ฅผ ๊ธฐ์ค์ผ๋ก sql๋ฌธ์ ์๊ฐํ์ง ์๊ณ , ์ํฐํฐ ํด๋์ค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฉ์๋๋ฅผ ์๊ฐํด์ผ ํ๋ค.
์ฝ๋ ๋จผ์ ํ์ธํด๋ณด์.
// ์ํ์ฐฉ์ค ์ฝ๋
public Page<Room> getRoomByTag(List<Tag> hashtags, Pageable sort) {
JPQLQuery<Room> query = jpaQueryFactory.select(qRoomTag.room).from(qRoomTag)
.where(qRoomTag.tag.in(hashtags))
.groupBy(qRoom)
.having(qRoomTag.tag.count().eq((long) hashtags.size()));
List<Room> roomList = getQuerydsl().applyPagination(sort, query).fetch();
return new PageImpl<>(roomList, sort, query.fetchCount());
}
// ์์ฑ ์ฝ๋
public Page<Room> getRoomTagByTagName(String[] hashtags, Pageable sort) {
List<Room> roomList = jpaQueryFactory.select(qRoomTag.room).from(qRoomTag)
.where(qRoomTag.tag.tagName.in(hashtags))
.groupBy(qRoomTag.room)
.having(qRoomTag.tag.count().eq((long) hashtags.length)).fetch();
return new PageImpl<>(roomList, sort, query.fetchCount());
}
์ฒด์ด๋ํ์ฌ ์ฌ์ฉํ ๋ฉ์๋๋ง ๋ณด๋ฉด ์ฟผ๋ฆฌ๋ฌธ๊ณผ ๋์ผํ๋ค. ํ์ง๋ง ๋ด๊ฐ ์ค์ํ ๋ถ๋ถ์ ๋ณด๋ฉด sql ์ญํ ์ ํ๋ ๋ฉ์๋๊ฐ ๋ฌธ์ ๊ฐ ์๋๋ผ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด์งํฅ์ ์ผ๋ก ์๊ฐํ์ง ์์๊ธฐ๋๋ฌธ์ ๋ฐ์ํ ์ค์๋ผ๋๊ฑธ ์ ์ ์๋ค.
๋จผ์ ๊ฐ์ฅ ๋ฐ๊นฅ ์ค์ฝํ์ 2๊ฐ์ง ๋ฉ์๋๋ฅผ ๋ณด์. ๋ ๋ฉ์๋๋ ๋งค๊ฐ๋ณ์๋ฅผ ๋ค๋ฅธ ํํ๋ก ๋ฐ๋๋ค. ํ๋ก ํธ์์ ์์ฒญ์ผ๋ก ๋ค์ด์จ ํด์ํ๊ทธ์ ํํ์ ๋ํ ์ค๋ช ์ ๋ง๋ถ์ด๋ฉด ํด์ํ๊ทธ๋ ๋ฌธ์์ด ํํ๋ก ๋ฐฐ์ด์ ์ ์ฅ๋์ด์๋ค(String[] hashtags). ์ด๊ฒ์ผ๋ก ๋ฏธ๋ฃจ์ด ์๊ฐํด๋ณด๋ฉด ์์ฑ ์ฝ๋์์๋ ์์ฒญ์ ํ์์ ๊ทธ๋๋ก ์ฌ์ฉํ๊ณ , ์ํ์ฐฉ์ค ์ฝ๋์์๋ ์ด ํจ์๋ฅผ ๋ถ๋ฅด๊ธฐ ์ ์ ์์ฒญ์ ๋ฐํ์ผ๋ก Tag ๊ฐ์ฒด ๋ฆฌ์คํธ๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ์ ๊ฒ์ ์ ์ ์๋ค. ์ค์ ๋ก ์ํ์ฐฉ์ค ์ฝ๋ ์ด์ ์๋ ์์ฒญ์ผ๋ก ๋ฐ์ (String[] hashtags)ํํ ํ๊ทธ๋ฅผ tag ํ ์ด๋ธ์์ ์กฐํํ์ฌ tag ๊ฐ์ฒด ๋ฆฌ์คํธ๋ฅผ ๋ง๋ค์ด์๋ค.
๋ญ๊ฐ ์ด์ํ์ง ์์๊ฐ? ์ด๋ฏธ ํ๊ทธ๋ช
์ ์๊ณ ์๋๋ฐ ํ๊ทธ ๋ฒํธ๋ฅผ ๋ชจ๋ฅธ๋ค๊ณ ๋ ๋ค์ ํ๊ทธ๋ฅผ ์กฐํํด์ผํ๋ค๋โฆ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์์ ์ํฐํฐ๋ฅผ ๊ตฌ์ฑํ๋ค๋ฉด ์ด๋ฏธ Tag ๊ฐ์ฒด ๋ด๋ถ์๋ ํ๊ทธ ๋ฒํธ์ ํ๊ทธ๋ช
์ด ํ๋๋ก ํํ๋์ด์๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก roomTag ๊ฐ์ฒด ๋ด๋ถ์๋ ํ๊ทธ๋ช
์ ์๋์ง๋ง ํ๊ทธ๋ช
์ ํฌํจํ tag ๊ฐ์ฒด๊ฐ ์ ์ฅ๋์ด ์์ผ๋ฏ๋ก ํ๋์ ์ ๊ทผํ์ฌ ์ฌ์ฉํ๋ฉด ๋๋ค. qRoomTag.tag.tagName.in(hashtags)
์ฒ๋ผ ๋ง์ด๋ค.
๋ค์์ผ๋ก group by()
๋ฉ์๋๋ฅผ ๋ณด์. ์ํ์ฐฉ์ค ์ฝ๋์์๋ ๋จ์ํ room ๊ฐ์ฒด๋ฅผ ๊ทธ๋ฃนํ ์กฐ๊ฑด์ผ๋ก ์ค์ ํ์ง๋ง ์์ฑ ์ฝ๋์์๋ roomTag ๊ฐ์ฒด ๋ด๋ถ์ ํ๋๋ก ์กด์ฌํ๋ room ๊ฐ์ฒด๋ฅผ ๊ทธ๋ฃน ์กฐ๊ฑด์ผ๋ก ์ค์ ํ๋ค. JPA์ QueryDsl์ ํ๋ก๊ทธ๋จ ๊ฐ์ฒด์ DB๋ฅผ ์ฐ๊ฒฐํด์ฃผ๊ณ ์๊ธฐ๋๋ฌธ์ ์๋ฌด๋ฆฌ ๊ฐ์ room ํ์
์ด๋ผ๊ณ ํ ์ง๋ผ๋ roomTag ๊ฐ์ฒด์ ํ๋์ ์กด์ฌํ๋ room ๊ฐ์ฒด๋ฅผ ๋ช
์ํด์ผ DB์ ์ํฐํฐ๋ฅผ ์ฐ๊ฒฐํด์ค ์ ์๋ค.
ํโฆ ์๋ฌด๊ฒ๋ ๋ชจ๋ฅด๊ณ ๋จ์ํ๊ฒ room ๊ฐ์ฒด๋ฅผ ์ง์ ํ๋ค๊ฐ jpa๋ก๋ถํฐ ์๊พธ๋ง ์๋ชป๋ ์ปฌ๋ผ, ์๋ ์ปฌ๋ผ, ์ดํดํ ์ ์๋ ์ปฌ๋ผ์ด๋ผ๋ ์๋ฌ๋ฅผ ๋ฐ์์ผ ํ๋ค. ๋ถ๋ช sql๋ฌธ๊ณผ ๋์ผํ๋ฐ ์ ์๋ ๊น ํ๋๋ฐ ์๋ฌ๋ฅผ ์ก์ ๋๋ sql๋ฌธ๋ฒ ์ค๋ฅ๊ฐ ์๋ ์ด์ sql๋ฌธ์ ๊ธฐ์ค์ผ๋ก ์๊ฐํ ๊ฒ์ด ์๋๋ผ ๊ฐ์ฒด์งํฅ ๊ธฐ๋ฐ์ผ๋ก ์๊ฐํ์ด์ผ ํ๋ค.
jpa๊ฐ ์ฝ์ง ์์ง๋ง ์ ๋ง ์ ์ฉํ๋ค๋ ๊ฒ์ ๋ค์ํ๋ฒ ๊นจ๋ฌ์๋ค. ์๋๋ฉด 6์ ์ ๊น์ง ๊ธฐ๋ฅ ๊ตฌํ์ ๋๋ด์ผ๊ฒ ๋๋ฐ DB ์กฐํ๋ ์๊พธ๋ง ์คํจํ๊ธธ๋ ์ฟผ๋ฆฌ๋ฌธ ์์ฒด๋ฅผ ์๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ๋จ์์ ํ๋ก๊ทธ๋๋ฐํ์ฌ ๊ตฌํํ์๋ค. ์๋๊ฐ ๊ทธ ์ฝ๋๊ณ ๋ณ๋ก ์ค๋ช ํ๊ณ ์ถ์ง ์๋คโฆ ๐
String[] hashtags = word.substring(1).split("#");
HashMap<Room, Integer> roomTagMap = new HashMap<>();
// tag ํ
์ด๋ธ์์ hashtags์ ํด๋นํ๋ ํ๊ทธ ๋ฆฌ์คํธ๋ฅผ ๋ชจ๋ ๊ฐ์ ธ์ด
List<Tag> tagList = tagRepository.findByTagNameIn(hashtags);
for (Tag tag : tagList) {
// roomTag ํ
์ด๋ธ์์ ๊ฐ hashtag์ ํด๋นํ๋ ๋ฃธ ๋ฆฌ์คํธ ๋ชจ๋ ๊ฐ์ ธ์ด
List<RoomTag> searchedRooms = roomTagRepository.findByTag(tag);
// ๋งต์ ๋ฃธ๊ณผ ์ฐพ๋ ํด์ํ๊ทธ๋ฅผ ๋ช๊ฐ ํฌํจํ๋์ง ์ ์ฅ
for (RoomTag searchedRoom : searchedRooms) {
Room curRoom = searchedRoom.getRoom();
roomTagMap.computeIfPresent(curRoom, (k, v) -> v+1);
roomTagMap.putIfAbsent(curRoom, 1);
}
}
// ์กฐํํ๋ ํด์ํ๊ทธ ๊ฐ์๋งํผ ํด์ํ๊ทธ๋ฅผ ํฌํจํ ๋ฃธ๋ง ๋ฐํ
List<Room> roomContainingHashtags = new ArrayList<>();
int size = hashtags.length;
for (Map.Entry<Room, Integer> entry : roomTagMap.entrySet()) {
if (entry.getValue() == size) roomContainingHashtags.add(entry.getKey());
}
roomList = new PageImpl<>(roomContainingHashtags, sort, roomContainingHashtags.size());