JPQL 테스트
@SpringBootTest
@Transactional
public class QuerydslBasicTest {
@Autowired
EntityManager em;
@BeforeEach
public void before(){
Team teamA = new Team("teamA");
Team teamB = new Team("teamB");
em.persist(teamA);
em.persist(teamB);
Member member1 = new Member("member1", 10, teamA);
Member member2 = new Member("member2", 20, teamA);
Member member3 = new Member("member3", 30, teamB);
Member member4 = new Member("member4", 40, teamB);
em.persist(member1);
em.persist(member2);
em.persist(member3);
em.persist(member4);
}
@Test
public void startJPQL(){
//member 1 찾기
String qlString ="" +
"select m from Member m " +
"where m.username = :username ";
Member findMember = em.createQuery(qlString, Member.class)
.setParameter("username", "member1").getSingleResult();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
QueryDsl 테스트
@SpringBootTest
@Transactional
public class QuerydslBasicTest {
@Autowired
EntityManager em;
@BeforeEach
public void before(){
Team teamA = new Team("teamA");
Team teamB = new Team("teamB");
em.persist(teamA);
em.persist(teamB);
Member member1 = new Member("member1", 10, teamA);
Member member2 = new Member("member2", 20, teamA);
Member member3 = new Member("member3", 30, teamB);
Member member4 = new Member("member4", 40, teamB);
em.persist(member1);
em.persist(member2);
em.persist(member3);
em.persist(member4);
}
@Test
public void startQuerydsl(){
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
QMember m = new QMember("m");
Member findMember = queryFactory
.select(m)
.from(m)
.where(m.username.eq("member1"))//파라미터 바인딩 처리
.fetchOne();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
JPAQueryFactory를 필드로 제공하면 동시성 문제가 생기는가?
fetch() : 쿼리문을 처리하고 반환되는 값들을 그대로 리스트로 가져온다. -> 반환되는 데이터가 없을 경우 빈 리스트(empty list)가 반환됨.
fetchOne() : 단 하나의 데이터를 조회합니다. 쿼리문에 의해 반환되는 데이터가 0개면 NULL, 1개이면 정상, 2개 이상이면 NonUniqueResultException 발생.
fetchFirst() : limit(1).fetchOne() 과 동일.
사용방법 2가지
QMember qmember = new QMember("m"); //별칭 직접 사용하기
QMember qMember = QMember.member; //기본 인스턴스 사용하기.
@Test
public void startQuerydsl(){
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
QMember m = new QMember("m");
Member findMember = queryFactory
.select(m)
.from(m)
.where(m.username.eq("member1"))//파라미터 바인딩 처리
.fetchOne();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
기본 인스턴스 사용시 static import를 통해서 바로 Qmember가 만들어져있는것을 사용할 수있다.
import static study.querydsl.entity.QMember.*;
@Test
public void search(){
Member findMember = queryFactory
.selectFrom(member)
.where(member.username.eq("member1")
.and(member.age.eq(10)))
.fetchOne();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
@Test
public void searchAndParam(){
List<Member> result1 = queryFactory
.selectFrom(member)
.where(member.username.eq("member1"),
member.age.eq(10))
.fetch();
assertThat(result1.size()).isEqualTo(1);
}
member.username.eq("member1") // username = 'member1'
member.username.ne("member1") //username != 'member1'
member.username.eq("member1").not() // username != 'member1'
member.username.isNotNull() //이름이 is not null
member.age.in(10, 20) // age in (10,20)
member.age.notIn(10, 20) // age not in (10, 20)
member.age.between(10,30) //between 10, 30
member.age.goe(30) // age >= 30
member.age.gt(30) // age > 30
member.age.loe(30) // age <= 30
member.age.lt(30) // age < 30
member.username.like("member%") //like 검색
member.username.contains("member") // like ‘%member%’ 검색
member.username.startsWith("member") //like ‘member%’ 검색
JPQL
select
count(m), //회원수
sum(m.age), //나이 합
AVG(m.age), //나이 평균
MAX(m.age), //최대 나이
MIN(m.age) //최소 나이
from Member m
Querydsl
@Test
public void aggregation() throws Exception{
List<Tuple> result = queryFactory
.select(member.count(),
member.age.sum(),
member.age.avg(),
member.age.max(),
member.age.min())
.from(member)
.fetch();
Tuple tuple = result.get(0);
assertThat(tuple.get(member.count())).isEqualTo(4);
assertThat(tuple.get(member.age.sum())).isEqualTo(100);
assertThat(tuple.get(member.age.avg())).isEqualTo(25);
assertThat(tuple.get(member.age.max())).isEqualTo(40);
assertThat(tuple.get(member.age.min())).isEqualTo(10);
}
문서에 설명으로는 이렇게 나와있다.
Tuple
defines an interface for generic query result projection
쿼리 결과를 튜플 형태로 표현할 때 사용된다.
여러 타입을 조회할 때 사용하기 위해서 querydsl에서 만든 것