Skip to content

Commit df21a78

Browse files
authored
Create README.md
1 parent aaf72bc commit df21a78

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

README.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# 프로젝트 설계 중점
2+
3+
늘어나는 문제의 성격과 분야를 염두한 확장성, 유지보수성 높은 설계
4+
5+
# 설계 방법
6+
7+
### 1. Entity간의 상속 관계를 DB에서 구현시 Join 전략을 사용
8+
9+
![comssaInfra drawio](https://github.com/user-attachments/assets/96ad881d-af59-40c0-bba0-bcd990dc1a42)
10+
11+
### 2. QueryDsl을 사용
12+
13+
#### 공통된 조건으로 조회시에도 문제마다 중복되는 쿼리를 작성해야하는 문제점
14+
15+
- **전공 객관식** 문제를 카테고리로 조회
16+
17+
```java
18+
19+
@Query("SELECT DISTINCT nq FROM MajorMultipleChoiceQuestion nq "
20+
+ "LEFT JOIN FETCH nq.questionChoices "
21+
+ "WHERE nq.questionCategory IN :questionCategories ")
22+
List<MajorMultipleChoiceQuestion> findAllByQuestionCategoriesFetchChoices(
23+
@Param("questionCategories") List<QuestionCategory> questionCategories
24+
);
25+
```
26+
27+
- **자격증 객관식** 문제를 카테고리로 조회
28+
29+
```java
30+
31+
@Query("SELECT DISTINCT lnq FROM LicenseMultipleChoiceQuestion lnq "
32+
+ "LEFT JOIN FETCH lnq.questionChoices "
33+
+ "WHERE lnq.questionCategory IN :questionCategories ")
34+
List<LicenseMultipleChoiceQuestion> findAllByQuestionCategoriesFetchChoices(
35+
@Param("questionCategories") List<QuestionCategory> questionCategories);
36+
```
37+
38+
39+
#### QueryDsl로 해결
40+
- 문제를 조회하는 **공통된 조건** (조회할 테이블에 Where 조건을 적용)
41+
42+
```java
43+
public interface SelectWhereCategoriesAndLevels<T extends Question> {
44+
45+
default JPAQuery<T> selectWhereQuestionCategories(List<QuestionCategory> questionCategories) {
46+
return getQuestions()
47+
.where(
48+
whereCategories(
49+
getQuestionQClass(),
50+
questionCategories)
51+
);
52+
}
53+
54+
//구현체에서 Select할 실제 문제 테이블을 따로 구현
55+
JPAQuery<T> getQuestions();
56+
57+
```
58+
- 실제 구현체에서는 **조회할 테이블**만을 설정해준다.
59+
```java
60+
@Override
61+
public JPAQuery<LicenseMultipleChoiceQuestion> getQuestions() {
62+
return jpaQueryFactory.selectFrom(
63+
QLicenseMultipleChoiceQuestion.licenseMultipleChoiceQuestion);
64+
}
65+
```
66+
- Repository에서 검색 조건을 정의하는 인터페이스를 상속하여 문제의 종류마다 어떤 조건으로 검색될 수 있는지도 쉽게 알 수 있음
67+
```java
68+
@Repository
69+
public class LicenseMultipleChoiceQuestionDslRepository
70+
extends QueryDslJpaQueryMaker<LicenseMultipleChoiceQuestion>
71+
implements SelectWhereCategoriesAndLevels<LicenseMultipleChoiceQuestion>,
72+
SelectWhereContent~~(추가될 수 있는 검색 조건)
73+
```
74+
75+
76+
### 3. 문제의 성격에 따라 인터페이스를 상속하고 행동을 정의
77+
- **객관식 문제**의 공통된 행동 정의
78+
```java
79+
public interface ChoiceBehavior {
80+
List<? extends QuestionChoice> getQuestionChoices();
81+
}
82+
```
83+
```java
84+
public class LicenseMultipleChoiceQuestion extends Question implements ChoiceBehavior
85+
86+
@OneToMany(mappedBy = "question", cascade = CascadeType.ALL, orphanRemoval = true)
87+
private List<LicenseQuestionChoice> questionChoices;
88+
//LicenseQuestionChoice, MajorQuestionChoice를 반환하도록 구현
89+
@Override
90+
public List<LicenseQuestionChoice> getQuestionChoices() {
91+
return questionChoices;
92+
}
93+
```
94+
- **객관식 문제**의 공통된 Response Dto에서의 사용
95+
```java
96+
public static <Q extends Question & ChoiceBehavior>
97+
ResponseMultipleChoiceQuestionDto from(Q question) {
98+
List<ResponseQuestionChoiceDto> questionChoices =
99+
question.getQuestionChoices()
100+
.stream()
101+
...
102+
}
103+
```

0 commit comments

Comments
 (0)