Spring Data JPA๋ฅผ ์ฌ์ฉํ๋ฉด @Query ์ด๋
ธํ
์ด์
์ ํตํด ์ง์ JPQL(JPA Query Language)์ ์์ฑํ ์ ์์ต๋๋ค. SQL๊ณผ ๋น์ทํด ๋ณด์ด์ง๋ง ์ํฐํฐ ์ค์ฌ์ผ๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ ๋ช ๊ฐ์ง ์ค์ํ ์ฐจ์ด์ ๊ณผ ์ฃผ์ํ ์ ์ด ์์ต๋๋ค. ์ด ๊ธ์์๋ @Query๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๊ณผ JPQL์ ํต์ฌ ๊ฐ๋
๋ค์ ๊ฐ๋จํ๊ณ ๋ช
ํํ๊ฒ ์ค๋ช
ํฉ๋๋ค.
from boardfrom Board bBoard๋ ์๋ฐ ํด๋์ค ์ด๋ฆ์ด๋ฏ๋ก ๋๋ฌธ์๋ฅผ ์ฌ์ฉํด์ผ ํ๋ฉฐ, ์๋ฆฌ์์ค(b)๋ฅผ ๋ฐ๋์ ๋ถ์ฌ ์ฌ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค.@Query("select b from Board b")
List<Board> findAllBoards();
โก๏ธ select * from board ์ ๋น์ทํ์ง๋ง, ์ํฐํฐ ๊ธฐ์ค์ด๋ผ๋ ์ ์ด ๋ค๋ฆ
๋๋ค.
@Query("select b.seq, b.title from Board b where b.title like %?1%")
List<Object[]> findSeqAndTitle(String keyword);
b.seq, b.title์ฒ๋ผ ์ผ๋ถ ํ๋๋ง ์ ํํ๋ฉด ๋ฐํ ํ์
์ List<Object[]>๊ฐ ๋ฉ๋๋ค.Object[]๋ก ๋ฐ๋ ์ด์ : b.seq๋ Long, b.title์ String ๋ฑ ๋ฆฌํด ํ์
์ด ์์ฌ ์๊ธฐ ๋๋ฌธ์
๋๋ค.select seq, title from board์ ์ ์ฌํ์ง๋ง, JPQL์ ํด๋์ค ๊ธฐ๋ฐ์ผ๋ก ์ดํดํด์ผ ํฉ๋๋ค.๐ Tip: ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ์ํฐํฐ ์ ์ฒด(Board)๋ฅผ ๋ฐ๋ ๊ฒ์ ๋๋ค. ๋ฆฌํด ํ์ ์ด ๋ช ํํ๊ณ ์ฝ๋๋ ๊น๋ํด์ง๊ธฐ ๋๋ฌธ์ JPQL์ ํฐ ์ฅ์ ์ค ํ๋๋ก ๊ผฝํ๋๋ค.
@Query("select b from Board b where b.title like %?1%")
List<Board> searchByTitle(String keyword);
?1์ ์ฒซ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ฅผ ์๋ฏธ@Query("select b from Board b where b.title like %:title%")
List<Board> searchByTitle(@Param("title") String keyword);
:title โ ๋ณ์๋ช
์ ๊ธฐ์ค์ผ๋ก ๋งคํ@Param ์๋ต๋ ๊ฐ๋ฅ:@Query("select b from Board b where b.title like %:keyword%")
List<Board> searchByTitle(String keyword); // keyword ์ด๋ฆ์ด ๊ฐ์ผ๋ฉด @Param ์๋ต ๊ฐ๋ฅ| ํญ๋ชฉ | JPQL | SQL |
|---|---|---|
| ๋์ | ์ํฐํฐ ํด๋์ค | DB ํ ์ด๋ธ |
| FROM ์ | from Board b | from board |
| SELECT ์ | b ๋๋ b.seq, b.title | *, seq, title |
| ๋ฆฌํด ํ์ | List<Board>, List<Object[]> | ResultSet |
| ํ๋ผ๋ฏธํฐ | ์์น ๊ธฐ๋ฐ ?1, ์ด๋ฆ ๊ธฐ๋ฐ :paramName | ?, :paramName |
@Query("select b.seq, b.title, b.writer, b.createDate "
+ "from Board b "
+ "where b.title like %?1% "
+ "order by b.seq desc")
List<Object[]> queryAnnotationTest2(String searchKeyword);
๐ ์ค๋ช :
select b.seq, b.title ... โ ์ผ๋ถ ํ๋๋ง ์ ํObject[]์ธ ์ด์ : ๋ชจ๋ ํ๋์ ํ์
์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธObject[]@Query๋ JPQL ๊ธฐ๋ฐ์
๋๋ค. ๋ค์ดํฐ๋ธ SQL์ ์ฐ๊ณ ์ถ๋ค๋ฉด nativeQuery = true ์ต์
์ ์ฌ์ฉํ์ธ์.Page<T>์ ํจ๊ป ํ์ด์ง ์ฟผ๋ฆฌ๋ ์์ฑํ ์ ์์ต๋๋ค.@Query๋ฅผ ์ ํ์ฉํ๋ฉด ์ ์ง๋ณด์์ฑ๊ณผ ์ฑ๋ฅ์ ํจ๊ป ์ก์ ์ ์์ต๋๋ค.like %?1%์์ ํผ์ผํธ %๋ ๋ญ์ผ?์ด๊ฑด SQL์์ ์ฌ์ฉํ๋ ํจํด ๋งค์นญ ๊ธฐํธ์์.
| ๊ธฐํธ | ์๋ฏธ |
|---|---|
% | "๋ชจ๋ ๋ฌธ์์ด"์ ๋ปํด์ (0๊ธ์ ์ด์) |
@Query("select b from Board b where b.title like %?1%")
์ ์ฟผ๋ฆฌ์์ ?1์ ์ฒซ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๊ณ , %๋ ๋ค์๊ณผ ๊ฐ์ ์๋ฏธ๊ฐ ์์ด์:
%?1% โ ํ๋ผ๋ฏธํฐ ๊ฐ์ ํฌํจํ๋ ๋ฌธ์์ด
์: ํ๋ผ๋ฏธํฐ๋ก "์ ๋ชฉ"์ ๋๊ธฐ๋ฉด
โ like '%์ ๋ชฉ%'๊ฐ ๋์ด
โ "ํ
์คํธ ์ ๋ชฉ1" "๊ณต์ง ์ ๋ชฉ์
๋๋ค" ๊ฐ์ ๊ฒ๋ค์ด ๊ฒ์๋ผ์.

