- ์ด์ ๊ธ ํ์ธ -
0. ๋ก์ปฌ ํ๊ฒฝ ๊ตฌ์ฑ ์ฐธ์กฐ
- ์ด์ ๊ธ ํ์ธํ์ฌ DB ๋ฐ spring ์ค์ ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
1. ์ฑ์ ์ ์ฅ ์ ํ๋ฆฌ์ผ์ด์ ์ค๋ช
๊ธฐ์ ์คํ
- Spring Data JPA
- MySQL 8.0
์๊ตฌ์ฌํญ
- ํ์์ ์ฌ๋ฌ๊ฐ์ ์ํ ์ฑ์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค
- ํ์์ ์ํ ์ฑ์ ์ ๋ณด๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค
- ํ๊ท ์ ์๊ฐ 60์ ์ด์์ด๋ผ๋ฉด ํฉ๊ฒฉ์ ๋ฆฌ์คํธ์ ์ ์ฅ๋ฉ๋๋ค
- ํ๊ท ์ ์๊ฐ 60์ ๋ฏธ๋ง์ด๋ผ๋ฉด ๋ถํฉ๊ฒฉ์ ๋ฆฌ์คํธ์ ์ ์ฅ๋ฉ๋๋ค
ERD
API ์คํ
- ์ฑ์ ์ ์ฅ API
- ์ํ๋ง๋ค ํ์์ ์ฑ์ ์ ์ ์ฅํฉ๋๋ค.
PUT /exam/{exam}/score
{
"studentName" : string,
"korScore" : integer,
"englishScore" : integer,
"mathScore" : integer
}
- ์ํ ํฉ๊ฒฉ์ ๋ช
๋จ API
- ์ํ์ ํฉ๊ฒฉ์ ๋ช ๋จ ๋ฆฌ์คํธ๋ฅผ ๋ถ๋ฌ์ต๋๋ค
GET /exam/{exam}/pass
[
{
"studentName" : string,
"avgScore" : double
},
...
]
- ์ํ ๋ถํฉ๊ฒฉ์ ๋ช
๋จ API
- ์ํ์ ๋ถํฉ๊ฒฉ์ ๋ช ๋จ ๋ฆฌ์คํธ๋ฅผ ๋ถ๋ฌ์ต๋๋ค
GET /exam/{exam}/fail
[
{
"studentName" : string,
"avgScore" : double
},
...
]
2. ์ฑ์ ์ ์ฅ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌํ
1) controller
1] ScoreApi
@RequiredArgsConstructor
@RestController
public class ScoreApi {
private final StudentScoreService studentScoreService;
@PutMapping("/exam/{exam}/score")
public void save(
@PathVariable("exam") String exam,
@RequestBody SaveExamScoreRequest request
) {
studentScoreService.saveScore(
request.getStudentName(),
exam,
request.getKorScore(),
request.getEnglishScore(),
request.getMathScore()
);
}
@GetMapping("/exam/{exam}/pass")
public List<ExamPassStudentResponse> pass(@PathVariable("exam") String exam) {
return studentScoreService.getPassStudentsList(exam);
}
@GetMapping("/exam/{exam}/fail")
public List<ExamFailStudentResponse> fail(@PathVariable("exam") String exam) {
return studentScoreService.getFailStudentsList(exam);
}
}
- ์ค์ง์ ์ธ controller ์ ๋๋ค.
2] request.SaveExamScoreRequest
@Getter
@AllArgsConstructor
@NoArgsConstructor(force = true, access = AccessLevel.PROTECTED)
public class SaveExamScoreRequest {
private final String studentName;
private final Integer korScore;
private final Integer englishScore;
private final Integer mathScore;
}
- ์์ฒญ DTO
3] response.ExamFailStudentResponse
@Getter
@AllArgsConstructor
public class ExamFailStudentResponse {
private final String studentName;
private final Double avgScore;
}
- ์๋ต DTO
4] response.ExamPassStudentResponse
@Getter
@AllArgsConstructor
public class ExamPassStudentResponse {
private final String studentName;
private final Double avgScore;
}
- ์๋ต DTO
2) model
- entity(์ํฐํฐ) ์์ ์ ์ํํ๊ฒ ์ต๋๋ค.
1] StudentScore
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "student_score")
@Entity
public class StudentScore {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "student_score_id")
private Long id;
@Column(name = "exam")
private String exam;
@Column(name = "student_name")
private String studentName;
@Column(name = "kor_score")
private Integer korScore;
@Column(name = "english_score")
private Integer englishScore;
@Column(name = "math_score")
private Integer mathScore;
}
- ํ์ ์ฑ์ ์ ์ ์ฅํ๋ ์ํฐํฐ ์ ๋๋ค(ํ ์ด๋ธ)
2] StudentScore
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "student_pass")
@Entity
public class StudentPass {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "student_pass_id")
private Long id;
@Column(name = "exam")
private String exam;
@Column(name = "student_name")
private String studentName;
@Column(name = "avg_score")
private Double avgScore;
}
- ํฉ๊ฒฉ์ ์ฑ์ ์ ์ ์ฅํ๋ ์ํฐํฐ ์ ๋๋ค(ํ ์ด๋ธ)
3] StudentFail
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "student_fail")
@Entity
public class StudentFail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "student_fail_id")
private Long id;
@Column(name = "exam")
private String exam;
@Column(name = "student_name")
private String studentName;
@Column(name = "avg_score")
private Double avgScore;
}
- ๋ถํฉ๊ฒฉ์ ์ฑ์ ์ ์ ์ฅํ๋ ์ํฐํฐ ์ ๋๋ค(ํ ์ด๋ธ)
3) repository
- JPA๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด repository ์ธํฐํ์ด์ค(๊ฐ ์ํฐํฐ๋ณ)๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค.
public interface StudentScoreRepository extends JpaRepository<StudentScore, Long> {
}
public interface StudentPassRepository extends JpaRepository<StudentPass, Long> {
}
public interface StudentFailRepository extends JpaRepository<StudentFail, Long> {
}
4) service
- ๋น์ง๋์ค ๋ก์ง์ด ๋ด๊ฒจ์ ธ ์๋ ์๋น์ค๋ฅผ ๊ตฌํํ๊ฒ ์ต๋๋ค.
1] StudentScoreService
@RequiredArgsConstructor
@Service
public class StudentScoreService {
private final StudentFailRepository studentFailRepository;
private final StudentScoreRepository studentScoreRepository;
private final StudentPassRepository studentPassRepository;
public void saveScore(
String studentName,
String exam,
Integer korScore,
Integer englishScore,
Integer mathScore) {
StudentScore studentScore = StudentScore.builder()
.exam(exam)
.studentName(studentName)
.korScore(korScore)
.englishScore(englishScore)
.mathScore(mathScore)
.build();
studentScoreRepository.save(studentScore);
MyCalculator calculator = new MyCalculator(0.0);
Double avgScore = calculator.add(korScore.doubleValue())
.add(englishScore.doubleValue())
.add(mathScore.doubleValue())
.divide(3.0)
.getResult();
if (avgScore >= 60) {
studentPassRepository.save(StudentPass.builder()
.exam(exam)
.studentName(studentName)
.avgScore(avgScore)
.build());
} else {
studentFailRepository.save(StudentFail.builder()
.exam(exam)
.studentName(studentName)
.avgScore(avgScore)
.build());
}
}
public List<ExamPassStudentResponse> getPassStudentsList(String exam) {
List<StudentPass> studentPasses = studentPassRepository.findAll();
return studentPasses.stream()
.filter(l -> l.getExam().equals(exam))
.map(l -> new ExamPassStudentResponse(l.getStudentName(), l.getAvgScore()))
.toList();
}
public List<ExamFailStudentResponse> getFailStudentsList(String exam) {
List<StudentFail> studentFails = studentFailRepository.findAll();
return studentFails.stream()
.filter(l -> l.getExam().equals(exam))
.map(l -> new ExamFailStudentResponse(l.getStudentName(), l.getAvgScore()))
.toList();
}
}
- ํด๋น ๋ก์ง ๋ฐ์ ์ดํ Api๋ฅผ ์์ฒญํ๋ฉด ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ์ ํ์ธํ ์ ์์ต๋๋ค.
3. ์ฐธ์กฐ
- RequiredArgsConstructor ์ด๋ ธํ ์ด์ ๊ด๋ จ ์ค๋ช
- ์ฐธ์กฐ : ๊ฐ์ธ๋ธ๋ก๊ทธ
4. Github์ผ๋ก ํ์ธ
์ ์ฒด ํ์ผ ํ์ธ(ํ์ฌ ๋ณ๊ฒฝ๋ด์ญ)
[Github]
์ฐธ์กฐ : ์ธํ๋ฐ ๊ฐ์ [์ฅฌ์ฅฌ์ ํจ๊ป ํ๋ฃจ๋ง์ ๋๋ด๋ ์คํ๋ง ํ ์คํธ]
'๐ป FrameWork(ํ๋ ์์ํฌ) > SpringTEST(์คํ๋งํ ์คํธ)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
3-4 [Mocktio] Stubbing ํ ์คํธ(๊ฐ์ง ๋ฐ์ดํฐ ์์ฑ) (0) | 2024.06.06 |
---|---|
3-3 [Mocktio] ํ์ ๊ฒ์ฆ TEST(๋ฉ์๋ ํธ์ถ ์ฌ๋ถ ํ์ธ) (0) | 2024.06.06 |
3-1 [Mocktio] ๊ฐ๋จํ ์ฑ์ ์ ์ฅ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌํ(๋ก์ปฌ ํ๊ฒฝ ๊ตฌ์ฑ) (0) | 2024.06.03 |
2-4 [Junit] ํ ์คํธ ๋ฐ๋ณต ๋ฐ ์ ๋ ฅ๊ฐ ๋ค์ํ๊ฒ ์ค์ (0) | 2024.06.03 |
2-3 [Junit] ํ ์คํธ์ ์ด๋ฆ๋ถ์ด๊ธฐ (0) | 2024.06.03 |