엔티티 객체
로서 데이터를 다루게 된다.질의문
이 필요하다.테이블이 아닌 객체
로 하는 것이 JPQL이다.select 조회할 대상 ...
from 검색대상 객체 [as] 별칭(필수)
[where]
[groupby]
[having]
[orderby]
select h
from Hospital h
where h.id
public interface EntityManager {
// ...
Query createQuery(String var1);
// ...
<T> TypedQuery<T> createQuery(String var1, Class<T> var2);
// ...
}
createQuery() 메소드에 JPQL 쿼리문을 스트링
으로 입력하여 결과 반환
TypeQuery< T> : 검색 대상이 명확하여 미리 지정할 수 있을 때 사용
select m form Member m
Member.class
로 명확select m.username from Member m
String.class
로 명확Query : 검색 대상이 하나가 아니거나 명확하지 않아 미리 지정할 수 없을 때 사용
select m.username, m.age from Member m
Object[]
로 반환TypeQuery나 Query의 결과를 반환하는 방법
엔티티 객체
가 들어간다. (테이블 X)@Entity
@Table(name="MEMBER)
class Member {
//...
}
em.createQuery("select m from Member m", Member.class).getResultList();
SELECT
m.id, ...
FROM
MEMBER m;
select m
from Member m
[inner] join m.team t
//m 즉 Member와 연관이 있는 Team으로 조인하겠다는 의미
select m
from Member m
left [outer] join m.team t
// LEFT가 되는 m 즉 Member는 모두 가져오고 그에 대한 Team의 정보를 조인한다. 없으면 null
select m.username, t.teamname
from Member m, Team t
// 멤버 1 | 팀 1
// 멤버 1 | 팀 2
// 멤버 1 | 팀 3
// 멤버 2 | 팀 1
// :
// 멤버 3 | 팀 3
select m from Member m
select m.team from Member m
select m.username, m.age from Member m
select m.address from Member m
Query createQuery(String var1).getResultList;
로 Object[]
반환select new 패키지경로.NameAgeDTO(m.username, m.age) from Member m
select
case when 조건1 then 내용1
when 조건2 then 내용2
else '내용3'
end
from Member m
select
case 비교대상
when 값1 then 내용1
when 값2 then 내용2
else 내용3
end
from Member m
setParameter()
를 통하여 이름이나 위치로 바인딩 할 수 있지만, 위치로 바인딩하게 되면 수정이 힘들어 이름으로 바인딩
TypeQuery<Member> query = em.createQuery(
"select m " +
"from Member m "
"where m.age >= :userAge "
"and m.username = :userName", Member.class);
List<Member> = query
.setParameter("userAge", 18)
.setParameter("userNmae", "김%")
.getResultList();
// 18세 이상의 김씨성을 가진 회원 정보
인라인 뷰
로 사용할 수 없다. → join을 통해서 해결.
으로 그래프 탐색하는 표현식hopital.sigudong.parent.sigudongName
//hospital 엔티티 > sigudong (연관 필드) > 부모sigudong (연관 필드) > 이름 (상태 필드)
@XXXToOne
@XXXToMany
연관 필드
를 select하면 묵시적인 조인이 발생한다.//엔티티
select h.sigudong
from Hospital h
//컬렉션
select h.hosImgs
from Hospital h
select s.*
from Hospital h join Sigudong s
on h.sigudong_id = s.sigudong_id;
select i.*
from Hospital h join HosImg i
on h.hospital_id = i.hospital_id;
public class MyH2Dialect extends H2Dialect {
public MyH2Dialect() {
registerFunction("group_concat", new StandardSQLFunction("group_concat", StandardBasicTypes.STRING));
}
}
<property name="hibernate.dialect" value="dialect.MyH2Dialect"/>
org.hibernate.dialect
에 있는 기본 JPQL 방언들도 위와 같이 등록 되어있다.애플리케이션 로딩 시점
에 특정 이름에 초기화하고 사용하는 쿼리Spring Data JPA
의 @Query
의 경우도 NamedQuery 로 등록하여 사용하는 것이다.@Entity
@NamedQuery(
name = "Member.findByUserName",
query = "select m from Member m where m.username = :username")
public class Member {
// ...
}
em.createQuery("Member.findByUserName", Member.class)
.setParameter("username", "두부쿠키");
int resultCount = em.createQuery("update Member m set m.salary = m.salary * 1.2")
.executeUpdate();
// 적용된 엔티티 객체 수(레코드 수) 반환
영속성 컨텍스트의 1차 캐시
와 DB
의 정보 불일치
가 있을 수 있다.int resultCount = em.createQuery("update Member m set m.age = 20")
.executeUpdate();
System.out.println(resultCount);
// 이 변경 값이 DB에는 날라가서 적용되어있지만
// 현재 영속성 컨텍스트 내부에서는 변경이 안되어 있다.
em.clear(); // 이게 없냐 있냐에 따라 달라짐
List<Member> select_m_from_member_m_2 = em.createQuery("select m from Member m ", Member.class).getResultList();