Soptmakers์์, ๋๋ง์๊ธฐ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ค. ์ฒ์ MVP๋ ๋ชจ๋ ํ์ฐจ์ ๋๋ง์๊ธฐ ๋ชฉ๋ก์ ๋ณด์ด๋๋ก ํ๊ธฐ๋ก ํ๋ค.
๋ฌดํ ์คํฌ๋กค์ ๊ตฌํํ ๋๋ limit, cursor, hasNext์ ๊ฐ์ ํ๋๊ฐ ํ์ํ๋ค.
- limit : ํ์ด์ง ์ฌ์ด์ฆ
- cursor: ์ฝ๊ณ ์ถ์ ํ์ ๋ฐ์ดํฐ ๊ฐ์
- hasNext: ์คํฌ๋กค ์ดํ ๊ทธ ๋ค์ ๋ฐ์ดํฐ๊ฐ ๋จ์์๋์ง ์๋์ง ํ๋จํ๋ ํ๋
๋ฌธ์ ์ ๋ฐ์
์ ์ฒด ์กฐํํ๋ ๊ฒฝ์ฐ์, ์ค๋ณต๋๋ ๋ฐ์ดํฐ๊ฐ ๋ณด์ด๊ฒ๋จ
limit์ 10
cursor๋ 10, 20, 30~ ์ ๊ฐ์ผ๋ก ์์ฒญ
์ด ๊ณผ์ ์์, (0 ~ 10) (10 ~ 20) (20 ~ 30) ์ค๊ฐ์ ๊ฐ๋ค์ด ์ค๋ณต๋๋ ํ์ ๋ฐ์
๐Offest Based Pagination
@Repository
@RequiredArgsConstructor
public class WordChainGameQueryRepository {
private final JPAQueryFactory queryFactory;
public List<WordChainGameRoom> findAllLimitedGameRoom(
Integer limit, Integer cursor
) {
val room = QWordChainGameRoom.wordChainGameRoom;
return queryFactory.selectFrom(room)
.offset(cursor)
.limit(limit)
.orderBy(room.id.desc())
.groupBy(room.id)
.fetch();
}
}
cursor์ ํด๋นํ๋ ๋งํผ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด๋ค์ธ ํ limit ๋งํผ์ ํ์ ์ฝ๊ณ ์์ ์ต์ ํ์ ์ญ์ ํ๋ ๊ณผ์ ์ ๊ฑฐ์น๊ฒ ๋ฉ๋๋ค.
๋ฐ์ดํฐ๊ฐ ๋ง์์ง๋ฉด ๋ง์์ง ์๋ก ์ฝ์ด์ผํ ๋ฐ์ดํฐ์ ๊ฐ์๊ฐ ๋ง์์ง๊ฒ ๋๋ฉฐ, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ง์ ๋ถํ๊ฐ ์๊ฒจ ์๋ ๋ฉด์์๋ ๋๋ ค์ง๊ฒ ๋ฉ๋๋ค.
๋ํ, ์๋ก์ด ํ์ด์ง๋ฅผ ๊ฐ์ ธ์ค๋ ์ค๊ฐ์ ์๋ก์ด ๋ฐ์ดํฐ๊ฐ ์ฝ์ ๋๋ฉด, ์ด์ ํ์ด์ง์ ์ค๋ณต๋๋ ํ์์ด ๋ฐ์ํฉ๋๋ค.
order by id desc
์ต์ ์์ ๊ณผ๊ฑฐ์์ผ๋ก ์กฐํ
์์์ ์ฝ์๋ ํ์ ๋ค์ ์ฝ์ด์ผํ๊ธฐ ๋๋ฌธ์, ํ์ด์ง ์ฟผ๋ฆฌ๊ฐ ๋ค๋ก ๊ฐ์๋ก ๋๋ ค์ง๋๋ค.
์) offset 10000, limit 10 -? 10010๊ฐ์ ํ์ ์ฝ๊ณ 10000๊ฐ์ ํ์ ๋ฒ๋ฆผ.
๐No Offest , Cursor Based Pagination
์กฐํ ์์ ๋ถ๋ถ์ ์ธ๋ฑ์ค๋ก ๋น ๋ฅด๊ฒ ์ฐพ์, ๋งค๋ฒ ์ฒซ ํ์ด์ง๋ง ์ฝ๋๋ก ํ๋ ๋ฐฉ์.
๋ง์ง๋ง ์กฐํํ ํ์ id ๊ฐ์ ๊ธฐ์ค์ผ๋ก, ์ฝ์ง ์์ ํ์ page size ๋งํผ ์กฐํํฉ๋๋ค. id๋ผ๋ ํด๋ฌ์คํฐ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์์ ๋ถ๋ถ์ ๋น ๋ฅด๊ฒ ์ฐพ์ ์กฐํ๊ฐ ๊ฐ๋ฅํฉ๋๋ค. ํ์ด์ง ๋ฒํธ(offset)๊ฐ ์๋ ๋๋ณด๊ธฐ ๋ฐฉ์.
ํ๋ก ํธ ๊ฐ๋ฐ์๋๊ป cursor๋ฅผ ์กฐํ๋ ๋ง์ง๋ง id๋ฅผ ์ ์กํด๋ฌ๋ผ๊ณ ์์ ์ฌํญ์ ์์ฒญ
์ฒซ ์กฐํ๋ cursor์ 0์ ๋ณด๋ด๋๋ก ์์ฒญ
public List<WordChainGameRoom> findAllLimitedGameRoom(Integer limit, Long cursor) {
val room = QWordChainGameRoom.wordChainGameRoom;
return queryFactory.selectFrom(room)
.where(ltGameRoomId(cursor))
.limit(limit)
.orderBy(room.id.desc())
.groupBy(room.id)
.fetch();
}
private BooleanExpression ltGameRoomId(Long gameRoomId) {
val room = QWordChainGameRoom.wordChainGameRoom;
if(gameRoomId == null || gameRoomId == 0) return null;
return room.id.lt(gameRoomId);
}
๐ Cursor Based Pagination์ ํ๊ณ์
cursor๊ฐ์ ์์ฐจ์ ์ด์ด์ผํ๋ฉฐ, ์ ๋ ฌ์ ํฌํจ๋๋ ํ๋ ์ด์์ ํ๋๋ unique ํด์ผํ๋ค.
offset ๋ฐฉ์ ๊ฐ์ ๊ฒฝ์ฐ, ์คํตํ ๋ฐ์ดํฐ ์์ limit๊ฐ๋ง ์ฃผ์ด์ง๋ค๋ฉด ์ด๋ค ์ฟผ๋ฆฌ๋ฅผ ์ํํด๋ ํ์ด์ง์ ๊ตฌํํ ์ ์์ง๋ง cursor ๋ฐฉ์์ ๋ ๋ง์ ์ ์ฝ์ ๊ฐ์ง๋ค.
'Server๐งค > QueryDsl' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[QueryDsl] ํ์ด์ง๋ค์ด์ ์ฒ๋ฆฌ (Offset based, Cursor based) (0) | 2023.06.04 |
---|---|
[Querydsl] Jmeter๋ฅผ์ด์ฉํ ์๋ ํ ์คํธ / Entity ์กฐํ์ id ์กฐํ ์ฑ๋ฅ ์ฐจ์ด (2) | 2023.05.09 |