(5-3) [Spring&mybatis] 학생관리 프로그램 만들기 (main화면, 시퀀스 연결하기)

씩씩한 조약돌·2023년 1월 29일
0

미니프로젝트🤹

목록 보기
15/21
post-thumbnail

학생관리 프로그램

참고자료 : spring 프로젝트 생성 / mybatis연결 / spring+mybatis연결 / Bootstrap

구현내용

  • 기존의 데이터 조회, 추가, 수정, 삭제를 포함
  • 조회 페이지를 2개로 나누기
    -> main.jsp : 성적의 총점, 평균을 구하고 순위를 보여줌
    -> admin.jsp : 데이터 추가, 수정, 삭제를 처리
  • 각 페이지에는 이동할 수 있는 버튼 추가 (메인->관리자 / 관리자->메인)
  • 부트스트랩 이용해서 스타일 적용하기
  • (NEW) 시퀀스번호와 학생번호를 나눠서 WHERE문에서는 시퀀스번호를 이용하기

개발환경

언어 : JAVA (JDK 11)
서버 : Apache Tomcat 9.0
프레임워크 : Spring Framework 3.9.18, MyBatis 3.5.8, Bootstrap 5.2.3
DB : OracleXE 11gR2
IDE : Eclipse 2020-12, SQL Developler


1. 학생번호도 수정할 수 있도록 처리

sqn(시퀀스) 칼럼을 추가해서 WHERE조건문의 조건을 처리할 수 있도록 한다.

1. DB 테이블 수정

  • num칼럼에 등록된 Primary Key삭제
  • 시퀀스 칼럼(sqn) 추가해서 테이블 다시 생성하기
--DROP TABLE studentlist;

CREATE TABLE studentlist (
 sqn number,
 num number,
 name varchar2(100),
 kor number(3),
 eng number(3),
 math number(3)
);

--ALTER TABLE studentlist DROP PRIMARY KEY DROP INDEX;

--DROP SEQUENCE stul_sqn_seq;

CREATE SEQUENCE stul_sqn_seq
START WITH 1
INCREMENT BY 1
NOCACHE
NOCYCLE;

INSERT INTO studentlist(sqn, num, name, kor, eng, math)
VALUES(stul_sqn_seq.nextval, 1, '홍길동', 80, 75, 80);

INSERT INTO studentlist(sqn, num, name, kor, eng, math)
VALUES(stul_sqn_seq.nextval, 2, '고수', 90, 90, 97);

--DELETE FROM studentlist
--WHERE num =5;

SELECT * FROM studentlist
ORDER BY num;


commit;

2. StuDTO 수정

  • sqn변수 추가, getter/setter

