Note
BooleanBuilder => BooleanExpression 리팩토링
- 기존에는 쿼리 클래스 안에 projection()이라는 메서드 안에 변수 BooleanBuilder search를 선언했다.
- 그 다음 쿼리의 where절에 넣고 싶은 조건을 search.and(조건) 형태로 여러 개 나열하는 방식이었다.
- 하지만, BooleanBuilder를 사용하면 predicate() 메서드가 길어져서 가독성이 떨어졌다. 그리고 해당 조건에 대해 재사용이 불가능하다는 단점이 있었다.
- 그래서 김영한 강사님께서 알려주신 BooleanExpression을 적용하기로 했다.
Ex) 검색 조건 쿼리 - BooleanBuilder 를 사용한 이전 코드
<hide/>
public BooleanBuilder predicate(Member memberVO) {
BooleanBuilder search = new BooleanBuilder();
if (StringUtil.isNotEmpty(Member.getMemberId())) {
search.and(member.memberId.containsIgnoreCase(Member.getMemberId()));
}
if (StringUtil.isNotEmpty(Member.getMembeNm())) {
search.and(member.memberNm.containsIgnoreCase(Member.getMembeNm()));
}
return search;
}
public List<Member> getSearchedMemberList(Member memberVO) {
return queryFactory
.select(projection())
.from(member)
.where(predicate(Member)
.fetch();
}
- 위와 같이 "predicate()" 이라는 메서드가 꼭 필요하다.
- get 메서드의 return문을 보면 where 절 안에 predicate()이 들어가 있는데 predicate()라는 단어만 봤을 때는 어떤 조건인지 정확하게 파악하기 힘들다.
- 따라서, 각 조건에 대한 메서드를 분리하려고 한다.
Ex) 검색 조건 쿼리 - BooleanExpression 적용 후
<hide/>
private BooleanExpression eqMemberId(String memberId) {
if (!StringUtil.isEmpty(memberId)) {
return member.memberId.containsIgnoreCase(memberId);
}
return null;
}
private BooleanExpression eqMemberNm(String MemberNm) {
if (!StringUtil.isEmpty(MemberNm)) {
return member.MemberNm.containsIgnoreCase(MemberNm);
}
return null;
}
public List<Member> getSearchedMemberList(Member memberVO) {
return queryFactory
.select(projection())
.from(member)
.where(eqMemberId(memberVO.getMemberId()),
eqMemberNm(memberVO.getMemberNm()),
)
.fetchOne();
}
- 위와 같이 WHERE 절 안에 여러 개의 조건을 메서드명으로 명확하게 구분해서 하나씩 넣을 수 있다.
- 그러면 predicate() 라는 메서드가 필요없어진다.
- 위에 예시는 MemberId, MemberNm 을 가지고 검색하는 메서드인데 해당 필드에 값을 넣지 않아도 검색되도록 해야하기 때문에 VO 에 값이 들어왔는지 아닌지 확인하는 if 문이 필요하다.
에러 해결
<hide/>
Already included file name 'c:/learning/LearningDetail.vue' differs from file name 'c:/LearningDetail.vue' only in casing.
The file is in the program because:
Imported via "@/components/ai/learning/LearningDetail.vue" from file 'c:/learning/LearningDetail.vue'
Root file specified for compilation
Root file specified for compilationVetur(1261)
- 오류
- 원인: 부모, 자식 컴포넌트에 import 문을 중복으로 선언했다.
- 해결
failed to resolve component
- 오류: 학습 paramEdit 컴포넌트를 해결할 수 없다?
- 원인: import문 없이 컴포넌트를 바로 사용했다.
- 해결: import 추가
typeError
Uncaught (in promise) TypeError: data.includes is not a function
- 오류: typeError
- 원인: GET 요청의 결과로 받은 데이터를 담는데 오류가 있었다.
- 해결:
- axios의 http 요청으로 res 데이터를 받는다.
- res.data를 그대로 넣는게 아니라 res.data.list 같은 형태로 필요한 부분만 해당 컴포넌트의 변수 state의 list 안에 넣어준다.
property "(메서드명)" was accessed during render but is not defined on instance;
- 오류 [Vue warn]: Property "getModelParamList" was accessed during render but is not defined on instance.
- 원인: ParamEdit 컴포넌트에서 watch() 부분이 잘못됐다.
- 해결
- 1) tableData
- 파람리스트 정보를 입력할 때마다 store에 커밋해준다.
- 2) getLearning: Learning 데이터에 변화가 생긴 경우, 콤보 박스에서 다른 modeld 를 선택한 경우가 이에 해당한다.
- LearningEdit 컴포넌트에서 store.set 한다.
- 그러면Learning 데이터가 바뀔 때마다 get()의 결과가 바뀔 것이다.
- 바뀔 때마다 해당 내용을 LearningParamEdit 에서 store.get 해서 해당 내용의 바뀐 modelId를 읽어와서 이에 대한 파람리스트를 조회해준다.
- 1) tableData
- 오류
- 원인
- 해결:
'개발 일지 > 주간 개발 일지' 카테고리의 다른 글
[05월 3주차] querydsl JOIN 방법 (0) | 2023.05.15 |
---|---|
[05월 2주차] Vue.js 3 modal(모달, 팝업) 창 띄우기 (0) | 2023.05.13 |
[04월 4주차] 프론트엔드 디버깅 방법, PostgreSQL 필드 변경 시 MySQL 과 문법상 차이점 (0) | 2023.04.30 |
[04월 3주차] Vue.js 3 과 Spring (0) | 2023.04.22 |
[04월 2주차] JPA, Vue.js 3 기본 명령어 (0) | 2023.04.16 |