Notice
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 상속 관계 매핑
- 창의충전소
- web view
- multipart upload
- BFS
- bfs dfs
- 노마드코더
- React Natvive
- 자료구조
- 구현
- 경우의 수
- React Native
- Navigation
- springboot
- 오블완
- 티스토리챌린지
- Project Bee
- 원복
- 백준 1992
- 버튼 활성화
- 이영직
- 폴더구조
- ReactNative
- FlatList
- 휴대폰 기기
- service 테스트
- 해외 대외활동
- react
- 완전탐색
- 비트마스킹
Archives
- Today
- Total
유미의 기록들
[개인과제 - Spring 플러스] 레거시 코드 리팩토링 본문
728x90
반응형
레거시 코드(Legacy Code)란?
나를 포함한 모든 개발자가 기존에 개발했던 코드
잘 작동되는 코드여도 오래된 기술을 사용할 수 있고, 현재는 사용되지 않는 코드들도 있다. 결합도가 높거나, 테스트 코드가 없거나 가독성이 떨어지는 등의 특징들을 가지고 있다
💡 목표
- 레거시 코드의 리팩토링을 통해 코드의 가독성과 유지보수성을 높이고 개발 생산성을 향상시킬 수 있다
- 복잡한 구조를 단순화하고, 최신 기술과 패턴을 적용함으로써 확장성과 유연성을 확보할 수 있다
- 성능을 개선하고, 보안성을 강화할 수 있으며, 변경에 대한 리스크를 줄여 안정적인 서비스 운영에 기여할 수 있다
📄 리팩토링한 내용
🚀 트러블 슈팅
코드 추가 - 4. QueryDSL 을 사용하여 검색 기능 추가
[검색 조건]
- 검색 키워드로 일정의 제목을 검색할 수 있어요.
- 제목은 부분적으로 일치해도 검색이 가능해요.
- 일정을 생성일 최신순으로 정렬해주세요.
- 담당자의 닉네임은 부분적으로 일치해도 검색이 가능해요.
[검색 결과]
- 일정에 대한 모든 정보가 아닌, 제목만 넣어주세요.
- 해당 일정의 담당자 수를 넣어주세요.
- 해당 일정의 총 댓글 개수를 넣어주세요.
- 검색 결과는 페이징 처리되어 반환되도록 합니다.
⚠️ 일정 담당자 수, 댓글 개수 결과 반환 안됨
처음에 일정의 담당자 수와, 총 댓글 개수를 select절에서 조회 대상을 지정할 때, `todo.managers.size()`나 `todo.comments.size()`와 같은 컬렉션의 크기를 바로 가져오려고 했다.
queryFactory
.select(new QTodoSearchResponse(
todo.title,
todo.managers.size().as("managerCount"),
todo.comments.size().as("commentCount")
))
`size()`는 컬렉션 크기를 JPA엔티티가 로드된 상태(메모리 상에서 이미 로드된 컬렉션)에서 가져오는 것이지, 데이터베이스 쿼리로 변환되는 것이 아니다. 즉 데이터베이스 쿼리에서 `COUNT`함수로 집계되지 않으므로, 실제 `COUNT`를 사용하는 것을 권장한다
⚠️ 검색 조건 닉네임을 추가하여 요청했을 때 에러 발생
arta.servlet.ServletException: Request processing failed: org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.query.SemanticException: Ambiguous unqualified attribute reference 'user' (qualify the attribute reference by an identification variable)
private BooleanExpression nicknameContain(String nickname) {
return StringUtils.hasText(nickname) ? user.nickname.contains(nickname) : null;
}
담당자는 User테이블의 외래 키로 연결되어 있기 때문에 `user.nickname`으로 검색하려면 반드시 User 테이블을 join 해야만 닉네임에 접근할 수 있다. 하지만 Todo 테이블과 Manager 테이블만 조인을 했기 때문에 다음과 같은 에러가 발생하였다
수정 방법
List<TodoSearchResponse> content=queryFactory
.select(new QTodoSearchResponse(
todo.title,
manager.count().as("managerCount"),
comment.count().as("commentCount")
))
.from(todo)
.leftJoin(todo.managers,manager)
.leftJoin(todo.comments,comment)
.leftJoin(todo.user,user)
.where(
titleContain(condition.getTitle()),
nicknameContain(condition.getNickname())
)
.groupBy(todo.id)
.orderBy(todo.createdAt.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
1. managers.size()나 comments.size() 대신, 각각의 엔티티를 join한 후 group by와 count를 사용해서 컬렉션의 크기를 효율적으로 계산하고, 성능 문제를 피할 수 있었다
2. 담당자, 댓글 테이블 뿐만 아니라 유저 테이블까지 조인을 해주면서 검색 조건을 추가했을 때 발생하는 에러를 해결할 수 있었다.
select
t1_0.title,
count(m1_0.id),
count(c1_0.id)
from
todos t1_0
left join
managers m1_0
on t1_0.id=m1_0.todo_id
left join
comments c1_0
on t1_0.id=c1_0.todo_id
left join
users u1_0
on u1_0.id=t1_0.user_id
where
u1_0.nickname=?
group by
t1_0.id
limit
?, ?
728x90
반응형
'대외활동 기록 > 내일배움캠프' 카테고리의 다른 글
[최종 프로젝트] 생성자 대신 정적 팩토리 메서드 (0) | 2024.11.08 |
---|---|
[최종 프로젝트] Entity 계층 구조에 따른 상속 관계 매핑 (0) | 2024.11.07 |
[개인과제 -Spring 숙련] 회원 CRUD API 구현 (Level 2) (0) | 2024.08.29 |
[개인 과제 -Spring숙련] JPA를 활용한 일정관리 앱 서버 설계 (Level 1) (0) | 2024.08.22 |
[개인 과제 - Spring입문] 일정 관리 앱 서버 (0) | 2024.08.16 |
Comments