본문 바로가기

SpringBoot

SpringBoot(33) - 학생 성적 관리 예제(학생 성적 입력 / 목록 출력 / 수정 및 삭제)

728x90
반응형

1) SpringBoot

    1-1) 학생 성적 관리 예제

      1-1-1) 학생 성적 입력 / 목록 출력 / 수정 및 삭제

 

 

 

 

 

1) SpringBoot

1-1) 학생 성적 관리 예제

DB에 "student" Table 생성 - 작업환경(DBeaver) 

-- DB 구조
-- 학생 성적 관리(테이블명 : student)

create table student(
--  컬럼명         자료형            제약조건           설명
	stid        varchar(10)    primary key,    	-- 학번(기본키)  
	stname      varchar(30)    not null,       	-- 학생이름
	korean      int            default 0,       -- 국어점수    
	english     int            default 0,       -- 영어점수 
	math        int            default 0        -- 수학점수
);

select * from student;

insert into student(stid, stname, korean, english, math) values('asdf1234', '홍길동', 70, 80, 90);
insert into student(stid, stname, korean, english, math) values('fghj1234', '마동석', 50, 90, 80);
insert into student(stid, stname, korean, english, math) values('hjkp1234', '유재석', 70, 90, 60);
insert into student(stid, stname, korean, english, math) values('qwer1234', '강호동', 40, 60, 80);

delete from student where stname = '이광수';

drop table student;

commit;

 

 

1-1-1) 학생 성적 생성 / 목록 출력 / 수정 및 삭제

(1) [src/main/resources] - [templates] 안에 home.html 파일 생성 후 아래와 같이 작성

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>학생 성적 관리</title>
</head>
<body>
	<h1>[ 학생 성적 관리 ]</h1>
	<p><a href="gradeWrite">성적 입력하기</a></p>
	<p><a href="gradeSelectAll">전체 조회하기</a></p>
</body>
</html>

 

 

(2) [src/main/java] - [net.datasa.test.controller] 안에 HomeController.java 파일 생성 후 아래와 같이 작성

package net.datasa.test.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

	@GetMapping({"", "/"})
	public String home() {
		return "home";
	}
}

 

 

(3) [src/main/java] - [net.datasa.test.controller] 안에 StudentController.java 파일 생성 후 아래와 같이 작성

package net.datasa.test.controller;

import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.datasa.test.domain.dto.StudentDTO;
import net.datasa.test.service.StudentService;

@Controller
@Slf4j
@RequiredArgsConstructor
public class StudentController {
	
	// 명시적인 생성자를 통한 초기화(Service 관련)
	// @Autowired보다 권장되며, 테스트가 용이함. 주입되지 않은 경우에는 컴파일 타임에 오류가 발생함.
	private final StudentService studentService;
	
	/**
	 * 성적 관련 점수 입력폼으로 이동
	 * @return 점수 입력 HTML 파일 경로
	 */
	@GetMapping("gradeWrite")
	public String gradeWrite() {
		return "gradeForm";
	}
	
	/**
	 * 점수 입력폼의 데이터를 받아서 Service로 전달하여 DB에 저장
	 * @param gradeDTO 사용자가 입력한 값(학번, 이름, 과목별 점수)이 저장된 객체
	 * @return 전체 학생 정보 조회 화면(목록 화면 - gradeSelectAll)에 해당하는 HTML 파일 경로
	 */
	@PostMapping("gradeWrite")
	public String gradeWrite(@ModelAttribute StudentDTO studentDTO) {
		log.debug("입력한 학생 정보 : {} ", studentDTO);
		
		studentService.writeSave(studentDTO);
		
		return "redirect:/";
	}
	
	/**
	 * 전체 학생 정보(학번, 이름, 과목별 점수, 총합) 조회
	 * @return 전체 학생 정보 조회 화면(목록 화면 - gradeSelectAll)에 해당하는 HTML 파일 경로
	 */
	@GetMapping("gradeSelectAll")
	public String gradeSelectAll(Model model) {
        List<StudentDTO> studentList = studentService.selectAll();
        model.addAttribute("studentList", studentList);
		return "gradeList";
	}
	
	/**
	 * 학번(stid)을 전달받아 학생 정보 삭제
	 * @param stid 삭제할 학번
	 * @return 전체 학생 정보 목록 보기 페이지로 이동
	 */
    @GetMapping("deleteStudent")
    public String deleteStudent(@RequestParam("stid") String stid) {
        studentService.delete(stid);
        return "redirect:gradeSelectAll";
    }
    
    /**
     * 수정 페이지로 이동
     * @param stid 수정할 학번
     * @param model HTML 파일로 값을 전달해주는 객체
     * @return 학생 정보 수정폼의 HTML 파일 경로
     */
    @GetMapping("gradeUpdate")
    public String gradeUpdate(@RequestParam("stid") String stid, Model model) {
    	StudentDTO studentDTO = studentService.select(stid);
    	model.addAttribute("student", studentDTO);
    	return "updateForm";
    }
        
