MyBatis
, SpringJdbcTemplate
함께 사용
단순 JPQL은 동적 쿼리를 만들기 어렵다.
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();
String sql = "SELECT ID, AGE, TEAM_ID, NAME FROM MEMBER WHERE NAME = 'kim'";
List<Member> resultList = em.createNativeQuery(sql, Member.class)
.getResultList();
delete_문 :: = delete_절 [where_절]
select m from Member as m where m.age > 18
select
COUNT(m), //회원수
SUM(m.age), //나이 합
AVG(m.age), //평균 나이
MAX(m.age), //최대 나이
MIN(m.age) //최소 나이
from Member m
TypeQuery
: 반환 타입이 명확할 때 사용TypedQuery<Member> query1 = em.createQuery("select m from Member m", Member.class);
Query
: 반환 타입이 명확하지 않을 때 사용Query query2 = em.createQuery("select m.userName, m.age from Member m");
query.getResultList()
: 결과가 하나 이상일 때, 리스트 반환
List<Member> members = em.createQuery("select m from Member m", Member.class)
.getResultList();
query.getSingleResult()
: 결과가 정확히 하나, 단일 객체 반환
javax.persistence.NoResultException
javax.persistence.NonUniqueResultException
Member member = em.createQuery("select m from Member m", Member.class)
.getSingleResult();
em.createQuery("SELECT m FROM Member m where m.userName = :username")
.setParameter("username", "member1")
.getSingleResult()
SELECT m FROM Member m
-> 엔티티 프로젝션
SELECT m.team FROM Member m
-> 엔티티 프로젝션
select t from Member m join m.team t
SELECT m.address FROM Member m
-> 임베디드 타입 프로젝션SELECT m.username, m.age FROM Member m
-> 스칼라 타입 프로젝션SELECT m.username, m.age FROM Member m
Query 타입으로 조회
Object[] 타입으로 조회
List resultList = em.createQuery("select m.userName, m.age from Member m")
.getResultList();
Object o = resultList.get(0);
Object[] result = (Object[])o;
System.out.println("userName = " + result[0]);
System.out.println("age = " + result[1]);
@Setter @Getter
@AllArgsConstructor
public class MemberDto {
private String userName;
private int age;
}
List<MemberDto> resultList = em.createQuery(
"select new hellojpa.jpql.MemberDto(m.userName, m.age) from Member m",
MemberDto.class)
.getResultList();
setFirstResult(int startPosition)
: 조회 시작 위치 (0부터 시작)setMaxResults(int maxResult)
: 조회할 데이터 수//페이징 쿼리
String jpql = "select m from Member m order by m.age desc";
List<Member> resultList = em.createQuery(jpql, Member.class)
.setFirstResult(10)
.setMaxResults(20)
.getResultList();
select
member0_.id as id1_0_,
member0_.age as age2_0_,
member0_.team_id as team_id4_0_,
member0_.user_name as user_nam3_0_
from
member member0_
order by
member0_.age desc limit ? offset ?
SELECT m FROM Member m [INNER] JOIN m.team t
inner 생략 가능
SELECT m FROM Member m LEFT [OUTER] JOIN m.team t
outer 생략 가능
select count(m) from Member m, Team t where m.username = t.name
JPQL:
SELECT m, t FROM Member m LEFT JOIN m.team t on t.name = 'A'
SQL:
SELECT m.*, t.* FROM Member m LEFT JOIN Team t ON m.TEAM_ID=t.id and t.name='A'
JPQL:
SELECT m, t FROM Member m LEFT JOIN Team t on m.username = t.name
SQL:
SELECT m.*, t.* FROM Member m LEFT JOIN Team t ON m.username = t.name
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
메인 쿼리랑 서브 쿼리랑 서로 관계가 없어야 성능이 잘 나옴
{ALL | ANY | SOME} (subquery) |
select m from Member m where **exists** (select t from m.team t where t.name = ‘팀A')
select o from Order o where o.orderAmount > **ALL** (select p.stockAmount from Product p)
select m from Member m where m.team = **ANY** (select t from Team t)
"select m.userName, 'HELLO', true, 10L from Member m"
jpabook.MemberType.Admin
(패키지명 포함)"select m from Member m where m.type = hellojpa.jpql.MemberType.ADMIN";
String query = "select m from Member m where m.type = :type";
List<Member> result = em.createQuery(query, Member.class)
.setParameter("type", MemberType.ADMIN)
.getResultList();
"select "
+ "case when m.age <= 10 then '학생요금' "
+ "when m.age >= 60 then '경로요금' "
+ "else '일반요금' "
+ "end "
+ "from Member m";
"select "
+ "case t.name"
+ "when 'teamA' then '인센티브 120%' "
+ "when 'teamB' then '인센티브 110%' "
+ "else '인센티브 105%' "
+ "end "
+ "from Team t";
COALESCE: 하나씩 조회해서 null이 아니면 반환
사용자 이름이 없으면 이름 없는 회원을 반환
"select coalesce (m.userName, '이름 없는 회원') from Member m";
NULLIF: 두 값이 같으면 null 반환, 다르면 첫번째 값 반환
사용자 이름이 ‘관리자’면 null을 반환하고 나머지는 본인의 이름을 반환
"select NULLIF (m.userName, '관리자') from Member m"
CONCAT 문자 더하기
"select concat('a', 'b') from Member m"
SUBSTRING 문자 자르기
"select substring(m.userName, 0, 2) from Member m"
LOCATE (a, b) - b에서 a가 몇 번째에 있는지 찾아라 (인덱스가 0부터가 아니라 1부터 시작, 없으면 0을 반환)
"select locate('ber', m.userName) from Member m"
SIZE, INDEX(JPA 용도) size: 연관 관계에서 컬렉션 개수를 알 수 있음
"select size(t.members) from Team t"
사용하는 DB 방언을 상속 받고, 사용자 정의 함수를 등록한다.
select function('group_concat', i.name) from Item i