//검색
List<Member> result =
em.createQuery("select m From Member m where m.name like ‘%kim%'", Member.class)
.getResultList();
select m from Member as m where m.age > 18
TypeQuery : 반환 타입이 명확할 때 사용Query : 반환 타입이 명확하지 않을 때 사용query.getResultList() : 결과가 하나 이상일 때 리스트 반환, 결과가 없으면 빈 리스트 반환query.getSingleResult() : 결과가 정확히 하나, 단일 객체 반환, 결과가 없거나 둘 이상이면 예외 발생// 파라미터 바인딩 이름 기준일 때 (:username)
Member result =
em.createQuery("select m from Member m where m.username = :username", Member.class)
.setParameter("username", "member1")
.getSingleResult();
System.out.println("result.getUsername() = " + result.getUsername());
위치기준(?1)도 제공하지만 위치 기반은 웬만하면 사용하지 않는것이 좋음
m m.team, 임베디드 타입 m.address, 스칼라 타입 m.username, m.age (숫자, 문자 등 기본 데이터 타입) List<Team> result = em.createQuery("select m.team from Member m", Team.class)
.getResultList();
// 해당 쿼리를 실행하면 join이 발생하기 때문에(Member에 있는 Team 참조)
List<Team> result = em.createQuery("select t from Member m join m.team t", Team.class)
.getResultList();
// 그냥 처음부터 join을 넣어서 쿼리를 만들어주는 것이 좋음
여러 값 조회
SELECT m.username, m.age FROM Member m
List resultList = em.createQuery("select m.username, m.age FROM Member m")
.getResultList();
Object o = resultList.get(0);
Object[] result = (Object[]) o;
List<Object[]> resultList = em.createQuery("select m.username, m.age FROM Member m")
.getResultList();
Object[] result = resultList.get(0);
public class MemberDTO{
private String username;
private int age;
public MemberDTO(String username, int age){
this.username = username;
this.age = age;
}
...
}
em.createQuery(
"select new jpql.MemberDTO(m.username, m.age) FROM Member m", MemberDTO.class)
.getResultList();
MemberDTO memberDTO = result.get(0);
setFirstResult(int startPosition) : 조회 시작 위치 (0부터 시작) setMaxResults(int maxResult) : 조회할 데이터 수//페이징 쿼리
List<Member> resultList =
em.createQuery("select m from Member m order by m.age desc", Member.class)
.setFirstResult(1)
.setMaxResults(10)
.getResultList();
//inner는 생략 가능
String query="select m from Member m inner join m.team t";
List<Member> result = em.createQuery(query, Member.class)
.getResultList();
//outer는 생략 가능
String query="select m from Member m left outer join m.team t";
List<Member> result = em.createQuery(query, Member.class)
.getResultList();
//cross join
String query="select m from Member m,Team t where m.username=t.name";
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();
String query="select m from Member m left join Team t on m.username=t.name";
List<Member> result = em.createQuery(query, Member.class)
.getResultList();
select m from Member m where m.age > (select avg(m2.age) from Member m2) select m from Member m where (select count(o) from Order o where m = o.member) > 0 서브 쿼리 지원 함수
한계
JPQL 타입 표현
String query="select m.username, 'HELLO', true from Member m
where m.type=jpql.MemberType.ADMIN";
List<Member> result = em.createQuery(query, Member.class)
.getResultList();
//파라미터 바인딩으로 하면 복잡하지 않음
String query="select m.username, 'HELLO', true from Member m
where m.type=:userType";
List<Member> result = em.createQuery(query, Member.class)
.setParameter("userType",MemberType.ADMIN)
.getResultList();
em.createQuery("select i from Item i where type(i) = Book", Item.class)
.getResultList();
기타
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();
String query=
"select " +
"case t.name "+
" when '팀A' then '인센티브110%' " +
" when '팀B' then '인센티브120%' " +
" else '인센티브105%' " +
"end " +
"from Team t";
List<String> result = em.createQuery(query, String.class)
.getResultList();
// 사용자 이름이 없으면 이름 없는 회원을 반환
String query= "select coalesce(m.username, '이름 없는 회원') from Member m";
List<String> result = em.createQuery(query, String.class)
.getResultList();
// 사용자 이름이 ‘관리자’면 null을 반환하고 나머지는 본인의 이름을 반환
String query= "select nullif(m.username, '관리자') from Member m";
List<String> result = em.createQuery(query, String.class)
.getResultList();
// H2Dialect를 상속
public class MyH2Dialect extends H2Dialect {
// 생성자에서 registerFunction해서 등록 (이름, 조건)
public MyH2Dialect(){
registerFunction("group_concat", new StandardSQLFunction("group_concat", StandardBasicTypes.STRING));
}
}