๐โ๋์ SQL๋ก ๊ฐ์ ๊ฒ์์ ์ ์ฐํ๊ฒ โ LectureSqlProvider ๊ตฌํ๊ธฐโ
๐ 2025-07-02 | โ๏ธ ๋ฐ์ฐฌํฌ |
๐ง ์ ์ด ๊ธฐ๋ฅ์ ์์ํ๋๊ฐ?
๊ฐ์ ๊ฒ์ ํ๋ฉด์ ๋ง๋ค๋ค ๋ณด๋ ์ด๋ฐ ์๊ตฌ๊ฐ ์์์ก๋ค:
- ์นดํ ๊ณ ๋ฆฌ๋ณ๋ก ๋๋ ์ผ ํด์
- ์ ๋ชฉ์ โJavaโ๊ฐ ๋ค์ด๊ฐ ๊ฐ์๋ง ๋ณด์ฌ์ฃผ์ธ์
- ์ธ๊ธฐ์์ผ๋ก ์ ๋ ฌํด์ฃผ์ธ์
- ํ์ด์ง๋ ๊ผญ ํ์ํด์
์ฒ์์๋ ๋จ์ํ ์ ์ SQL๋ก ์์ํ๋ค.
ํ์ง๋ง ์กฐ๊ฑด์ด ๋์ด๋ ์๋ก ์ฟผ๋ฆฌ๋ ๋ฌด๋์ก๊ณ ,
if-else์ ๋ช๊ณผ ๋ณต๋ถ SQL ์ง์ฅ์ด ์์๋๋ค.
๊ทธ๋์ ๊ฒฐ๋จํ๋ค.
๋์ SQL + MyBatis SQL Provider ํจํด์ผ๋ก ์ ํํด์,
๊ฐ๋ ์ฑ๊ณผ ์ฌ์ฌ์ฉ์ฑ์ ๋์์ ์ก๊ธฐ๋ก.
๐งฑ ์ค๊ณ ๊ตฌ์กฐ ํ๋์ ๋ณด๊ธฐ
๊ณ์ธต | ์์ | ์ค๋ช |
---|---|---|
DTO | LectureSearchCondition |
๊ฒ์ ์กฐ๊ฑด(์นดํ ๊ณ ๋ฆฌ, ํค์๋, ์ ๋ ฌ, ํ์ด์ง ๋ฑ) ์ ๋ฌ ๊ฐ์ฒด |
Provider | LectureSqlProvider |
SELECT , COUNT ์ฟผ๋ฆฌ ๋์ ์์ฑ ๋ด๋น |
Mapper | LectureMapper.xml |
๋์ ์ฟผ๋ฆฌ ๋ฌธ์์ด ๋ฐ์ธ๋ฉ |
Service | LectureService |
๋น์ฆ๋์ค ๋ก์ง (์กฐ๊ฑด ๋ถ๊ธฐ, ์๋ต ๋ณํ ๋ฑ) |
๐ ํต์ฌ ๋ฉ์๋ ์ค๊ณ
โ
findLectures(LectureSearchCondition cond)
- ์ธ๊ธฐ์ ์ ๋ ฌ ๊ฐ์ค์น ์๊ณ ๋ฆฌ์ฆ ๋ด์ฅ:
(ํ์ * 0.9) + (๋ฆฌ๋ทฐ ์ * 0.1) AS popularityScore
- ์กฐ์ธ ๊ตฌ์ฑ:
FROM lectures l
LEFT OUTER JOIN user_interactions ui
ON l.lecture_id = ui.target_id
AND ui.target_type = 'LECTURE'
AND ui.interaction_kind = 'FEEDBACK'
- ์กฐ๊ฑด ๋ถ๊ธฐ:
if (cond.getKeyword() != null) {
WHERE("title LIKE ... OR description LIKE ...");
}
- ์ ๋ ฌ ๋์ ๊ตฌ์ฑ:
if ("popular".equals(cond.getSort())) {
ORDER_BY("popularityScore DESC");
} else {
ORDER_BY("l.created_at DESC");
}
๐ ์ค์๊ฐ ์ธ๊ธฐ์์ ๋ง๋ค์ด๋ด๊ธฐ ์ํด ๋ฐ์ดํฐ๋ฅผ โ์ ๋ ฌ ๊ฐ๋ฅ ์งํโ๋ก ๊ฐ๊ณตํด์ ๋ฃ๋ ๊ฒ ํต์ฌ์ด์๋ค.
์ด๋ฐ ์ ๋ ฌ ์งํ๋ UX์ ๋ฐ์ดํฐ ๊ธฐ๋ฐ ์ถ์ฒ์ ์ ์ถฉ์ง์ ์ด ๋๋ค.
โ
countLectures(LectureSearchCondition cond)
-
SELECT ๊ตฌ๋ฌธ์ ๋จ์ํ์ง๋ง,
์กฐ๊ฑด ํํฐ๋ง์ ์กฐํ ์ฟผ๋ฆฌ์ ๋์ผํ๊ฒ ๋ง์ท๋ค.
SELECT COUNT(DISTINCT l.lecture_id)
-
GROUP BY ์์ด ์กฐ์ธ๋ง ์ ์ง โ Count ์ฑ๋ฅ ์ต์ ํ
๐ ๋ฆฌ์คํธ ์กฐํ์ ํ์ด์ง ์นด์ดํธ๋ฅผ ๋ณ๋๋ก ๋ถ๋ฆฌํ๋ฉด,
ํ์ด์ง ์์ฒญ ์ฑ๋ฅ์ 10๋ฐฐ ์ด์ ๊ฐ์ ํ ์ ์๋ค.
๐งช ํ ์คํธ ์๋๋ฆฌ์ค ์์ฝ
์กฐ๊ฑด ์์ | ๊ธฐ๋ SQL ๋์ |
---|---|
์กฐ๊ฑด ์์ | ์ ์ฒด ๊ฐ์ ์ต์ ์ ์กฐํ |
keyword = โJavaโ | WHERE title LIKE โ%Java%โ OR description โฆ |
category = โ์นโ | WHERE l.category = โ์นโ |
sort = โpopularโ | ORDER BY popularityScore DESC |
size = 20, offset = 10 | LIMIT 10, 20 |
โ ๋ชจ๋ ์ฟผ๋ฆฌ๋ ์ฝ์ ๋ก๊ทธ๋ก ์ง์ ์ถ๋ ฅํ์ฌ ์ฟผ๋ฆฌ ์ ํ์ฑ ๊ฒ์ฆ ์๋ฃ
๐ง ๊ตฌํ ์ค ๊ฒช์ ๋ฌธ์
โ ๋ฌธ์ : ์ ๋ ฌ ์กฐ๊ฑด์ด ์๊พธ ๋๋ฝ๋จ
- ์์ธ:
ORDER_BY(...)
๋ฅผif
๋ฌธ ์์์ ์์ฑํ๋๋ฐ,SQL()
๊ฐ์ฒด ๋ด๋ถ์ ์ ์ฉ๋์ง ์์ - ํด๊ฒฐ: ๋ชจ๋
ORDER_BY
๋ ์ฟผ๋ฆฌ ๋ธ๋ก์ ๋ง์ง๋ง์ ๊ณ ์ ์์น๋ก ๋ฐฐ์นํด์ผ ์์ ์ ์ ์ฉ๋จ
๐ ์ค๋ฌดํ ์ต์ ํ ์ ๋ต
ํญ๋ชฉ | ์ ๋ต | ์ด์ |
---|---|---|
SQL ๊ฐ์ฒด ๊ตฌ์ฑ | org.apache.ibatis.jdbc.SQL |
๊ฐ๋ ์ฑ + ์ ์ง๋ณด์์ฑ ํ๋ณด |
์ ๋ ฌ ์ ์ ๊ณ์ฐ | ํ์ + ๋ฆฌ๋ทฐ์ | ์ถ์ฒ ์๊ณ ๋ฆฌ์ฆ ๊ฐ์ํ ๋ฐ ์ค์๊ฐ UX ๋ณด์ฅ |
ํค์๋ ๊ฒ์ | title + description ๋์ LIKE | ๊ฒ์ ๋ง์กฑ๋ ํฅ์ |
ํ์ด์ง ๋ฐฉ์ | LIMIT #{offset}, #{size} |
๋ฐ์ดํฐ ์์ด ๋ง์๋ ์ฑ๋ฅ ์ ์ง |
LEFT OUTER JOIN | ๋ฆฌ๋ทฐ ์๋ ๊ฐ์ ํฌํจ | ๊ฐ์ ๋ค์์ฑ ํ๋ณด |
๐ญ ์์ผ๋ก์ ํ์ฅ ๊ณํ
๊ธฐ๋ฅ | ์ค๋ช |
---|---|
๐ ์ ๋ ฌ ๊ธฐ์ค ์ถ๊ฐ | ๋ฆฌ๋ทฐ๋ง์์, ๊ฐ๊ฒฉ๋ฎ์์, ๋ฌด๋ฃ๋ง ๋ณด๊ธฐ ๋ฑ |
๐ ์ธ๊ธฐ ์ ์ ๊ฐ์ | ์กฐํ์, ์ฐ ์ ๋ฑ ํฌํจํ ๋ค์ค ๊ฐ์ค์น ๋ชจ๋ธ |
๐ ๋ค๊ตญ์ด ์ง์ | title_kr , title_en ๋ถ๊ธฐ ์ฒ๋ฆฌ |
๐ ElasticSearch ์ฐ๋ | ๋์ฉ๋ ์กฐ๊ฑด ๊ฒ์ ์ฑ๋ฅ ํฅ์ |
โ ๋จ์ ํ ์คํธ | Provider ํจ์๋ณ assertSQLEquals ํ
์คํธ ์์ฑ ์์ |
โ๏ธ ํ๊ณ
์ด๋ฒ LectureSqlProvider
์์
์ ๋จ์ํ SQL ๋ฆฌํฉํ ๋ง์ด ์๋์๋ค.
๊ทธ ์์๋ ๋ค์๊ณผ ๊ฐ์ ๊ตํ์ด ์์๋ค:
๐ก โ์กฐ๊ฑด์ด ๋์ด๋๋ ์์คํ ์ผ์๋ก, ์ฟผ๋ฆฌ๋ ์ฌ๋์ด ์ฝ์ ์ ์์ด์ผ ํ๋ค.โ
MyBatis์ SQL()
๊ฐ์ฒด๋ ๋จ์ํ ๋ฌธ๋ฒ์ด ์๋๋ผ,
๋๋ฉ์ธ ๋ก์ง์ SQL ์์ค์์ ๋ถ๋ฆฌํ๊ณ ํ ์คํธ ๊ฐ๋ฅํ ์ฝ๋๋ก ๋ง๋ค ์ ์๋ ๋ฐฉ๋ฒ๋ก ์ด์๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฌด์๋ณด๋ค,
๋ฐฑ์๋ ์ค๊ณ๊ฐ ์ข์์ผ ํ๋ก ํธ๊ฐ ๋จ์ํด์ง๋ค.
์กฐ๊ฑด๋ง ๋๊ธฐ๋ฉด ๊ทธ์ ๋ง๋ ๊ฐ์ ๋ชฉ๋ก์ ์ ๊ตํ๊ฒ ์ฟผ๋ฆฌํด์ฃผ๋ ์ด ๊ตฌ์กฐ๋
์ค๋ฌด์์ API ์ค๊ณ์ ํต์ฌ์ด ๋ฌด์์ธ์ง ๋ค์ ํ๋ฒ ๊นจ๋ซ๊ฒ ํ๋ค.
โ ํ ๋ฌธ์ฅ ์์ฝ
โMyBatis SQL Provider ํจํด์ผ๋ก ์กฐ๊ฑด ๊ธฐ๋ฐ ๊ฐ์ ๊ฒ์์ ์ ๊ตํ๊ฒ ๊ตฌ์ฑํ์ฌ, ์ ์ง๋ณด์์ฑ๊ณผ UX ์ค์ฌ์ ์ค์๊ฐ ์ถ์ฒ ๊ตฌ์กฐ๋ฅผ ์์ฑํ๋ค.โ