@Param ์๋ต ๊ฐ๋ฅํ ์กฐ๊ฑด: ํ๋ผ๋ฏธํฐ ์ด๋ฆ์ด ๊ฐ์ผ๋ฉด ์๋ต ๊ฐ๋ฅ์๋ฅผ ๋ค์ด ์๋ ์ฝ๋:
@Query("select b from Board b where b.title like %:keyword%")
List<Board> searchByTitle(@Param("keyword") String keyword);
์ฌ๊ธฐ์:
:keyword โ JPQL ์ฟผ๋ฆฌ ์์์ ์ฐ๋ ์ด๋ฆ@Param("keyword") โ ์๋ฐ ์ฝ๋์์ ์ด ์ด๋ฆ์ ๋ฐ์ธ๋ฉ์ด๋ ์๋ฐ์ ํ๋ผ๋ฏธํฐ ์ด๋ฆ(keyword)์ด JPQL ์์ ์ด๋ฆ(:keyword)๊ณผ ์์ ํ ๊ฐ๋ค๋ฉด @Param("keyword")๋ฅผ ์๋ตํด๋ OK์์!
@Query("select b from Board b where b.title like %:keyword%")
List<Board> searchByTitle(String keyword); // ์๋ต ๊ฐ๋ฅ: ๋ณ์๋ช
์ด ๊ฐ์

@Query("select b from Board b where b.title like %:keyword%")
List<Board> searchByTitle(String title); // ๋ณ์๋ช
(title)๊ณผ ํ๋ผ๋ฏธํฐ(keyword)๊ฐ ๋ค๋ฅด๋๊น ์๋ต ๋ถ๊ฐ!
์ด ๊ฒฝ์ฐ์๋ ๊ผญ ์ด๋ ๊ฒ ์จ์ผ ํด์:
List<Board> searchByTitle(@Param("keyword") String title);
| ๊ตฌ๋ถ | ์ค๋ช |
|---|---|
% | SQL์์ "์๋ฌด ๊ธ์"๋ฅผ ์๋ฏธํจ. like %์ ๋ชฉ% โ ์ ๋ชฉ์ด ํฌํจ๋ ๋ชจ๋ ๋ฌธ์์ด ๊ฒ์ |
@Param ์๋ต | ๋ฉ์๋ ํ๋ผ๋ฏธํฐ ์ด๋ฆ๊ณผ JPQL ํ๋ผ๋ฏธํฐ ์ด๋ฆ์ด ๊ฐ์ ๋๋ง ์๋ต ๊ฐ๋ฅ |

how to use multiple like conditions with @Query.
Letโs clarify step by step. ๐
List<Board> boardList = boardRepo.queryAnnotationTest1("์ ๋ชฉ10", "333");
You expect this to run a JPQL query like:
select b from Board b
where b.title like %?1% and ... like %?2%
But you canโt write like %?1% directly like that.
like %...% patterns:@Query("select b from Board b where b.title like %?1% and b.writer like %?2%")
List<Board> queryAnnotationTest1(String titleKeyword, String writerKeyword);
โ
Yes! This is the correct way to use two like filters with position-based parameters (?1, ?2).
Spring Data JPA actually doesnโt allow %?1% directly in all cases.
Instead, you should write it like this:
@Query("select b from Board b where b.title like concat('%', ?1, '%') and b.writer like concat('%', ?2, '%')")
List<Board> queryAnnotationTest1(String titleKeyword, String writerKeyword);
concat('%', ?1, '%') โ dynamically builds '%์ ๋ชฉ10%'@Query("select b from Board b where b.title like concat('%', :title, '%') and b.writer like concat('%', :writer, '%')")
List<Board> queryAnnotationTest1(@Param("title") String titleKeyword, @Param("writer") String writerKeyword);
| Your case | What to write |
|---|---|
Want to filter title and writer both with %keyword% | Use concat('%', ?1, '%') for position-based or :title with @Param for name-based |