3. StuMapper.xml 수정

  • sqn칼럼추가
  • WHERE 조건문을 sqn으로 변경
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
<mapper namespace = "stu">
	<select id="list" resultType="model.StuDTO">
		SELECT * FROM studentlist
		ORDER BY num
	</select>
	
	<insert id="ins" parameterType="model.StuDTO">
		INSERT INTO studentlist(sqn, num, name, kor, eng, math)
		VALUES(stul_sqn_seq.nextval, #{num}, #{name, jdbcType=VARCHAR}, #{kor}, #{eng}, #{math})
	</insert>
	
	<select id="one" parameterType="int" resultType="model.StuDTO">
		SELECT * FROM studentlist
		WHERE sqn=#{sqn}
	</select>

	<update id="upd" parameterType="model.StuDTO">
		UPDATE studentlist SET num=#{num}, name=#{name}, kor=#{kor}, eng=#{eng}, math=#{math}
		WHERE sqn=#{sqn}
	</update>

	<delete id="del" parameterType="int">
		DELETE FROM studentlist
		WHERE sqn=#{sqn}
	</delete>
</mapper>

4. admin.jsp 수정

  • 수정/삭제 시 sqn값이 넘어올 수 있도록 변경
<td><a class="list-group-item list-group-item-primary" href="update.do?sqn=${stu.sqn}">수정</a></td>
				<td><a class="list-group-item list-group-item-warning" href="delete.do?sqn=${stu.sqn}">삭제</a></td> 

5. StuDaoImp클래스 수정

  • selectOne(query_id, '조건') : id에 대한 select문을 실행하면서 조건(쿼리문에서 사용할 인자)를 전달
    -> controller에서 받아온 sqn을 mapper의 ${sqn}으로 넘겨줌
  • delete(query_id, Object obj) : obj 객체의 값을 조건문의 조건 값으로 사용해 id에 대한 delete문 실행
    -> controller에서 받아온 sqn을 mapper의 ${sqn}으로 넘겨줌
	@Override
	public StuDTO one(int sqn) {
		return sqlSession.selectOne("stu.one", sqn);
	}

	@Override
	public void deleteMethod(int sqn) {
		sqlSession.delete("stu.del", sqn);
	}

6. stuController클래스 수정

  • addObject() : "dto"에 stuDao.one(sqn)리턴값 넣어주기
    -> stuDao.one(sqn)리턴값 = 쿼리문 실행한 데이터를 받아옴
	@RequestMapping(value="/update.do", method=RequestMethod.GET)
	public ModelAndView update(int sqn, ModelAndView mav) {
		mav.addObject("dto", stuDao.one(sqn));
		mav.setViewName("stu/update");		
		return mav;
	}
	
	@RequestMapping(value="/delete.do")
	public String delete(int sqn) {
		stuDao.deleteMethod(sqn);
		return "redirect:/admin.do";

4-2. update.jsp

  • 학생번호도 수정할 수 있도록 처리
  • 받아오는 값을 sqn으로 변경
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Update</title>
<style>
form {margin:10px; width:300px;}
#btn {float:right}
</style>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
</head>
<body>
	<form name = "frm" action="update.do" method="post">
		<div class="input-group mb-3">
 			<span class="input-group-text" id="inputGroup-sizing-default">번호</span>
  			<input type="text" name="num" value="${dto.num}" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default">
		</div>	
		<div class="input-group mb-3">
 			<span class="input-group-text" id="inputGroup-sizing-default">이름</span>
  			<input type="text" name="name" value="${dto.name}" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default">
		</div>
		<div class="input-group mb-3">
 			<span class="input-group-text" id="inputGroup-sizing-default">국어</span>
  			<input type="text" name="kor" value="${dto.kor}" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default">
		</div>
		<div class="input-group mb-3">
 			<span class="input-group-text" id="inputGroup-sizing-default">영어</span>
  			<input type="text" name="eng" value="${dto.eng}" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default">
		</div>				
		<div class="input-group mb-3">
 			<span class="input-group-text" id="inputGroup-sizing-default">수학</span>
  			<input type="text" name="math" value="${dto.math}" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default">
		</div>	
		<input type="hidden" name = "sqn" value="${dto.sqn}"/>
		<p><input type="submit" value="수정" class="btn btn-outline-primary" id="btn"/></p>
	</form>
</body>
</html>

▼ WHERE조건문이 sqn값으로 받아오기 때문에, num의 값을 변경할 수 있음


2. main화면 구현

1. StuDTO 수정

변수 rank, sum, avg 추가 / getter,setter

2. SELECT 쿼리문 추가 : StuMapper.xml 수정

	<select id="all" resultType="model.StuDTO">
		SELECT rank() over(ORDER BY kor+eng+math DESC) AS rank, num, name, kor, eng, math, (kor+eng+math) AS sum, round((kor+eng+math)/3,2) AS avg
		FROM studentlist
		ORDER BY rank
	</select>

3. SqlSession-쿼리문 연결 : StuDao인터페이스 / StuDaoImp클래스

	@Override
	public List<StuDTO> all() {
		return sqlSession.selectList("stu.all");
	}

4. 쿼리문 실행 및 main.jsp로 화면 넘겨주기 : StuController클래스

// http://localhost:8090/myapp/main.do

	@RequestMapping(value="/main.do")
	public ModelAndView all(ModelAndView mav) {
		mav.addObject("all", stuDao.all());
		mav.setViewName("stu/main");
		return mav;
	}

5. main.jsp 생성

총점과 평균을 출력하는 페이지 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Main</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<style>
#ins {display: inline-block; width : 100px; text-align:center; margin-bottom:10px; margin-right:10px; float :right;}
table {clear : both;}
tr, td {text-align:center;}
#admin {margin-left:10px;}
</style>
</head>
<body>
	<table class="table">
		<tr class="table-light">
			<th>순위</th> <th>번호</th> <th>이름</th> <th>국어</th> <th>영어</th> <th>수학</th>
			<th>총점</th> <th>평균</th> 
		</tr>
		<c:forEach items="${all}" var="main">
			<tr>
				<td>${main.rank}</td> <td>${main.num}</td> <td>${main.name}</td>
				<td>${main.kor}</td> <td>${main.eng}</td> <td>${main.math}</td> 
				<td>${main.sum}</td> <td>${main.avg}</td>
			</tr>
		</c:forEach>
	</table>
	<p><a id="admin" class="btn btn-primary" href="">admin ></a></p>
</body>
</html>


3. main - admin 연결

1. main.jsp

	<p><a id="admin" class="btn btn-primary" href="toadmin.do">admin ></a></p>

2. admin.jsp

	<p><a id="main" class="btn btn-primary" href="tomain.do">< Main</a></p>

3. GET방식으로 처리 : StuController클래스

  • /toadmin.do가 호출되면 /admin.do로 redirect
  • /tomain.do가 호출되면 /main.do로 redirect
	@RequestMapping(value="/toadmin.do", method=RequestMethod.GET)
	public String toAdmin() {
		return "redirect:/admin.do";
	}
	
	@RequestMapping(value="/tomain.do", method=RequestMethod.GET)
	public String toMain() {
		return "redirect:/main.do";
	}


🏋️후기

전체데이터조회/추가/수정/삭제는 수업시간에 한 내용을 그대로 따라쳐서 작성한 코드여서 틀린 부분을 찾기가 쉬웠는데, 새로운 기능(시퀀스와 번호를 나누기 / main과 admin 페이지 나누기) 을 추가하면서 코드를 아주 약간 변형하는 과정에서 오류가 많이 나서 생각보다 시간이 많이 걸렸다.

  • 쿼리문 문법 및 개념이 헷갈려서 쿼리문 작성하는데도 시간이 오래 걸렸다. 쿼리문도 복습을 계속 해야겠다. (시퀀스 추가/삭제, primary key, rank 등)
  • 오류내용 1 : mapper에서 sqn칼럼을 추가하고 WHERE조건문에도 sqn로 변경했는데 자꾸 num의 값을 받아옴 / 해결시도 : jsp에서 하이퍼링크(href="update.do?sqn=${stu.sqn}")를 수정하고, dao와 controller에서도 sqn을 받아오도록 처리한 후 해결됨!
  • 오류내용 2 : 총점, 평균, 등수를 출력하는데 쿼리문도 잘 작동하고, 페이지도 잘 뜨는데 데이터를 출력하지못함 / 해결시도 : controller와 dao를 새로 만들고 환경설정도 다시 하는 등 여러가지 시도해보느라 1시간동안 해맸는데, 알고보니 jsp에서 core를 추가를 안했었다.. . .

오류난 부분을 해결하면서 코드들이 어떻게 연결되어있는지 파악할 수 있어서 재밌었다. 아래 내용을 더 추가해보고 싶다.


🤹추가하기

  • 평균 : 소수점 둘째자리까지 출력
  • 조건별로 쿼리문 작성해서 버튼을 눌러 해당 데이터 출력할 수 있도록 처리
    (평균 내림차순/오름차순 ..
    (이름 내림차순/오름차순
    (국어성적 내림차순/오름차순
    (영어성적 내림차순/오름차순
    (수학성적 내림차순/오름차순
  • insert, update에서 input요소 작성시 null값이나 공백일 경우 js알림창 뜨도록 처리
  • Tiles로 view구현
  • 수정할때 페이지이동이 아닌 표 자체에서 바로 input화면으로 변경 (해당 학생 데이터 값만 input요소로 바뀌도록-> if문? Choose문?
    또는 전체 다 input으로 바꿔서 여러 행의 데이터를 수정할 수 있도록->쿼리문이 나올지?)
profile
씩씩하게 공부중 (22.11~)

0개의 댓글