본문 바로가기
공부/springboot

JPA 사용법(2) -- JPQL

by 샤샤샤샤 2023. 1. 26.

JPQL이란?

SQL을 자바에서 사용할수 있게끔 변환된 SQL.

JPA는 테이블이 아닌 엔티티 객체를 중심으로 개발하기 때문에 쿼리문을 사용하지 않는다. 그러나 어찌되었건 특정 데이터를 검색하기 위해서는 쿼리문의 역할을 해줄 것이 필요한데, JPA에서는 이를 위해 JPQL을 제공한다.

JPQL은 객체를 대상으로, SQL은 테이블을 대상으로 쿼리한다는 것이 차이점이다.

 

특징

1. 엔티티와 속성은 대소문자를 구분하지만, 키워드는 구분하지 않는다.

예)

select m from Member as m where m.age > 18
SELECT m FROM Member as m WHERE m.age > 18

둘 모두 동일하게 작동한다.

 

2. 테이블이 아닌 엔티티 객체 이름을 사용하며, 마찬가지로 컬럼이 아닌 필드를 선택한다.

 

3. 반드시 별칭을 사용해야 한다.(as는 생략가능.)

 

4. 특정 db에 종속적인 기능은 지원하지 않는다. 

    즉, MySQL의 Limit나 시간을 나타내는 함수 now()처럼, 특정 db에만 존재하는 기능은 지원하지 않는다.

 

사용법

1. JpaRepository를 상속한(확장한) 인터페이스에 List객체를 하나 만든다. 이때 리스트의 제네릭은 Entity클래스고, 매개        변수는 선택 조건으로 넣고 싶은 컬럼의 타입이 된다.

2. 메서드 위에 @Query을 작성하고 괄호안에 쿼리문을 작성한다.

    이때 매개변수로 받고싶은 값은 :변수이름과 같이 작성하면 된다.

@Query("SELECT u FROM User u WHERE u.status = :status")
List<"엔티티 클래스"> findAllActiveUsers(String status);
// String타입은 status를 매개변수로 받고, 그 값과 같은 엔티티를 불러오는 쿼리문

네이티브 SQL을 사용하는 방법도 있다.

이를 사용하면 특정 db에 종속적인 기능도 사용 가능하게 된다.

value= "쿼리문",  nativeQuery = true 를 작성하면 사용할수 있따.

@Query( value = "SELECT * FROM USERS u WHERE u.status = 1", nativeQuery = true)
List<"엔티티 클래스"> findAllActiveUsersNative();

 

데이터의 수정/ 삭제

UPDATE/ DELETE문을 작성하기 위해서는 인터페이스에서 만들어진 메소드에 @Modifying @Transactional 어노테이션을 작성해줘야 한다.

@Modifying
@Transactional
@Query(value = "UPDATE member SET user_id = :userid WHERE id = :id", nativeQuery = true)
List<"엔티티 클래스"> findAllActiveUsersNative();

이후 컨트롤러 클래스에서 삭제할 엔티티를 선택해주거나, 업데이트할 정보를 직접 넣어줘야 한다.

업데이트

public void update() {
        Optional<MemberEntity> member = memberRepository.findById(1L);
        // 1L: id의 타입이 Long여서 형변환을 한것
        member.ifPresent( unwrapMember ->{
            unwrapMember.setUserId("Mr.Kim");
            unwrapMember.setUserName("김삿갓");
            memberRepository.save(unwrapMember); //같은 id의 값이 있다면, update 됨.
            System.out.println( "업데이트 성공!" );
        });
    }

삭제

 public void delete() {
        Optional<MemberEntity> member = memberRepository.findById(1L);
        member.ifPresent( unwrapMember -> {
            memberRepository.delete( unwrapMember );
            System.out.println( "삭제 성공!" );
        });
    }

**Optional 클래스: 객체를 감싸는 wrapper클래스로, null을 허용함으로서 NPE를 피할수 있게 해준다.

   empty나 nullable, of 와 같은 함수들이 존재하며, if문처럼 값이 존재할때만 코드를 작동시킬수 있는 ifPresent와 같은           함수도 존재한다. 이때 ifPresent가 받는 인자는 람다식이나 메소드 레퍼런스가 된다. 람다식의 변수는 Optional로 인해       싸여진 객체, 위의 코드에서는 findById로 가져온 객체가 된다.

 

 

'공부 > springboot' 카테고리의 다른 글

스프링이란?  (0) 2023.05.10
스프링부트: 시큐리티(1)  (0) 2023.02.20
JPA 사용법(1) -- JPA 사용법  (0) 2023.01.26
개발용 임시 DB : H2DB  (0) 2023.01.25
MVC -- Model(2) : 데이터 받아오기  (0) 2023.01.25