BACK/JPA

[JPA] TIL 11일차 - 객체지향 쿼리 언어 JPQL 기본 문법

연듀 2024. 4. 8. 19:44

기본 문법과 쿼리 API

 

TypedQuery, Query

Member member = new Member();
member.setUsername("member1");
member.setAge(10);
em.persist(member);

TypedQuery<Member> query1 = em.createQuery("select m from Member m", Member.class);
TypedQuery<String> query2 = em.createQuery("select m.username from Member m", String.class);
Query query3 = em.createQuery("select m.username, m.age from Member m"); // 타입 정보를 받을 수 없을 때

 

 

결과 조회 API

Member singleResult = query.getSingleResult(); // 결과 하나일 때

List<Member> resultList = query.getResultList(); // 결과 하나 이상일 때, 결과 없으면 빈 리스트 반환 
for (Member member1 : resultList) {
       System.out.println("member1 = " + member1);
 }

 

 

파라미터 바인딩

Member result = em.createQuery("select m from Member m where m.username = :username", Member.class)
        .setParameter("uersname", "member1")
        .getSingleResult();
System.out.println("result = " + result.getUsername()); // result = member1

 

위치 기준 말고 위와 같이 이름 기준으로 써야 한다.

 

 


 

프로젝션

 

select 절에 조회할 대상을 지정하는 것

엔티티 프로젝션을 하면 셀렉트 한 대상이 다 영속성 컨텍스트에서 관리된다.

// 엔티티 프로젝션
List<Member> result = em.createQuery("select m from Member m", Member.class).getResultList();
Member findMember = result.get(0);
findMember.setAge(20); // 영속성 컨텍스트에서 관리되므로 20으로 변경된다. 

tx.commit();
// 엔티티 프로젝션
List<Team> result = em.createQuery("select m.team from Member m", Team.class).getResultList(); // 팀과 조인하는 쿼리가 나간다.(묵시적 조인)
// select t from Member m join m.team t 와 같다. <- 이렇게 명시적으로 조인을 적어주는게 좋다.
em.createQuery("select o.address from Order o", Address.class).getResultList(); // 임베디드 타입 프로젝션
em.createQuery("select distinct m.username, m.age from Member m").getResultList(); // 스칼라 타입 프로젝션

 

 

프로젝션  - 여러 값 조회

// Object[] 타입으로 조회
List<Object[]> resultList = em.createQuery("select m.username, m.age from Member m").getResultList();
Object[] result = resultList.get(0);
System.out.println("username = " + result[0]);
System.out.println("age = " + result[1]);

 

// DTO로 바로 조회
List<MemberDTO> result = em.createQuery("select new hellojpql.jpql.MemberDTO(m.username, m.age) from Member m", MemberDTO.class)
                    .getResultList();
MemberDTO memberDTO = result.get(0);
System.out.println("memberDTO = " + memberDTO.getUsername());

 

 

 


 

페이징

List<Member> result = em.createQuery("select m from Member m order by m.age desc", Member.class)
        .setFirstResult(0) // 조회 시작 위치(0부터 시작)
        .setMaxResults(10) // 조회할 데이터 수 
        .getResultList();
System.out.println("result.size  = " + result.size());
for (Member member1 : result) {
    System.out.println("member1 = " + member1);
}

 

DB 방언에 맞게 SQL 문이 나간다.

 


 

조인

 

내부 조인, 외부 조인

Team team = new Team();
team.setName("teamA");
em.persist(team);

Member member = new Member();
member.setUsername("member1");
member.setAge(10);
member.setTeam(team);

em.persist(member);
em.flush();
em.clear();

String query = "select m from Member m inner join m.team t"; // inner는 생략 가능
//String query = "select m from Member m left join m.team t"; // inner는 생략 가능

List<Member> result = em.createQuery(query, Member.class).getResultList();

 

 

세타 조인

String query = "select m from Member m, Team t where m.username = t.name";
List<Member> result = em.createQuery(query, Member.class).getResultList();

 

 

 


 

JPQL 타입 표현

 

String query = "select m.username, 'HELLO', TRUE From Member m " +
                    "where m.memberType =:userType"; // 하드코딩 하려면 패키지 명 다 넣어야 함
            List<Object[]> result = em.createQuery(query)
                            .setParameter("userType", MemberType.ADMIN)
                                    .getResultList();

 

em.createQuery("select i from Item i where type(i) = Book", Item.class).getResultList(); // type으로 DTYPE을 체크함

 

 

 

 


 

조건식

String query = "select " +
                    "case when m.age <= 10 then '학생요금'" +
                    " when m.age >= 60 then '경로요금'" +
                    " else '일반요금' "+
                    "end " +
                    "from Member m";
            List<String> result = em.createQuery(query, String.class).getResultList();
            for (String s : result) {
                System.out.println("s = " + s);
            }

 

String query = "select coalesce(m.username, '이름 없는 회원') from Member m";

String query = "select NULLIF(m.username, '관리자') from Member m";

 

 

 

*포스팅 시 기존에 알고있었던 SQL과 비슷한 문법들은 생략하였다. 

 

 

 

 

 

인프런 자바 ORM 표준 JPA 프로그래밍 - 기본편을 수강하고 정리한 글입니다.

https://www.inflearn.com/course/ORM-JPA-Basic