참고자료 : 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
sqn(시퀀스) 칼럼을 추가해서 WHERE조건문의 조건을 처리할 수 있도록 한다.
--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;
<?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>
<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>
selectOne(query_id, '조건')
: id에 대한 select문을 실행하면서 조건(쿼리문에서 사용할 인자)를 전달delete(query_id, Object obj)
: obj 객체의 값을 조건문의 조건 값으로 사용해 id에 대한 delete문 실행 @Override
public StuDTO one(int sqn) {
return sqlSession.selectOne("stu.one", sqn);
}
@Override
public void deleteMethod(int sqn) {
sqlSession.delete("stu.del", sqn);
}
addObject()
: "dto"에 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";
<%@ 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의 값을 변경할 수 있음
변수 rank, sum, avg 추가 / getter,setter
<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>
@Override
public List<StuDTO> all() {
return sqlSession.selectList("stu.all");
}
// 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;
}
총점과 평균을 출력하는 페이지 생성
<%@ 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>
<p><a id="admin" class="btn btn-primary" href="toadmin.do">admin ></a></p>
<p><a id="main" class="btn btn-primary" href="tomain.do">< Main</a></p>
/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 페이지 나누기) 을 추가하면서 코드를 아주 약간 변형하는 과정에서 오류가 많이 나서 생각보다 시간이 많이 걸렸다.
오류난 부분을 해결하면서 코드들이 어떻게 연결되어있는지 파악할 수 있어서 재밌었다. 아래 내용을 더 추가해보고 싶다.