자라선

[자바 ORM 표쥰 JPA 프로그래밍] 23일차 - JPQL 활용 (4) 본문

Develop/JPA

[자바 ORM 표쥰 JPA 프로그래밍] 23일차 - JPQL 활용 (4)

자라선 2021. 11. 10. 16:17

1. 엔티티를 조건으로 사용

        // Team 테이블에서 PK값 0 를 조회
        final Team team = em.find(Team.class, 0l);

        // Team PK 0를 사용하여 Member FK 로 조회한다.
        String jpql = "select m from Member m where m.team = :team";
        final List<Member> resultList = em.createQuery(jpql, Member.class)
                                            .setParameter("team", team)
                                            .getResultList();

JPQL에서 조건절에서 Member의 Team 필드로 걸어두었지만 파라미터로는 Team 엔티티가 그대로 들어가는데

이런 경우 JPQL에서는 자동으로 Team 엔티티의 PK로 뽑아 SQL로 변환시킨다.

 

2. @NamedQuery 

        String jpql = "select m from Member m where m.team = :team";

이와 같이 소스내의 String을 사용하여 쿼리를 생성하는데 이 쿼리를 동적쿼리라고한다 .

문자열이다보니 문자열을 런타임중에 변화시켜 다양한 쿼리로만들수있기 때문이다.

 

반대로 어플리케이션 로딩 시점에서 JPQL로 문법 검증을 하여 미리 파싱하는 방식을 

정적 쿼리라고 부르며 이를 사용하기 위해서 @NameQuery 어노테이션을 사용한다.

 

@Data
@NamedQueries(
    @NamedQuery(
            name = "Member.findByUsername",
            query = "select m from Member m where m.username = :username"
    )
)
@Entity
public class Member {

    @Id
    @GeneratedValue
    private long id;
    
    ....

 

엔티티에 @NamedQuery 어노테이션으로 쿼리명과 쿼리를 작성한다.

        final List<Member> members = em.createNamedQuery("Member.findByUsername", Member.class)
                                        .setParameter("username", "member_53")
                                        .getResultList();

        System.out.println(members.size());

그 후 작성된 쿼리명으로 해당 쿼리를 가져와서 출력해주면 된다.

 


 

추가로 NamedQuery를 작성할때 소스단 에서 작성할 수있지만 

ROW가 길어질경우 가독성을 해칠수도 있으며 작성에도 불편함이 따른다.

 

그래서 XML로 작성할 수 있도록 지원해준다.

 

아래 파일을 새로 생성해주며 persistence.xml 설정에도 해당 파일을 추가해준다.

 

META-INF/ormMember.xml

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm" version="2.1">

    <named-query name="Member.findByUsername">
        <query>
            <![CDATA[
                select m
                from Member m
                where m.username = :username
            ]]>
        </query>
    </named-query>

    <named-query name="Member.count">
        <query>select count(m) from Member m</query>
    </named-query>

</entity-mappings>
	<!-- persistence.xml -->
	<persistence-unit name="jpabook">
        <!-- properties 상단에 위치해야함 -->
        <mapping-file>META-INF/ormMember.xml</mapping-file>
        
        ...

 

 

만약에 @NamedQuery 와 XML 에 동일한 쿼리명이 있다면 XML를 우선으로 적용된다.

Comments