스프링데이터 + JPA/QueryDSL 38

26. SQL 함수 호출

QueryDSL로 DB의 함수를 호출하는 쿼리를 만드는 것이 가능하다. @Test public void sqlFunction(){ List result = query.select(Expressions.stringTemplate( "function('replace', {0}, {1}, {2})", m.username, "member", "M" )).from(m) .fetch(); for (String s : result) { System.out.println("s = " + s); } } Expressions.stringTemplate( "function('DB함수명', {0}, {1} ....)", 0번째인자, 1번째인자 .... ) 이렇게 쓴다. 표현식.문자형템플릿(function('함수명', 인자들...

25. 수정, 삭제 벌크연산

벌크란 여러 row들을 한번에 처리 하는 것. 근데 벌크는, 영속성 컨텍스트를 무시하고 직접 DB에 쿼리를 넣는다. 그래서, 만약 조회해 온 다음에 벌크를 하게 되면, 영속성 컨텍스트에 있는 데이터와 DB에 있는 데이터가 맞지 않을 수도 있다. 영속성 컨텍스트에 엔티티가 있으면 조회했을 때 그걸 주니까. 보통 그래서 해결책은 벌크연산 이후에 데이터를 조회해오거나 벌크연산 후 영속성 컨텍스트를 초기화 시켜버리는 것 https://qwefdg3.tistory.com/800 그래서 아예 스프링 Data JPA에서는 옵션을 제공해 줌 https://qwefdg3.tistory.com/886 이렇게 수정 등을 했을 때(delete도 수정) 자동으로 영속성 컨텍스트를 초기화 해 준다던지 그런 옵션이 있음. @Tes..

24. 동적쿼리. Where 다중 파라미터

where의 인자를 여러개 주면 자동으로 and로 묶어지는 특성을 이용하여 동적 쿼리를 만들 수 있다. private Predicate usernameEq(String usernameCond){ return usernameCond != null ? m.username.eq(usernameCond) : null; } private Predicate ageEq(Integer ageCond){ return ageCond != null? m.age.eq(ageCond) : null; } 먼저 null이 아닐 경우 eq 표현식을 반환하는 메소드를 만들어 줬다. 그리고, private List searchMember2(String usernameCond, Integer ageCond){ return query.se..

23. 동적쿼리. BooleanBuilder 방식

동적쿼리는 2가지 방식이 있음. BooleanBuilder를 사용하는 방법과 Where문 안에 다중 파라미터를 사용하는 방법임. 이 시간에는 BooleanBuilder를 사용하는 방법을 알아보겠음. 우선, BooleanBuilder도 QueryDSL의 표현식을 상속받은 클래스임. private List searchMember1(String usernameParam, Integer ageParam){ BooleanBuilder builder = new BooleanBuilder(); if(usernameParam != null){ builder.and(m.username.eq(usernameParam)); } if(ageParam != null){ builder.and(m.age.eq(ageParam));..

22. @QueryProjection

@QueryProjection이라는 것을 사용할 것이다. 이것으 사용방법은 정말 간단하다. Dto의 프로젝션으로 사용하길 원하는 생성자에게 @QueryProjection public MemberDto(String username, int age) { this.username = username; this.age = age; } 이렇게 붙여주면 그만이다. 또 하나 해야할 건, 빌드해 줘야 한다. Q엔티티 빌드할 때와 마찬가지로 gradle -> other -> compileQuerydsl 해 주면, 빌드 되면서 생성자 하나 있는 파일이 생긴다. @Generated("com.querydsl.codegen.DefaultProjectionSerializer") public class QMemberDto exte..

21. 프로젝션 Dto

QueryDSL로 프로젝션으로 Dto를 직접 받는 방법은 크게 3가지가 있다. 직접 받는다기 보다는 바로 받는다. 가 맞는 것 같다. setter가 활용되는 bean방식 필드에 직접 주입해주는 fields 방식 생성자 방식 먼저 bean 방식부터. 그 전에, jpql방식 @Test public void findDtoBytJPQL(){ List result = em.createQuery("select new study.querydsl.dto.MemberDto(m.username, m.age)" + " from Member m", MemberDto.class) .getResultList(); for (MemberDto memberDto : result) { System.out.println("memberDt..

20. 프로젝션

프로젝션이란 select에 무얼 가지고 올지 대상을 지정하는 것. 보통 이제 세가지 경우로 나뉘는데, 단일 프로젝션 복수의 프로젝션 Dto 조회 (이것도 사실 상 DB상에서 복수의 프로젝션 범주) 이정도 단일 조회는 엔티티 자체를 조회해오거나, 아니면 m.username해서 하나만 조회해 올 때. @Test public void simpleProjection(){ List result = query.select(m.username).from(m).fetch(); for (String s : result) { System.out.println("s = " + s); } } 그냥 조회해 오는거다. select 절 안에 조회해올것의 표현식을 쓰고, 가져오면 된다. Q클래스는 엔티티의 정보를 담은 표현식들의 모..

19. 상수, 문자 더하기

상수 @Test public void constant(){ List result = query.select(m.username, Expressions.constant("A")) .from(m) .fetch(); for (Tuple tuple : result) { System.out.println("tuple = " + tuple); } } Expressions 라는 게 있다. QueryDSL껀데, QueryDSL용 표현식? 으로 바꿔주는 그런 것 같다. 그냥 기타 등등을 저기에 넣어둔 게 아닐까? 여튼 Expressions.constant() 하면 이름 그대로 상수를 넣을 수 있다. 그러면 JPQL에서 상수로 바뀌어 지는 모양이다. tuple = [member1, A] tuple = [member2, A..

18. CASE 문

SQL문에서 CASE문을 쓰는 건 처음봤다. 프로시저에서는 몰라도, SQL 쿼리에 직접 쓰는 건 처음봤다. @Test public void basicCase(){ List result = query.select(m.age .when(10).then("열살") .when(20).then("스무살") .otherwise("기타")) .from(m).fetch(); for (String s : result) { System.out.println("s = " + s); } } 뭐 보면, select 절 위주로 보면, m.age가 10일땐 "열살"로 가져오고, 20일 땐 "스무살", 나머지는 "기타"로 가져옴. 그렇게 문자열로 가져옴. 결과는 잘 나왔고, s = 열살 s = 스무살 s = 기타 s = 기타 /* ..