가자공부하러!

Hibernate(10) - 응용 문법 ② (엔티티 직접 사용, named 쿼리, 벌크연산) 본문

공부/Java

Hibernate(10) - 응용 문법 ② (엔티티 직접 사용, named 쿼리, 벌크연산)

오피스엑소더스 2019. 11. 26. 21:09

1. 엔티티 직접 사용

1.1. 기본 키 값

  - JPQL에서 엔티티를 직접 사용하면 SQL에서 해당 엔티티의 기본 키 값을 사용한다.

    > 예) JPQL : select count(m) from Member m

      - 수행되는 쿼리 : select count(m.id) as cnt from Member m

      - 다음 JPQL도 수행되는 쿼리는 위와 같음 : select count(m.id) from Member m

1.2. 외래키 값

  - 연관관계 매핑된 다른 엔티티를 쿼리의 파라미터로 사용할 수 있다.

//@ManyToOne @JoinColumn(name = "TEAM_ID) private Team team;
em.createQuery("select m from Member m where m.team = :team", Member.class)
		.setParameter("team", new Team("팀A"));

 

2. Named 쿼리

2.1. Named 쿼리?

  - 미리 선언해둔 쿼리

    > @NamedQuery(name = "", query = "")

    > XML에 정의 가능

  - 정적 쿼리만 가능

  - application 로딩 시점에 초기화 되어 파싱하기 때문에 캐싱되어있는 상태로 시작됨

  - application 로딩 시점에 쿼리를 검증

  - xml파일로 설정한 내용이 우선권을 가진다.

  - Spring Data JPA에서 인터페이스 메서드 위에 바로 선언하는 쿼리가 바로 네임드 쿼리

//Spring Data JPA 예제
public interface UserRepository extends JpaRepository<User, Long>{
	@Query("select u from User u where u.emailAddress =?1")	//요게 바로 네임드 쿼리
    User findByEmailAddress(String emailAddress);
}

  - 예) @NamedQuery : 

package jpql;

import lombok.*;

import javax.persistence.*;

@Entity
@Table(name = "MEMBER")
@AllArgsConstructor
@NoArgsConstructor
@Getter @Setter
@NamedQuery(
        name = "Member.findByUserName"
        , query = "select m from Member m where m.username = :username"
)
public class Member {

    @Id @GeneratedValue
    private Long id;
    private String username;
    private int age;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TEAM_ID")
    private Team team;

    @Enumerated(EnumType.STRING)
    private MemberType type;
}

  - 예) ormMember.xml : 

<!-- persistence.xml -->
<persistence ...> <persistence-unit ...>
        <mapping-file>META-INF/ormMember.xml</mapping-file>
</persistence-unit> </persistence>
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" version="2.0">
    <named-query name="Member.findByUsername">
        <query>
                select m
                from Member m
                where m.username = :username
        </query>
    </named-query>
</entity-mappings>

 

 

3. 벌크 연산

3.1. 벌크연산?

  - 일반적인 update, delete 

    > JPA 변경 감지 기능으로 100건 이상을 update, delete 하려면 너무 많은 쿼리가 수행된다.

    > 한 번의 쿼리로 여러 작업을 처리

  - 지원스펙

    > JPA : UPDATE, DELETE

    > Hibernate : INSERT(insert into ... select)

3.2. 주의

  - 벌크 연산은 영속성 컨텍스트를 무시하고 DB에 직접 쿼리 실행

    - 방법1 : 영속성 컨텍스트가 생기기 전에 벌크 연산을 먼저 실행하고 영속성 컨텍스트 작업 수행

    - 방법2 : 벌크 연산을 수행하고 영속성 컨텍스트를 초기화 해주기

      > executeUpdate()는 flush를 자동으로 호출함(flush 다음 update 수행)

3.3. 사용방법 : excuteUpdate()

  - 예) 모든 회원의 나이를 20살로 변경

//resultCount = 영향받은 엔티티의 수 = 업데이트된 멤버의 수
int resultCount = em.createQuery("update Member m set m.age = 20")
		.executeUpdate();

 

 

 

Comments