    /**
     * 사용자가 폼에 입력(수정)한 학생 정보를 DB에 저장
     * @param studentDTO 사용자가 수정한 학생 정보를 저장한 객체
     * @return 전체 학생 정보 목록 보기 페이지로 이동
     */
    @PostMapping("gradeUpdate")
    public String gradeUpdate(@ModelAttribute StudentDTO studentDTO) {
    	log.debug("수정한 학생 정보 : {}", studentDTO);
    	studentService.update(studentDTO);
    	
    	return "redirect:gradeSelectAll";
    }
	
}

 

 

(4) [src/main/java] - [net.datasa.test.service] 안에 StudentService.java 파일 생성 후 아래와 같이 작성

package net.datasa.test.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import jakarta.persistence.EntityNotFoundException;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import net.datasa.test.domain.dto.StudentDTO;
import net.datasa.test.domain.entity.StudentEntity;
import net.datasa.test.repository.StudentRepository;

/**
 * 학생 정보를 관리하는 서비스 클래스
 */
@Service
@RequiredArgsConstructor
@Transactional
public class StudentService {
	private final StudentRepository studentRepository;

	/**
	 * 학생 정보를 전달 받아서 DB에 저장함
	 * @param studentDTO entity에 담아 DB에 저장할 학생 정보를 담은 객체
	 */
	public void writeSave(StudentDTO studentDTO) {
		StudentEntity entity = new StudentEntity();
		entity.setStid(studentDTO.getStid());
		entity.setStname(studentDTO.getStname());
		entity.setKorean(studentDTO.getKorean());
		entity.setEnglish(studentDTO.getEnglish());
		entity.setMath(studentDTO.getMath());
		
		studentRepository.save(entity);
		
	}

	/**
	 * 모든 학생 정보 조회
	 * @return 모든 학생 정보를 담은 객체의 리스트
	 */
	public List<StudentDTO> selectAll() {
		List<StudentEntity> entityList = studentRepository.findAll();
		List<StudentDTO> dtoList = new ArrayList<>();
		
		for (StudentEntity entity : entityList) {
			StudentDTO dto = new StudentDTO();
			dto.setStid(entity.getStid());
			dto.setStname(entity.getStname());
			dto.setKorean(entity.getKorean());
			dto.setEnglish(entity.getEnglish());
			dto.setMath(entity.getMath());
			dtoList.add(dto);
		}
		return dtoList;
	}

	/**
	 * 학생 정보 삭제
	 * @param stid 삭제할 학생의 학번
	 */
	public void delete(String stid) {
		StudentEntity studentEntity = studentRepository.findById(stid)
				.orElseThrow(() -> new EntityNotFoundException("학생 정보가 없습니다."));
		
		studentRepository.delete(studentEntity);
		
	}

	/**
	 * 학생 정보 조회
	 * @param stid 조회할 학생의 학번
	 * @return DB로부터의 조회 결과를 담은 객체
	 */
	public StudentDTO select(String stid) {
		StudentEntity entity = studentRepository.findById(stid)
				.orElseThrow(() -> new EntityNotFoundException("학생 정보가 없습니다."));
		
		StudentDTO dto = new StudentDTO();
		dto.setStid(entity.getStid());
		dto.setStname(entity.getStname());
		dto.setKorean(entity.getKorean());
		dto.setEnglish(entity.getEnglish());
		dto.setMath(entity.getMath());
		
		return dto;
	}

	/**
	 * 학생 정보를 학번을 기준으로 수정
	 * @param studentDTO 수정할 학생 정보
	 */
	public void update(StudentDTO studentDTO) {
		//DB의 정보를 조회
		StudentEntity entity = studentRepository.findById(studentDTO.getStid())
				.orElseThrow(() -> new EntityNotFoundException("학생 정보가 없습니다."));
		
		// StudentDTO의 수정할 정보를 entity에 세팅
		entity.setKorean(studentDTO.getKorean());
		entity.setEnglish(studentDTO.getEnglish());
		entity.setMath(studentDTO.getMath());
		
		// entity 저장
		studentRepository.save(entity);
		
	}
   
}

 

 

(5) [src/main/java] - [net.datasa.test.domain.dto] 안에 StudentDTO.java 파일 생성 후 아래와 같이 작성

package net.datasa.test.domain.dto;

import lombok.Data;

/**
 * 학생 정보 DTO
 */
@Data
public class StudentDTO {
    private String stid;           // 학번
    private String stname;         // 학생이름
    private Integer korean;        // 국어점수
    private Integer english;       // 영어점수
    private Integer math;          // 수학점수
}

 

 

(6) [src/main/java] - [net.datasa.test.repository] 안에 StudentRepository.java 파일 생성 후 아래와 같이 작성

package net.datasa.test.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import net.datasa.test.domain.entity.StudentEntity;

