[Spring] 체크박스 데이터 여러개 받기

류재성's avatar
Mar 11, 2024
[Spring] 체크박스 데이터 여러개 받기
 

1. View

 
notion image
 
uploadForm.mustache
<h4 class="card-title">보유 스킬</h4> <table class="table"> <tr> <td> <div class=form-control style="display: flex; justify-content: space-evenly"> <input type="checkbox" name="skill" value="java"> <span>java</span> <input type="checkbox" name="skill" value="javaScript"> <span>javaScript</span> <input type="checkbox" name="skill" value="Spring"> <span>Spring</span> <input type="checkbox" name="skill" value="HTML"> <span>HTML</span> <input type="checkbox" name="skill" value="jQuery"> <span>jQuery</span> <input type="checkbox" name="skill" value="MySQL"> <span>MySQL</span> <input type="checkbox" name="skill" value="없음"> <span>없음</span> </div> </td> </tr>
 
 

2. 스킬 테이블

Skill
@Entity @Data @Table(name = "skill_tb") public class Skill { // Tech Stack @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private Integer userId; // null 허용 -> 5 private Integer employerId; // 1 -> null 채용공고로 옮김. private String skillName; private Integer boardId ; // 채용공고 id private Integer resumeId; }
 

3. DTO

 
import java.util.List; public class ResumeRequest { @Data public class UploadDTO { // title, cv, schoolName, major, educationLevel, career private String title; private String content; private String schoolName; private String major; private String educationLevel; private String career; private List<String> skill; }
 
💡
체크박스에서 name="skill" 으로 받은 데이터를 List 타입으로 받음.
 

4. 컨트롤러

 
SkillController
@PostMapping("/resume/upload") public String upload(ResumeRequest.UploadDTO requestDTO) { User sessionUser = (User) session.getAttribute("sessionUser"); Integer resumeId = resumeRepository.upload(requestDTO, sessionUser.getId()); List<String> skills = requestDTO.getSkill(); for (String skill : skills) { skillRepository.uploadByUserId(skill, sessionUser.getId(), resumeId); } return "redirect:/user/" + sessionUser.getId(); }
 
💡
이력서를 작성하면서 기술 테이블에 데이터를 INSERT. skill 은 List 타입이기 때문에 반복문으로 하나씩 데이터를 추가한다.
 

5. 레파지토리

 
ResumeRepository
@Transactional public Integer upload(ResumeRequest.UploadDTO requestDTO, Integer userId) { String q = """ INSERT INTO resume_tb (user_id, title, content, school_name, major, education_level, career, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, now()) """; Query query = entityManager.createNativeQuery(q); query.setParameter(1, userId); query.setParameter(2, requestDTO.getTitle()); query.setParameter(3, requestDTO.getContent()); query.setParameter(4, requestDTO.getSchoolName()); query.setParameter(5, requestDTO.getMajor()); query.setParameter(6, requestDTO.getEducationLevel()); query.setParameter(7, requestDTO.getCareer()); query.executeUpdate(); String q1 = """ select max(id) from resume_tb; """; Query query1 = entityManager.createNativeQuery(q1); Integer resumeId = (Integer) query1.getSingleResult(); return resumeId ; }
💡
이력서 INSERT. Resume_tb 의 ID 조회를 위해 INSERT 후 MAX(ID) 를 조회한다.
 
SkillRepository
@Transactional public void uploadByUserId(String skill, int userId,int resumeId) { String q = """ INSERT INTO skill_tb(user_id, skill_name,resume_id) VALUES (?, ?,?) """; Query query = entityManager.createNativeQuery(q); query.setParameter(1,userId); query.setParameter(2,skill); query.setParameter(3,resumeId); query.executeUpdate(); }
 
notion image
 
 

6. 데이터 출력

 
ResumeController
@GetMapping("/resume/{resumeId}") // public String detail(@PathVariable int resumeId, HttpServletRequest request, Model model) { // ksj-030810 - model User sessionUser = (User) session.getAttribute("sessionUser"); ResumeResponse.ResumeDetailDTO resumeDetailDTO = resumeRepository.detail(resumeId); // todo : resumeId가 없는 경우 처리 resumeDetailDTO.isResumeOwner(sessionUser); request.setAttribute("resumeDetail", resumeDetailDTO); List<Skill> resumeSkillList = skillRepository.findByResumeId(resumeId); request.setAttribute("skillList", resumeSkillList); Double rawRating = ratingRepository.findBySubjectId(resumeDetailDTO.getUserId()); // ksj-030810 if (rawRating != null) { // 소수점 한자리수까지 출력 String rating = String.format("%.1f", rawRating); // model.addAttribute("resumeList", resumeDetailDTO.getId()); // ksj-03081 model.addAttribute("rating", rating); // ksj-030810 } if (sessionUser != null){ Boolean hasRated = ratingRepository.hasRated(sessionUser.getId(), resumeDetailDTO.getUserId()); request.setAttribute("hasRated", hasRated); Subscribe subscribe = subscribeRepository.findAllByUserIdResumeId(sessionUser.getId(), resumeId); request.setAttribute("subscribe", subscribe); } return "/resume/detail"; }
 
💡
List<Skill> resumeSkillList = skillRepository.findByResumeId(resumeId); request.setAttribute("skillList", resumeSkillList); 컨트롤러에서 이력서 ID를 이용해 데이터를 전달한다.
 
SkillRepositoty
public List<Skill> findByResumeId(int resumeId) { String q = """ select * from skill_tb where resume_id = ? """; Query query = entityManager.createNativeQuery(q,Skill.class); query.setParameter(1,resumeId); try { List<Skill> skillList = query.getResultList(); return skillList; } catch (Exception e) { return null; } }
 
resume/detail.mustache
<h4 class="card-title">보유 스킬</h4> <div class="form-control mb-3"> {{#skillList}} <btn class="btn btn-light">{{skillName}}</btn> {{/skillList}} {{^skillList}} <btn class="btn btn-outline-light form-control">없음</btn> {{/skillList}} </div>
 
 
notion image
Share article

{CODE-RYU};