Framework/SpringBoot

SpringBoot-Query

보라색츄르 2021. 7. 7. 11:36

1. Query란

1. 쿼리 메서드는 말 그대로 '메서드의 이름 자체가 질의문'이 되는 기능이다.

2. findBy.. / getBy... 등으로메서드의 이름을 시작하고 컬럼과 키워드를 연결하는 것으로 메서드 작성한다.

예) findByMnoBetweenOrderMnoDesc

3. 주로 findBy~~deleteBy~~getBy~~와 같은 이름으로 시작하고, 필요한 필드 조건이나 AND, OR와 같은 키워드를 조합하여 메서드의 이름만으로도 쿼리조건을 만들어 낼 수 있다. 

4. 메서드의 피라미터(매개변수)는 키워드에 따라서 갯수가 결정된다.

예) Between의 경우 범위를 지정하는 두가지 값이 필요하기 때문에 

    findByStartDateBetween과 같은 메서드 이름을 작성할 수 있다.

    실제 SQL은 select~~ where startDate between ?  and ? 와 같은 형식으로 실행된다.

 

2. 메서드 리턴 타입

   1) select를 하는 작업일 경우 List또는 배열을 이용할 수있다. 파라미터네 Pageable 타입을 전달하는 경우에는 반드시 Page<T>타입으로 지정

※참조: IntellJ일 경우 쿼리 메서드 작성 기능을 제공해준다.

 

import com.example.demo.entity.Memo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface MemoRepository extends JpaRepository<Memo,Long>{
    //Memo의 mno 값이 70~80사이의 객체들을 조회하고, mno의 역순으로 정렬할 수 있는 쿼리 메서드
    List<Memo> findByMnoBetweenOrderByMnoDesc(Long from, Long to);

    //쿼리 메서드와 pageable을 결합하는 쿼리 메서드
    Page<Memo> findByMnoBetween(long from, long to, Pageable pageable);
}
-----------------------------------------------------------------------------------------

@Test
    public void testQueryMethods(){
        List<Memo> list=memoRepository.findByMnoBetweenOrderByMnoDesc(70L, 88L);
        for(Memo memo : list){
            System.out.println(memo);
        }
    }
    
=================================================================================================
실행결과
Memo(mno=88, memoText=Sample..88, t=0)
Memo(mno=87, memoText=Sample..87, t=0)
Memo(mno=86, memoText=Sample..86, t=0)
Memo(mno=85, memoText=Sample..85, t=0)
Memo(mno=84, memoText=Sample..84, t=0)
Memo(mno=83, memoText=Sample..83, t=0)
Memo(mno=82, memoText=Sample..82, t=0)
Memo(mno=81, memoText=Sample..81, t=0)
Memo(mno=80, memoText=Sample..80, t=0)
Memo(mno=79, memoText=Sample..79, t=0)
Memo(mno=78, memoText=Sample..78, t=0)
Memo(mno=77, memoText=Sample..77, t=0)
Memo(mno=76, memoText=Sample..76, t=0)
Memo(mno=75, memoText=Sample..75, t=0)
Memo(mno=74, memoText=Sample..74, t=0)
Memo(mno=73, memoText=Sample..73, t=0)
Memo(mno=72, memoText=Sample..72, t=0)
Memo(mno=71, memoText=Sample..71, t=0)
Memo(mno=70, memoText=Sample..70, t=0)

 

 

2.쿼리 메서드와 Pageable의 결합: orderby 키워드등 메서드명이 길어질 때 이를 분리하여 간단한 메서드명으로 선언가능 즉, 정렬에 관한 부분은 Pageabel로 처리하여 간단한 메서드를 선언할 수 있다.

 

 

 

3. deleteBy를 이용하여 조건에 맞는 객체를 삭제하는 쿼리 메서도 

   실제 사용할 때는 해당 메서드에 @Commit(사용하지 않았을 경우에는 Rollback) @Transactional를 사용해야 한다. 

 

   -이유

    1) select문으로 해당 엔티티 객체 조회

    2) 각 엔티티 객체들을 한번에 삭제하지 않고 하나씩 삭제 하기 때문에 

 

참조 URL : https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation

 

Spring Data JPA - Reference Documentation

Example 109. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io

 

 

@Query 어노테이션

 

1. @Query어노테이션:  기존 SQL을 이용하여 메서드 생성 가능

Spring Data JPA가 제공하는 쿼리 메서드는 간단한 처리에 사용

만약 복작한 조건을 처리할때는 조인을 사용

 

2. @Query("SQL구문") 메서드이름과 무관하게 메서드에 추가한 어노테이션을 통하여 원하는 작업을 처리 

(즉, 메서드며은 개발자가 임의의 명명할 수잇다.)

 

3. @Query의 value(즉, "SQL구문")dms JPQL(객체 지향쿼리)로 작성.

 

4. @Query를 이용하여 할 수 있는 작업

1) 필요한 데이터만 선별적으로 추출가능

2) 데이터 베이스에 맞는 순수한 SQL을 사용 가능

3)insert, update, delete 와 같이 select가 아닌 DML등을처리 가능

   단, @Modifying과 함께 사용

 

5. JPQL(객체 지향 쿼리): 테이블 대신 엔티티 클래스를 이용하고, 테이블의 컬럼 대신, 엔티티 클래스의 멤버변수(필드)를 이용하여 작성.

예) mno역순으로 정렬하는 메서드 선언시.

   @Query("select m from Memo m order by m.mno desc")

   List<Memo> getListDesc();

 

실제 SQL에서 사용되는 함수들도 동일하게 사용가능

(avg() / sum() / max() / count().group by / order by등..)

----------------------------------------------------------------------------

 

JPQL : Entity class 기준

SQL  : Table 기준

 

JPA 에서는

SQL : "select * from tbl_memo m order by m.mno desc"

JPQL : "select m from Memo m order by m.mno desc"

 

JPA는 기존 SQL과 JPQL를 매핑하는 역할을 담당한다고 이해하시면 됩니다..

 

---------------------------------------------------------------------------------

 

    @Query("select m from Memo m order by m.mno desc")

    List<Memo> getListDesc();

 

------------------------------------------------------------------------------------

update ~~ set ~~~=? where ~~ =?

 

 

@Query 의 파라미터 바인딩 방법

 

1. ~~~ 와 같이 :파라미터명   을 활용하는 방식

2. 여러 개의 파라미터를 전달 =>  객체를 이용

   :#{ } 

 

* 참조 : update / delete 등 데이터가 수정이 되는 경우에는 

  @Transactional 을 사용한다... 

  특히 update를 사용할 경우에는 @Modifying 까지 사용해야 한다...

 

@Transactional

@Modifying

@Query("update Memo m set m.memoText = :memoText where m.mno = :mno")

int updateMemoText(@Param("mno") Long mno, @Param("memoText") String memoText);

 

Hibernate: 

    update

        tbl_memo 

    set

        memo_text=? 

    where

        mno=?

====> 1

 

--------------------------------------------------------------------

 

    @Transactional

    @Modifying

    @Query("update Memo m set m.memoText = :#{#p.memoText} where m.mno = :#{#p.mno} ")

    int updateMemoText(@Param("p") Memo memo );

 

Hibernate: 

    update

        tbl_memo 

    set

        memo_text=? 

    where

        mno=?

====> 1