@Getter
public class ScoreListResponseDto {
private long stuNum;
private String maskingName; // 첫글자 빼고 모두 *처리
private double average;
private String grade;
// Entity를 DTO로 변환
public ScoreListResponseDto(Score s) {
this.stuNum = s.getStuNum();
this.maskingName = makeMaskingName(s.getStuName());
this.average = s.getAverage();
this.grade = s.getGrade().toString();
}
private String makeMaskingName(String stuName) {
char firstLetter = stuName.charAt(0);
String maskedName = "" + firstLetter;
for (int i = 0; i < stuName.length() - 1; i++) {
maskedName += "*";
}
return maskedName;
}
}
@Getter @Setter
public class ScoreDetailResponseDto {
// 상세정보 화면을 렌더링하기 위한 데이터
private long stuNum;
private String stuName;
private int kor, eng, math, total;
private double average;
private String grade;
private int rank, totalCount; // 석차와 총 학생수
public ScoreDetailResponseDto(Score s, int rank, int count) {
this.stuNum = s.getStuNum();
this.stuName = s.getStuName();
this.kor = s.getKor();
this.eng = s.getEng();
this.math = s.getMath();
this.total = s.getTotal();
this.average = s.getAverage();
this.grade = s.getGrade().toString();
this.rank = rank;
this.totalCount = count;
}
}
@Getter @Setter @ToString
public class ScoreModifyRequestDto {
private long stuNum;
private int kor, eng, math;
}
// 국영수 점수가 바뀌면? 평균 총점 등급도 바뀌게 되는 것에 주의
@Override
public boolean updateScore(Score s) {
String sql = "UPDATE tbl_score " +
"SET kor = ?, eng = ?, math = ?, " +
"total = ?, average = ?, grade = ? " +
"WHERE stu_num = ?";
return template.update(sql, s.getKor(), s.getEng(), s.getMath(),
s.getTotal(), s.getAverage(), s.getGrade().toString(), s.getStuNum()) == 1;
}
@Service
라는 어노테이션 사용 - @Component + Service라고 알려주는 뜻이 동시에 들어감/*
컨트롤러와 레파지토리사이에 위치하여
중간 처리를 담당
- 트랜잭션 처리, 데이터 가공 처리...
- 의존 관계
Controller -> Service -> Repository
*/
@RequiredArgsConstructor
@Service
public class ScoreService {
private final ScoreRepository repository;
// 목록 조회 중간처리
// - DB에서 조회한 성적정보 목록은 민감한정보를 모두 포함하고 있는데
// 이를 컨트롤러에게 직접 넘기면 보안상 불필요한 정보까지 화면으로
// 넘어갈 수 있기 때문에 숨길건 숨기고 뺄건 빼는 데이터가공을 처리한다.
public List<ScoreListResponseDto> getList(String sort) {
List<Score> scoreList = repository.findAll(sort);
return scoreList.stream()
.map(s -> new ScoreListResponseDto(s))
.collect(Collectors.toList());
}
// 저장 중간처리
public boolean insert(ScorePostDto dto) {
return repository.save(new Score(dto));
}
// 삭제 중간처리
public boolean deleteScore(long stuNum) {
return repository.delete(stuNum);
}
// 개별조회 중간처리 (rank, count 반영)
public ScoreDetailResponseDto retrieve(long stuNum) {
Score score = repository.findOne(stuNum);
int[] result = repository.findRankByStuNum(stuNum);
ScoreDetailResponseDto dto = new ScoreDetailResponseDto(score, result[0], result[1]);
return dto;
}
// 수정 완료를 위해 서비스 클래스에서
// dto를 entity로 변환
public void update(ScoreModifyRequestDto dto) {
repository.updateScore(new Score(dto));
}
}
@Controller
@RequestMapping("/score")
@RequiredArgsConstructor
public class ScoreController {
// 의존객체 설정
private final ScoreService service;
@GetMapping("/list")
public String list(@RequestParam(defaultValue = "num") String sort, Model model) {
List<ScoreListResponseDto> dtos = service.getList(sort);
model.addAttribute("sList", dtos);
return "score/score-list";
}
@PostMapping("/register")
public String register(ScorePostDto dto) {
// service를 거쳐서 데이터베이스에 저장
service.insert(dto);
// 다시 조회로 돌아가야 저장된 데이터를 볼 수 있음
// 포워딩이 아닌 리다이렉트로 재요청을 넣어야 새롭게 디비를 조회
return "redirect:/score/list";
}
@GetMapping("/remove")
public String remove(@RequestParam("sn") long stuNum) {
service.deleteScore(stuNum);
return "redirect:/score/list";
}
@GetMapping("/detail")
public String detail(long stuNum, Model model) {
// 1. 상세조회를 원하는 학번을 읽기
// 2. DB에 상세조회 요청
// 3. DB에서 조회한 회원정보 JSP에게 전달
// 4. rank 조회
ScoreDetailResponseDto dto = service.retrieve(stuNum);
model.addAttribute("s", dto);
return "score/score-detail";
}
// 수정 화면 열기 요청
// detail에 있던 데이터를 들고옴 (조회)
@GetMapping("/modify")
public String modify(long stuNum, Model model) {
ScoreDetailResponseDto dto = service.retrieve(stuNum);
model.addAttribute("s", dto);
return "score/score-modify";
}
// 수정 데이터 반영 요청
@PostMapping("/modify")
public String modify(ScoreModifyRequestDto dto) {
// 1. 수정을 원하는 새로운 데이터 읽기 (국영수 점수 + 학번)
// System.out.println("dto = " + dto);
// 2. 서비스에게 수정 위임
service.update(dto);
return "redirect:/score/detail?stuNum=" + dto.getStuNum();
}
}
ScoreController
-> 수정화면을 열었을 때 detail에서 조회되었던 이름,국,영,수 점수에 대한 정보가 그대로 넘어가야 하므로 retrieve메서드를 가져오고 model로 jsp에 쏴준다.
수정 데이터를 반영 (입력받은 것들을 수정)
score-detail.jsp
-> 누른 사람의 정보가 떠야하므로 학번(stuNum)을 받는다.
score-modify.jsp