/**
 * 학생 정보 관련 Repository
 */
@Repository
public interface StudentRepository extends JpaRepository<StudentEntity, String> {

}

 

 

(7) [src/main/java] - [net.datasa.test.domain.entity] 안에 StudentEntity.java 파일 생성 후 아래와 같이 작성

package net.datasa.test.domain.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;

/**
 * 학생 정보 엔티티
 */
@Data
@Entity
@Table(name = "student")
public class StudentEntity {
	@Id
    @Column(name = "stid", nullable = false, length = 10)
    private String stid;

    @Column(name = "stname", nullable = false, length = 30)
    private String stname;

    @Column(name = "korean", columnDefinition = "int default 0")
    private Integer korean = 0;
    
    @Column(name = "english", columnDefinition = "int default 0")
    private Integer english = 0;
    
    @Column(name = "math", columnDefinition = "int default 0")
    private Integer math = 0;
}

 

 

(8) [src/main/resources] - [templates] 안에 gradeForm.html 파일 생성 후 아래와 같이 작성

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>성적 입력</title>
</head>
<body>
	<h1>[ 성적 입력 ]</h1>
	
	<form action="gradeWrite" method="post">
		<table>
			<tr>
				<th>학번</th>
				<td><input type="text" name="stid" required="required"></td>
			</tr>
			<tr>
				<th>이름</th>
				<td><input type="text" name="stname" required="required"></td>
			</tr>
			<tr>
				<th>국어점수</th>
				<td><input type="number" name="korean" value=0></td>
			</tr>
			<tr>
				<th>영어점수</th>
				<td><input type="number" name="english" value=0></td>
			</tr>
			<tr>
				<th>수학점수</th>
				<td><input type="number" name="math" value=0></td>
			</tr>
			<tr>
				<td><input type="submit" value="저장"></td>
			</tr>
		</table>
	</form>
</body>
</html>

 

 

(9) [src/main/resources] - [templates] 안에 gradeList.html 파일 생성 후 아래와 같이 작성

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>전체 학생 조회</title>
</head>
<body>
	<h1>[ 전체 학생 조회 ]</h1>
	
	<table>
        <tr>
            <th>번호</th>
            <th>학번</th>
            <th>이름</th>
            <th>국어</th>
            <th>영어</th>
            <th>수학</th>
            <th>총점</th>
            <th></th>
            <th></th>
        </tr>
        <tr th:if="${studentList == null or studentList.isEmpty()}">
            <td colspan="9">조회 결과가 없습니다.</td>
        </tr>
        <tr th:if="${studentList}" th:each="student, status : ${studentList}">
            <td th:text="${status.count}"></td>
            <td th:text="${student.stid}"></td>
            <td th:text="${student.stname}"></td>
            <td th:text="${student.korean}"></td>
            <td th:text="${student.english}"></td>
            <td th:text="${student.math}"></td>
            <!-- 국어, 영어, 수학점수의 총점 -->
            <td th:text="${student.korean + student.english + student.math}"></td>
        	<td><a th:href="|deleteStudent?stid=${student.stid}|">삭제</a></td>
        	<td><a th:href="|gradeUpdate?stid=${student.stid}|">수정</a></td>
        </tr>   
    </table>
</body>
</html>

 

 

(10) [src/main/resources] - [templates] 안에 updateForm.html 파일 생성 후 아래와 같이 작성

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>학생 점수 수정</title>
</head>
<body>
	<h1>[ 학생 점수 수정 ]</h1>
	
	<form action="gradeUpdate" method="post">
		<table>
			<tr>
				<th>학번</th>
				<td><input type="text" name="stid" th:value="${student.stid}" readonly></td>
			</tr>
			<tr>
				<th>이름</th>
				<td><input type="text" name="stname" th:value="${student.stname}" readonly></td>
			</tr>
			<tr>
				<th>국어점수</th>
				<td><input type="number" name="korean" th:value="${student.korean}"></td>
			</tr>
			<tr>
				<th>영어점수</th>
				<td><input type="number" name="english" th:value="${student.english}"></td>
			</tr>
			<tr>
				<th>수학점수</th>
				<td><input type="number" name="math" th:value="${student.math}"></td>
			</tr>
			<tr>
				<td><input type="submit" value="저장"></td>
			</tr>
		</table>
	</form>
</body>
</html>

 

 

 

(11) 결과 화면

첫 접속 화면

 

 

"성적 입력하기" 문구 클릭 시 학생 점수 입력폼 화면 : 목록 및 DB에 저장됨

 

 

"전체 조회하기" 문구 클릭 시 전체 학생 점수 목록 화면

 

 

"전체 학생 성적 목록" 화면에서 "삭제" 버튼 클릭 시 화면 : "정우성" 학생 삭제 예시

 

 

 

"전체 학생 성적 목록" 화면에서 "수정" 버튼 클릭 시 화면 :  학생 성적 수정폼으로 이동함