해결된 질문
작성
·
3.1K
0
private List<Member> searchMember2(String usernameCond, Integer ageCond) {
return queryFactory
.selectFrom(member)
.where(allEq(usernameCond,ageCond))//메서드를 만들어서 한번에 처리도 가능, 조립가능!!
.fetch();
}
private BooleanExpression usernameEq(String usernameCond) {
return usernameCond != null ? member.username.eq(usernameCond) : null;
}
private BooleanExpression ageEq(Integer ageCond) {
return ageCond != null ? member.age.eq(ageCond) : null;
}
private BooleanExpression allEq(String usernameCond, Integer ageCond){
return usernameEq(usernameCond).and(ageEq(ageCond));
}
강사의 내용에서 알려주신 코드중 usernameEq메서드의 return값이 null일 때 어떤식으로 처리하는 것이 좋을까요???
BooleanBuilder객체에 함수를 체이닝 할까 고민해봤지만 체이닝이 잘안되기도하고, BooleanBuilder를 사용할꺼면 usernameEq, ageEq와 같은 메서드를 만드는 의미가 없다고 생각아 합니다..... 좋은 방법있다면 알려주시면 감사하겠습니다.
답변 1
1
@Test
public void dynamicQuery_WhereParam(){
String usernameParam = null;
Integer ageParam = 10;
List<Member> result = searchMember2(usernameParam, ageParam);
for (Member member1 : result) {
System.out.println("member1 = " + member1);
}
assertThat(result.size()).isEqualTo(1);
}
private List<Member> searchMember2(String[] usernameCond, Integer ageCond) {
return queryFactory
.selectFrom(member)
.where(ageEqNullSafe(ageCond).and(usernameInNullSafe(usernameCond)))
.fetch();
}
private BooleanBuilder ageEqNullSafe(Integer age) {
return nullSafeBuilder(() -> member.age.eq(age));
}
private BooleanBuilder usernameInNullSafe(String[] username){
return nullSafeBuilder(()->member.username.in(username));
}
nullsafeBuilder를 이용해서 이것저것 테스트 중인데 usernameInNullSafe메서드를 보면 in절에 ArrayList, String[] 등의 iterable한 객체들이 들어가면 아래와같은 에러가 발생하더라고요ㅠㅠㅠㅠ
java.lang.NullPointerException
at com.querydsl.core.types.dsl.SimpleExpression.in(SimpleExpression.java:205)
그래서 혹시 in절에 String타입으로 넣고 null을 넣어도 에러가 뜨나 확인해보려고 아래와 같이 작성하니 잘작동합니다.ㅠㅠㅠㅠㅠ
@Test
public void dynamicQuery_WhereParam(){
String usernameParam = null;
Integer ageParam = 10;
List<Member> result = searchMember2(usernameParam, ageParam);
for (Member member1 : result) {
System.out.println("member1 = " + member1);
}
assertThat(result.size()).isEqualTo(1);
}
private List<Member> searchMember2(String usernameCond, Integer ageCond) {
return queryFactory
.selectFrom(member)
.where(ageEqNullSafe(ageCond).and(usernameInNullSafe(usernameCond)))
.fetch();
}
private BooleanBuilder ageEqNullSafe(Integer age) {
return nullSafeBuilder(() -> member.age.eq(age));
}
private BooleanBuilder usernameInNullSafe(String username){
return nullSafeBuilder(()->member.username.in(username));
}
like문은 어떤가 확인해보기 위해 아래의 코드와같이 like문에 null을 입력하니 iterable객체가 아니여도 에러가 발생하더라고요ㅠㅠㅠㅠ
@Test
public void dynamicQuery_WhereParam(){
String usernameParam = null;
Integer ageParam = 10;
List<Member> result = searchMember2(usernameParam, ageParam);
for (Member member1 : result) {
System.out.println("member1 = " + member1);
}
assertThat(result.size()).isEqualTo(1);
}
private List<Member> searchMember2(String usernameCond, Integer ageCond) {
return queryFactory
.selectFrom(member)
.where(ageEqNullSafe(ageCond).and(usernameLike(usernameCond)))
.fetch();
}
private BooleanBuilder usernameLike(String username){
return nullSafeBuilder(()->member.username.like(username));
}
private BooleanBuilder ageEqNullSafe(Integer age) {
return nullSafeBuilder(() -> member.age.eq(age));
}
in절이나 like절에 받아들일 수 없는 파라미터가 존재하는 것 같은데 이런경우에는 어쩔수없이 BooleanBuilder를 사용해야 하는 건가요? 아님 제가 코드를 잘못 작성하고 있는 걸까요...?
혹시 and 조건만 있다면 where() 안에 , 로 추가하는 것을 어떻게 생각하십니까?
그렇게 하면 null 조건에 대해 걱정할 필요가 없을 것 같습니다.
백엔드 개발자 취준생님의 코드를 보다보니 혹시 하는 생각이 들어서 질문드립니다 :)
where절에 or조건도 사용해야해서 or조건들만 BooleanBuilder를 객체에 조건들을 체이닝하고, 나머지 and조건들은 , 로 코드를 넣는식으로 해결하였습니다! 하지만 like 도는 in절의 파라미터자체에 null을 넣지못하는 상황이여서 nullSafeBuiler를 사용하지 못하는 아쉬움이 있습니다ㅠㅠㅠ
private BooleanExpression nameLike(String writer) {
return StringUtils.hasText(writer) ? article.member.name.contains(writer) : null;
}
위와 같이 원래 강의에서 구현하던 식으로 writer자체를 먼저 null처리를 해주면서 구현하였습니다
감사합니다!딱 원했던 해결책입니다!정말 감사합니다!