package com.spring.webmvc.springmvc.chap02.repository;
import com.spring.webmvc.springmvc.chap02.domain.Score;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface ScoreMapper {
// 점수 저장
boolean save(Score score);
// 전체 점수 정보 조회
List<Score> findAll(String sort);
// 개별 점수 조회
Score findOne(int stuNum);
// 점수 정보 삭제
boolean remove(int stuNum);
// 평균 1등 정보 구하기
List<Score> findFirst();
// 평균 꼴등 정보 구하기
List<Score> findlast();
}
package com.spring.webmvc.springmvc.chap02.repository;
import com.spring.webmvc.springmvc.chap02.domain.Score;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ScoreRowMapper implements RowMapper<Score> {
@Override
public Score mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Score(rs);
// Score s = new Score(rs);
// s.setStuNum(rs.getInt("stu_num"));
// s.setName(rs.getString("stu_name"));
// 입력할게 많으니 간편하게 처리해보자
// 생성자에 rs를 넘긴다.
// 컬럼을 읽어서 스코어 필드 어디에 맵핑할 것인지를 알려줘야 함.
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--mapper 태그는 sql을 매핑할때 사용하는 태그
nmaespace 속성에는 사용할 인터페이스의 풀 패키지경로 + 인터페이스이름
-->
<mapper namespace="com.spring.webmvc.springmvc.chap02.repository.ScoreMapper">
<!-- 점수 저장 -->
<insert id="save">
INSERT INTO tbl_score
VALUES (seq_tbl_score.nextval, #{name}, #{kor}, #{eng}, #{math}, #{total}, #{average}, #{grade})
</insert>
<!-- 점수 정보 삭제 -->
<delete id="remove">
DELETE FROM tbl_score
WHERE stu_num = #{stuNum}
</delete>
<resultMap id="scoreMap" type="com.spring.webmvc.springmvc.chap02.domain.Score">
<result property="stuNum" column="stu_num"></result>
<result property="name" column="stu_name"></result>
</resultMap>
<!-- 동적 SQL 작성법 -->
<!-- // 전체 점수 정보 조회 -->
<select id="findAll" resultMap="scoreMap">
SELECT * FROM tbl_score
<if test="sort == 'num'">
ORDER BY stu_num
</if>
<if test="sort == 'name'">
ORDER BY stu_name
</if>
<if test="sort == 'average'">
ORDER BY average DESC
</if>
</select>
<!-- 개별 점수 정보 조회 -->
<select id="findOne" resultMap="scoreMap">
SELECT * FROM tbl_score
WHERE stu_num = #{stuNum}
</select>
</mapper>
package com.spring.webmvc.springmvc.chap02.api;
import com.spring.webmvc.springmvc.chap02.domain.Score;
import com.spring.webmvc.springmvc.chap02.repository.ScoreMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequiredArgsConstructor
@Log4j2
@CrossOrigin
@RequestMapping("/api/score")
public class ScoreApiController {
private final ScoreMapper mapper;
// 점수 등록 및 조회 화면 열기 요청
@GetMapping("")
public List<Score> list(){
String sort = "name";
List<Score> all = mapper.findAll(sort);
log.info("/api/score/ GET!");
return all;
}
// 점수 신규등록 요청
@PostMapping("")
public String register(@RequestBody Score score) {
score.calcTotalAndAvg();
score.calcGrade();
log.info("/api/score POST! score: {} -" , score);
boolean flag = mapper.save(score);
return flag?"insert-success":"insert-fail";
}
/* @RequestMapping("score/detail")
public ModelAndView detail(int sutNum) {
log.info("score/detail GET - param1: {}", sutNum);
Score score = repository.findOne(sutNum);
ModelAndView mv = new ModelAndView("chap02/score-detail");
mv.addObject("s",score);
return mv;
}*/
@GetMapping("/{stuNum}")
public Score detail(@PathVariable int stuNum) {
log.info("/api/score GET 요청!! - ");
Score one = mapper.findOne(stuNum);
return one;
}
@DeleteMapping("/{stuNum}")
public String delete(@PathVariable int stuNum) {
log.info("/api/score GET 요청!! - stuNum{} ",stuNum);
boolean flag = mapper.remove(stuNum);
return flag ? "delete-success" :"delete-fail";
}
}
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
label {
display: block;
}
.del-btn {
width: 10px;
height: 10px;
background: red;
color: white;
border-radius: 5px;
margin-left: 5px;
text-decoration: none;
font-size: 0.7em;
padding: 6px;
}
.del-btn:hover {
background: orangered;
}
li {
margin-bottom: 10px;
}
.score-list>li:first-child {
font-size: 1.2em;
color: blue;
font-weight: 700;
border-bottom: 1px solid skyblue;
margin-bottom: 10px;
}
label span[class$='span'] {
color: red;
}
</style>
</head>
<body>
<h1>시험 점수 등록</h1>
<label>
# 이름: <input type="text" name="name">
</label>
<label>
# 국어: <input type="text" name="kor"> <span class="kor-span"></span>
</label>
<label>
# 영어: <input type="text" name="eng"> <span class="eng-span"></span>
</label>
<label>
# 수학: <input type="text" name="math"> <span class="math-span"></span>
</label>
<div>
<button id="reg-btn">확인</button>
</div>
<hr>
<ul class="score-list">
<li class="stuNum">총 학생 수 : <span class="stu-count">1</span>명</li>
</ul>
<script>
const URL = 'http://localhost:8282/api/score';
//함수 선언부
//점수 삭제 요청
function deleteScoreData($target) {
const xhr = new XMLHttpRequest();
const stuNum = $target.dataset.stuNum;
console.log('학번: ' + stuNum);
xhr.open('DELETE', URL + '/' + stuNum);
xhr.send();
xhr.onload = e => {
if (xhr.status === 200) {
removeAll();
getList();
} else {
alert('삭제 실패!');
}
};
}
//점수리스트 렌더링
function makeScoreListDOM(resp) {
const scoreList = JSON.parse(resp);
//총 학생수 숫자처리
document.querySelector('.stu-count').textContent = scoreList.length;
const $ul = document.querySelector('.score-list');
for (let s of scoreList) {
//객체 디스트럭쳐링
const {stuNum, name, kor, eng, math, total, average} = s;
//li태그 생성
let tag = `
<li>
# 학번: ${stuNum}, 이름: ${name}, 국어: ${kor}점, 영어: ${eng}점, 수학: ${math}점, 총점: ${total}점, 평균: ${average}점
<a data-stu-num='${stuNum}' class='del-btn' href='#'>삭제</a>
</li>
`;
$ul.innerHTML += tag;
}//for문 내부
//삭제버튼 클릭이벤트
$ul.addEventListener('click', e => {
e.preventDefault();
if (!e.target.matches('ul li .del-btn')) return;
//console.log('삭제버튼 클릭!');
deleteScoreData(e.target);
});
}
//서버의 전체 성적정보 부르기
function getList() {
const xhr = new XMLHttpRequest();
xhr.open('GET', URL);
xhr.send();
xhr.onload = e => {
if (xhr.status === 200) {
makeScoreListDOM(xhr.response);
} else {
alert('통신 실패: ' + xhr.status);
}
};
}
//등록시 숫자입력창 범위 검사
const $korInput = document.querySelector('input[name=kor]');
const $engInput = document.querySelector('input[name=eng]');
const $mathInput = document.querySelector('input[name=math]');
function numberValidation() {
if (+$korInput.value < 0 || +$korInput.value > 100) return 1;
if (+$engInput.value < 0 || +$engInput.value > 100) return 2;
if (+$mathInput.value < 0 || +$mathInput.value > 100) return 3;
return 4;
}
//검증 CSS처리
function validationCSS(flagNum) {
let className = '';
if (flagNum === 1) {
className = '.kor-span';
} else if (flagNum === 2) {
className = '.eng-span';
} else if (flagNum === 3) {
className = '.math-span';
}
if (flagNum !== 4) {
document.querySelector(className).textContent = '점수는 1~100점 사이로 입력하시오~';
}
}
//기존 ul의 li태그들 전체제거
function removeAll() {
const $ul = document.querySelector('.score-list');
for (let $li of [...$ul.children]) {
if ($li.classList.contains('stuNum')) continue;
$ul.removeChild($li);
}
}
//서버로 데이터 등록요청
function sendScoreData() {
const xhr = new XMLHttpRequest();
xhr.open('POST', URL);
xhr.setRequestHeader('content-type', 'application/json');
xhr.send(JSON.stringify({
name: document.querySelector('input[name=name]').value,
kor: +$korInput.value,
eng: +$engInput.value,
math: +$mathInput.value
}));
xhr.onload = e => {
console.log(xhr.status);
if (xhr.status === 200) {
//기존 렌더링 제거
removeAll();
//새로운 데이터 렌더링
getList();
} else {
alert('등록 실패!');
}
};
}
//메인 실행부
(() => {
//서버에 있는 성적정보 리스트 불러오기
getList();
//등록버튼 이벤트처리
document.querySelector('#reg-btn').onclick = e => {
//입력란 검사(숫자 검증)
const flagNum = numberValidation();
validationCSS(flagNum);
//서버 데이터 전송
sendScoreData();
};
})();
</script>
</body>
</html>
'Spring' 카테고리의 다른 글
[Spring / 비동기 #10] ajax의 문제 해결(콜백지옥)_22.07.29 [13일차] (0) | 2022.07.29 |
---|---|
[Spring / 비동기 #9] ajax의 문제점_22.07.29 [13일차] (0) | 2022.07.29 |
[Spring / 비동기 #7] js(npm서버) 비동기 데이터처리 실습_22.07.28 [12일차] (0) | 2022.07.28 |
[Spring / 비동기 #6] js_npm서버 사용법 / ajax _22.07.28 [12일차] (0) | 2022.07.28 |
[Spring / 게시판-댓글 #5] 비동기_코드 실습_22.07.28 [12일차] (0) | 2022.07.28 |