오봉이와 함께하는 개발 블로그
JPA - 기본 문법과 쿼리 API 본문
728x90
JPQL(Java Persistence Query Language)
- JPQL은 객체지향 쿼리 언어다. 따라서 테이블 대상이 아닌, 엔티티 객체 대상으로 쿼리한다.
- JPQL은 SQL을 추상화해서 특정 DB SQL에 의존하지 않는다.
- JPQL은 결국 SQL로 변환된다.
모델
모델 기반 코드 작성
@Entity
@Getter @Setter
public class Member {
@Id
@GeneratedValue
private Long id;
private String username;
private int age;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
@Entity
@Getter @Setter
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
}
@Entity
@Table(name = "ORDERS") // order는 예약어라 테이블명 변경 필요
@Getter @Setter
public class Order {
@Id @GeneratedValue
private Long id;
private int orderAmount;
@Embedded
private Address address;
@ManyToOne
@JoinColumn(name = "PRODUCT_ID")
private Product product;
}
@Embeddable
@Getter @Setter
public class Address {
private String city;
private String street;
private String zipcode;
}
@Entity
@Getter @Setter
public class Product {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
private int stockAmount;
}
JPQL 문법
SQL 문법과 똑같다.
(사진)
아래 update문과 delete문은 한 번에 여러 값을 업데이트 할 때 사용하는 벌크연산이라는 개념을 다룰 때 설명할 수 있겠다.
- select m from Member(엔티티) as m where m.age > 18
- 엔티티와 속성은 대소문자를 구분한다(Member, age)
- JPQL 키워드는 대소문자를 구분하지 않는다(SELECT, from, where)
- 테이블의 이름이 아닌, 엔티티의 이름을 사용한다.(Member)
- 별칭(m)은 필수다.(as는 생략 가능)
집합과 정렬
select
COUNT(m), -- 회원수
SUM(m.age), -- 나이 합
AVG(m.age), -- 평균 나이
MAX(m.age), -- 최대 나이
MIN(m.age) -- 최소 나이
from Member m
- GROUP BY, HAVING, ORDER BY 모두 동일하게 사용 가능
TypeQuery, Query
- TypeQuery : 반환 타입이 명확할 때 사용
- Query : 반환 타입이 명확하지 않을 때 사용
// em.createQuery("SELECT m.username, m.age from Member m", 타입.class);
TypedQuery<Member> query = em.createQuery("SELECT m FROM Member m", Member.class);
// m.username은 String, m.age는 int기 때문에 타입을 명시할 수 없다.
Query query = em.createQuery("SELECT m.username, m.age from Member m"); // Member.class가 없음.
결과 조회 API
- getResultList() : 결과가 하나 이상일 때, 리스트 반환
- 결과가 없으면 빈 리스트 반환
- getSingleResult() : 결과가 정확히 하나, 단일 객체 반환
- 결과가 없으면 : javax.persistence.NoResultException
- 둘 이상이면 : javax.persistence.NonUniqueResultException
파라미터 바인딩 - 이름 기준, 위치 기준
SELECT m FROM Member m where m.username=:username
query.setParameter("username", usernameParam);
SELECT m FROM Member m where m.username=?1
query.setParameter(1, usernameParam);
중간에 다른 파라미터를 삽입하면 순서가 다 꼬이기 때문에 위치 기준은 가급적 사용하지 않을 것을 권장한다.
// 이름 기준
TypedQuery<Member> query = em.createQuery("select m from Member m where m.username = :username", Member.class);
query.setParameter("username", "test"); // 여기서 파라미터 설정
Member findMember = query.getSingleResult();
// 체인 방식으로 엮어서 개선
Member result = em.createQuery("select m from Member m where m.username = :username", Member.class)
.setParameter("username", "test")
.getSingleResult();
// 위치 기준
TypedQuery<Member> query = em.createQuery("select m from Member m where m.username = ?1", Member.class);
query.setParameter(1, "test"); // 여기서 파라미터 설정
Member findMember = query.getSingleResult();
// 체인 방식으로 엮어서 개선
Member result2 = em.createQuery("select m from Member m where m.username = ?1", Member.class)
.setParameter(1, "test")
.getSingleResult();
출처 : 인프런 김영한 지식공유자님의 스프링 부트와 JPA 실무 완전 정복 로드맵 강의
728x90
'BE > JPA' 카테고리의 다른 글
JPA - 페이징 (0) | 2022.06.30 |
---|---|
JPA - 프로젝션(select) (0) | 2022.06.30 |
JPA - 객체 지향 쿼리 언어 소개 (0) | 2022.06.29 |
JPA - 실전 예제 6 - 값 타입 매핑 (0) | 2022.06.29 |
JPA - 값 타입 컬렉션 (0) | 2022.06.29 |
Comments