9. 객체 지향 쿼리 언어 1 - 기본 문법
1. 소개
- JPQL
List<Member> result = em.createQuery(
"select m From Member m where m.username like '@kim'",
Member.class
).getResultList();
for (Member member: result) {
System.out.println("member = " + member);
}
- Criteria
- 오류를 발견하기 쉽다.
- 동적 쿼리를 생성하기 쉽다.
- sql같지가 않다 -> 유지보수가 안됨 -> 잘 쓰지 않는다
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Member> query = cb.createQuery(Member.class);
Root<Member> m = query.from(Member.class);
CriteriaQuery<Member> cq = query.select(m).where(cb.equal(m.get("username"), "kim"));
List<Member> resultList = em.createQuery(cq).getResultList();
- QueryDSL
- 동적 쿼리 작성 편리
- 단순하고 쉽다
- 실무 사용 권장
JPAFactoryQuery query = new JPAQueryFactory(em);
QMember m = QMember.member;
List<Member> list =
query.selectFrom(m)
.where(m.age.gt(18))
.orderBy(m.name.desc())
.fetch();
- 네이티브 SQL
em.createNativeQuery("select MEMBER_ID, CITY, STREET, ZIPCODE, USERNAME from Member")
.getResultList();
- 쿼리를 실행할 때 em.flush()가 자동으로 실행
- db conn.query는 flush 실행을 안하므로 강제로 flush를 해줘야한다.
2. JPQL 기본 문법과 쿼리 API
- JPQL은 SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다
- select m from Member as m where m.age> 18
- Member -> 엔티티
- 엔티티와 속성은 대소문자 구분 O
- JPQL 키워드는 대소문자 구분 X
- 엔티티 이름 사용 테이블 이름 X
- 별칭은 필수 AS는 생략 가능
- count. avg, sum 다 사용 가능
- TypeQuert -> 반환 타입이 명확할 때 사용 & Query -> 반환 타입이 명확하지 않을 때 사용
em.createNativeQuery("select MEMBER_ID, CITY, STREET, ZIPCODE, USERNAME from Member")
.getResultList();
- 결과가 컬렉션이면 getResultList()
- 결과가 없으면 빈 리스트 반환
- 결과가 객체면 getSingleResult()
- 결과가 없으면 javax.persistence.NoResultException
- 결과가 둘 이상이면 javax.persistence.NoUniqueException
- 파라미터 바인딩 -> 위치 기반, 이름 기반이 있지만 위치기반을 추천
TypedQuery<Member> query = em.createQuery("select m from Member m where m.username = :username", Member.class)
.setParameter("username", "hello");
Member singleResult = query.getSingleResult();
System.out.println("singleResult = " + singleResult);
3. 프로젝션
- select 절이 조회할 대상을 지정
- 종류
- 프로젝션으로 데이터를 추출할 시 영속성 컨테이너에서 관리 -> 수정 및 삭제 가능- SELECT m FROM Member m → 엔티티 프로젝션 - SELECT m.team FROM Member m → 엔티티 프로젝션 - SELECT m.address FROM Member m → 임베디드 타입 프로젝션 - SELECT m.age, m.username FROM Member m → 스칼라 타입 프로젝션
- 스칼라 타입 프로젝션
- Query 타입
List resultList = em.createQuery("select m.username, m.age from Member m ").getResultList();
for (Object o : resultList) {
Object obj = o;
Object[] result = (Object[]) obj;
System.out.println("obj[0] = " + result[0]);
System.out.println("obj[1] = " + result[1]);
}
- TypeQuery 타입
List<Object[]> resultList = em.createQuery("select m.username, m.age from Member m ").getResultList();
- new 명령어로 조회
List<MemberDTO> result = em.createQuery("select new jpql.MemberDTO(m.username, m.age) from Member m ", MemberDTO.class)
.getResultList();
MemberDTO memberDTO = result.get(0);
System.out.println("memberDTO.getUsername() = " + memberDTO.getUsername());
System.out.println("memberDTO.getAge() = " + memberDTO.getAge());
4. 페이징
- setFirstResult -> 조회 시작 위치 & setMaxResult -> 조회할 데이터 수
List<Member> result = em.createQuery("select m from Member m order by m.age desc", Member.class)
.setFirstResult(0)
.setMaxResults(10)
.getResultList();
System.out.println("result = " + result.size());
for (Member member1 : result) {
System.out.println("member1 = " + member1.toString());
}
5. 조인
String query = "select m from Member m inner join m.team t";
List<Member> result = em.createQuery(query, Member.class)
.getResultList();
- On 절
- 조인 대상 필터링
- 연관관계 없는 엔티티 외부 조인 가능
String query = "select m from Member m left join m.team t on t.name = 'teamA'";
List<Member> result = em.createQuery(query, Member.class)
.getResultList();
6. 서브 쿼리
- JPA 서브 쿼리 한계
- where, having 절에서만 서브 쿼리 가능
- From 절의 서브 쿼리는 현재 JPQL에서 불가능
- 조인으로 해결, 쿼리를 두번 날리는 식으로 해결
7. JQPL 타입 표현과 기타식
- ENUM
String query = "select m.username, 'hello', true from Member m "
+ "where m.type = jpql.MemberType.ADMIN";
List<Object []> result = em.createQuery(query)
.getResultList();
- 상속관계에서 해당하는 타입만 가져오고 싶다
"select i from Item i where type(i) = Book"
8. 조건식 - CASE 식
- CASE
String query = "select" +
" case when m.age <= 10 then '학생요금'"+
" when m.age >= 60 then '경로요금'"+
" else '일반요금'"+
" end" +
" from Member m";
- COLALESE -> 하나씩 조회해서 NULL이 아니면 반환
String query = "select coalesce(m.username, '이름 없는 회원') from Member m";
9. JPA 기본 함수
- concat, substring, trim, lower, upper, length, locate
- 사용자 함수 지정
- dialect 디렉토리 생성
- MyH2Dialect 클래스 생성 후
- 함수 생성 코드 참조 후 작성
- select function('함수 이름') ~~~으로 사용
Author And Source
이 문제에 관하여(9. 객체 지향 쿼리 언어 1 - 기본 문법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@homelala/9.-객체-지향-쿼리-언어-1-기본-문법저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)