작성
·
429
0
이해를 돕기위해 코드 첨삭합니다.
대략적인 코드의 내용은
유저가 시험을 풀고 유저가 푼 문제를 긁어와서 그 문제들의 한 필드(Temporary) 업데이트 즉,
제출한 시험문제 전체를 업데이트하는 그런코드입니다.
Service ------------------------------------------------------------------------------------------
@Transactional
@Override
public ExamMultiSubjectUpdateResponseDto updateExamTemporary(Long courseUserSeq,Long examSeq) {
CourseUser courseUser = courseUserRepository.findById(courseUserSeq)
.orElseThrow(() -> new RestException(HttpStatus.NOT_FOUND, "찾을 수 없는 유저-과정 입니다. courseUserSeq = " + courseUserSeq));
Exam exam = examRepository.findBySeq(examSeq)
.orElseThrow(() -> new RestException(HttpStatus.NOT_FOUND, "일치하는 시험을 찾을 수 없습니다. examSeq=" + examSeq));
//유저가 시험보기를 누른 첫 스타트 시작시간 가져오기
// (객관식 개수가 0 일수도 있고 주관식개수가 0 일수도 있기때문에 2개의 메소드진행)
timeCheckMultiple(courseUserSeq, exam);
timeCheckSubjective(courseUserSeq, exam);
//유저-과정에 등록된 유저가 객관식, 주관식에 모든 임시데이터를 가져온다.
String tYn = "Y";
List<ExamMultipleChoiceResult> multiEntityList = examMultipleChoiceResultRepository.findAllByCourseUserSeqAndTemporaryYn(courseUserSeq,tYn);
List<ExamSubjectiveResult> subjectEntityList = examSubjectiveResultRepository.findAllByCourseUserSeqAndTemporaryYn(courseUserSeq,tYn);
//시험 테이블에 등록된 주관식 객관식 개수
Integer objCnt = exam.getObjCnt();
Integer subCnt = exam.getSubCnt();
log.info("해당과정을 듣는 유저가 입력한 객관식 = {} :: 해당과정을 듣는 유저가 입력한 등록한 주관식 = {}",multiEntityList.size(),subjectEntityList.size());
// 시험 테이블에 등록된 개수들과 유저가 입력한 개수의 조건 비교
if (multiEntityList.size() + subjectEntityList.size() == objCnt+subCnt){
ExamMultiSubjectUpdateResponseDto examMultiSubjectUpdateResponseDto = examRepository.updateTemporary(multiEntityList, subjectEntityList,courseUser);
return examMultiSubjectUpdateResponseDto;
} else if (!(multiEntityList.size() + subjectEntityList.size() > 0)){
throw new RestException(HttpStatus.BAD_REQUEST,"제출해야 할 주관식,객관식 데이터가 없습니다.");
} else {
throw new RestException(HttpStatus.BAD_REQUEST,"모든 객관식, 주관식에 답을 입력해주세요.");
}
}
QueryDsl ----------------------------------------------------------------------------------------
@Override
public ExamMultiSubjectUpdateResponseDto updateTemporary(List<ExamMultipleChoiceResult> multiEntityList, List<ExamSubjectiveResult> subjectEntityList, CourseUser courseUser) { //유저가 체크한 문제를 임시 상태(temporaryYn)에서 제출상태로 변경 Y 면 임시 저장상태 N 이면 제출한상태 long multi = queryFactory .update(qExamMultipleChoiceResult) .set(qExamMultipleChoiceResult.temporaryYn, "N") .where(qExamMultipleChoiceResult.in(multiEntityList)) .execute(); long subject = queryFactory .update(qExamSubjectiveResult) .set(qExamSubjectiveResult.temporaryYn, "N") .where(qExamSubjectiveResult.in(subjectEntityList)) .execute(); em.flush(); em.clear(); if (multi == 0 || subject == 0){ throw new RestException(HttpStatus.BAD_REQUEST,"시험 제출에 실패하였습니다."); } //Ip주소가 프록시나 로드밸런서를 통해 호출되는 경우 로드밸런서의 IP가 나온다 //이 경우를 방지하기 위해 X-Forwarded-For 값을 확인하고 없을 경우 getRemoteAddr()을 사용한다. HttpServletRequest req = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest(); String ip = ClientsUtils.getRemoteIP(req); //유저 시험 채점 테이블 기본값 세팅 (유저가 시험 제출을하면 관리자가 어떤유저가 제출한건지 알기위함.) //유저가 이미 제출했던 시험이 있는지 검증 if (!examUserRepository.existsByCourseUserSeq(courseUser.getSeq())){ examUserRepository.save(new ExamUser(courseUser,0.0,null,"Y","N",null, LocalDateTime.now(),null,ip,null)); } else { throw new RestException(HttpStatus.NOT_FOUND,"이미 제출하셨던 시험이 있습니다."); } //위 em.flush(),em.clear() 로 인해 //ExamMultiSubjectUpdateResponseDto 에 업데이트한 쿼리가 담기지않아 새로 호출 List<ExamMultipleChoiceResult> reFindMulti = examMultipleChoiceResultRepository.findAllByCourseUserSeq(courseUser.getSeq()); List<ExamSubjectiveResult> reFindSubject = examSubjectiveResultRepository.findAllByCourseUserSeq(courseUser.getSeq()); return ExamMultiSubjectUpdateResponseDto.builder() .multiEntityList(reFindMulti) .subjectEntityList(reFindSubject) .build(); }
위 코드에서 제가 궁금한 점은 1. QueryDsl 메소드안에서 위처럼 examUserRepository(DI :: 의존성주입)를 써도되는지..혹은 서비스단에서 처리하는게 맞는지.. 2. 위 코드에서 지양해야 하는점이있는지.. 피드백주시면 감사하겠습니다..
답변 1
0
안녕하세요. 최용호님^^
updateTemporary()는 서비스 계층으로 올리는 것이 더 좋을 것 같아요. 그리고 querydsl을 사용하는 부분들을 리포지토리로 보내구요.
죄송하지만 앞으로는 질문 안내에 있는 것 처럼, 학습 관련된 질문을 올려주시길 부탁드립니다. 저도 마음으로는 도움을 드리고 싶지만, 하루에도 수 많은 분들이 질문을 올려주십니다. 그래서 강의 학습과 관련된 질문에 초점을 맞추는 것이 맞다 생각합니다. 다시한번 이해를 부탁드립니다.
감사합니다.
네 감사합니다.^^