Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

Everything has an expiration date

[SpringMVC] 20240125 [프로그램 소스] 본문

[Spring MVC]/Program source (Spring MVC)

[SpringMVC] 20240125 [프로그램 소스]

Jelly-fish 2024. 1. 25. 13:04

 

SpringMVCStudy

 

MybatisWork03


 

체크할 사항

 

Ⅰ. Javascript 에서의 String → int 변환 함수 `Number`와 `parseInt`의 차이

 

`Number(str)` 

 

기본 기능 : 문자열을 인자로 받으면 해당 문자열을 숫자로 바꿔준다.

『Check!』 : 단, 문자열이 숫자 형태가 아닌 경우에는 `NaN` (Not a Number) 이 저장된다.

 

`parseInt(str)`

기본 기능 : 문자열을 인자로 받으면 해당 문자열을 숫자로 바꿔준다.

『Check!』 : 문자열이 숫자 형태가 아닌 경우

★[ parseInt(str) - 문자열이 숫자 형태가 아닌 경우]

ⓐ 문자열이 숫자로 시작하는 경우 :
  숫자가 끝날 때까지만 형변환을 수행한다.
ex ) `"12abc"` → `12`
ⓑ 문자열이 문자로 시작하는 경우 :  `NaN` (Not a Number) 이 저장된다.
ex ) `"abc123"` → `NaN`

 


Ⅱ. EL 에서의 문자열 결합은 `+=`를 사용한다.

EL 내부에서의 문자열 결합은 `+` 가 아니라, `+=` 으로 처리한다.

 

또한 EL 내부에서 또다른 EL 은 사용이 불가능하다.

따라서 EL 을 통해 얻어낸 값을 엘리먼트의 value 값에 넣어주고 싶은 경우에는

아래와 같이 `"넣어줄 속성=" += 넣어주고 싶은 변수값` 을 문자열 결합으로 처리하도록 한다.

<input type="text" class="form-control" 
${(조건식) ? "value=" += 넣어주고 싶은 변수값 : "disabled:'disabled'"}>
</input>

 


Ⅲ. 삼항연산자의 분기 문자열 `"value="` 과 EL 을 통해 얻어온 값 연결하기

EL 삼항연산자를 통해 `<button>` 엘리먼트의  `disabled` 속성, `value` 속성 분기처리

 

받아온 객체가 하나이고,value 로 전송해줄 데이터 또한 그 객체의 값일 때는

`객체명.변수명` 으로 접근하면 된다.

<!-- [삼항 연산자를 이용한 처리 - ⓑ 입력 / 입력불가 분기 : 두 번의 삼항 연산자] -->
<!-- → EL 로 받아온 변수 바로 삽입 -->
<c:set var="sid" value="${grade.sid }" />

<button type="button" class="btn btn-default btn-xs btnInsert"
	${grade.tot == -1 ? "value=" += grade.sid : "disabled='disabled'"}>${grade.tot == -1 ? "입력" : "입력 불가"}
</button>               ─────────────────────★

</td>

 


 

② `<c:set var="변수명" value="${전송받은 데이터값 }">`  을 이용해

변수에 미리 특정한 값을 저장한 후, 삼항연산자 EL 내부에 변수명을 작성하여 사용할 수 있다.

<!-- [삼항 연산자를 이용한 처리 - ⓑ 입력 / 입력불가 분기 : 두 번의 삼항 연산자] -->
<%--  → <c:set> 을 통한 변수 --%>	
<c:set var="testSid" value="${grade.sid }" />
    <button type="button" class="btn btn-default btn-xs btnInsert"
     	${grade.tot == -1 ? "value=" += testSid : "disabled='disabled'"}>${grade.tot == -1 ? "입력" : "입력 불가"}
    </button>
</td>

 

 


MybatisWork03

■■■ Spring MVC + Annotation + mybatis 프로젝트 실습 02 ■■■


○ 프로젝트
   : MybatisWork03

○ 관련 라이브러리 등록 및 환경 구성(※ 위에서 정리한 내용 참조)
   ...

○ 기능 구현
   : 기본적인 성적 관리
     이 과정에서 mybatis 활용.

○ 데이터베이스 관련 객체 준비
   - 사용 계정 : scott
   - 테이블 : TBL_STUDENT
     ·테이블 구조 : SID NUMBER --PK
                   , NAME VARCHAR2(30)
                   , TEL VARCHAR2(40)

   - 테이블 : TBL_GRADE
     ·테이블 구조 : SID NUMBER --PK
                   , SUB1 NUMBER(3)
                   , SUB2 NUMBER(3)
                   , SUB3 NUMBER(3)
   - 뷰 : STUDENTVIEW
     ·뷰 구조 : SID, NAME, TEL, SUB
                                 --- 참조 레코드 수

   - 뷰 : GRADEVIEW
     ·뷰 구조 : SID, NAME, SUB1, SUB2, SUB3, TOT, AVG, CH
                                              ---  ---  ---
                                             총점  평균 등급(합격, 과락, 불합격)



○ 물리적 파일 구성
(수정, 삭제 기능)

   ◎ MybatisWork03_scott.sql → 데이터베이스 관련 작업

   ◎ StudentDTO.java            → 데이터 전송 객체 자료형 클래스(DTO)
                                   학생 데이터 저장 및 전송
   ◎ GradeDTO.java              → 데이터 전송 객체 자료형 클래스(DTO)
                                   성적 데이터 저장 및 전송

   ◎ IStudentDAO.java           → 인터페이스
                                   학생 데이터 액션 처리 메소드 선언
   ◎ IGradeDAO.java             → 인터페이스
                                   성적 데이터 액션 처리 메소드 선언

   ◎StudentDAO.xml             → mybatis 환경 설정 파일 활용
   - GradeDAO.xml               → mybatis 환경 설정 파일 활용

   ◎StudentController.java     → Controller
   - GradeController.java       → Controller

   ◎StudentList.jsp            → View 페이지
                                   (학생 명단 출력 레이아웃 구성)
   ◎StudentInsertForm.jsp      → View 페이지
                                   (학생 데이터 입력 폼 구성)
   ◎GradeList.jsp              → View 페이지
                                   (성적 리스트 출력 레이아웃 구성)
   ◎GradeInsertForm.jsp        → View 페이지
                                   (성적 데이터 입력 폼 구성)


   - dispatcher-servlet.xml → mybatis 객체 등록 및 활용
   - web.xml → front controller 등록 및 인코딩 설정(필터 활용)

○ 사용자 최초 요청 주소
 `http://localhost:3306/MybatisWork03/studentlist.action`

실행 스크린샷


012345678910111213
Student(list, insert, update), Grade(list, insert, update)


 

SQL 

 

MybatisWork03_scott.sql
-- MybatisWork03_scott.sql

SELECT USER
FROM DUAL;
--==>> SCOTT

/*
○ 데이터베이스 관련 객체 준비
   - 사용 계정 : scott
   - 테이블 : TBL_STUDENT
     ·테이블 구조 : SID		NUMBER		--PK
                   , NAME		VARCHAR2(30)
                   , TEL		VARCHAR2(40)

   - 테이블 : TBL_GRADE
     ·테이블 구조 : SID		NUMBER		--PK
       	           , SUB1		NUMBER(3)
       	           , SUB2		NUMBER(3)
       	           , SUB3		NUMBER(3)
   - 뷰 : STUDENTVIEW
     ·뷰 구조 : SID, NAME, TEL, SUB
                                 --- 참조 레코드 수

   - 뷰 : GRADEVIEW
     ·뷰 구조 : SID, NAME, SUB1, SUB2, SUB3, TOT, AVG, CH
                                              ---  ---  ---
                                             총점  평균 등급(합격, 과락, 불합격)

*/

--○ 실습 테이블 생성
CREATE TABLE TBL_STUDENT
( SID   NUMBER
, NAME  VARCHAR2(30)
, TEL   VARCHAR2(40)
, CONSTRAINT STUDENT_SID_PK PRIMARY KEY(SID)
);
--==>> Table TBL_STUDENT이(가) 생성되었습니다.


--○ 데이터 입력
INSERT INTO TBL_STUDENT(SID, NAME, TEL)
VALUES(1, '정현욱', '010-1111-1111');
INSERT INTO TBL_STUDENT(SID, NAME, TEL)
VALUES(2, '이윤수', '010-2222-2222');
INSERT INTO TBL_STUDENT(SID, NAME, TEL)
VALUES(3, '강혜성', '010-3333-3333');
INSERT INTO TBL_STUDENT(SID, NAME, TEL)
VALUES(4, '박범구', '010-4444-4444');
--==>> 1 행 이(가) 삽입되었습니다. * 4

--○ 확인
SELECT *
FROM TBL_STUDENT;
--==>>
/*
1	정현욱	010-1111-1111
2	이윤수	010-2222-2222
3	강혜성	010-3333-3333
4	박범구	010-4444-4444
*/

--○ 커밋
COMMIT;
--==>> 커밋 완료.



--○ 실습 테이블 생성
CREATE TABLE TBL_GRADE
( SID   NUMBER
, SUB1  NUMBER(3)
, SUB2  NUMBER(3)
, SUB3  NUMBER(3)
, CONSTRAINT GRADE_SID_PK PRIMARY KEY(SID)
, CONSTRAINT GRADE_SID_FK FOREIGN KEY(SID)
             REFERENCES TBL_STUDENT(SID)
, CONSTRAINT GRADE_SUB1_CK CHECK(SUB1 BETWEEN 0 AND 100)
, CONSTRAINT GRADE_SUB2_CK CHECK(SUB2 BETWEEN 0 AND 100)
, CONSTRAINT GRADE_SUB3_CK CHECK(SUB3 BETWEEN 0 AND 100)
);
--==>> Table TBL_GRADE이(가) 생성되었습니다.


--○ 데이터 입력
INSERT INTO TBL_GRADE(SID, SUB1, SUB2, SUB3)
VALUES(1, 90, 90, 80);
INSERT INTO TBL_GRADE(SID, SUB1, SUB2, SUB3)
VALUES(2, 92, 92, 82);
INSERT INTO TBL_GRADE(SID, SUB1, SUB2, SUB3)
VALUES(3, 70, 60, 50);
--==>> 1 행 이(가) 삽입되었습니다. * 3

--○ 확인
SELECT *
FROM TBL_GRADE;
--==>>
/*
1	90	90	80
2	92	92	82
3	70	60	50
*/

--○ 커밋
COMMIT;
--==>> 커밋 완료.

--○ 뷰 생성(STUDENTVIEW)
CREATE OR REPLACE VIEW STUDENTVIEW
AS
SELECT S.SID AS SID
     , S.NAME AS NAME
     , S.TEL AS TEL
     , (SELECT COUNT(*)
        FROM TBL_GRADE
        WHERE SID = S.SID) AS SUB
FROM TBL_STUDENT S;
--==>> View STUDENTVIEW이(가) 생성되었습니다.


--○ 뷰 생성(GRADEVIEW)
CREATE OR REPLACE VIEW GRADEVIEW
AS
SELECT S.SID AS SID
     , S.NAME AS NAME
     , NVL(G.SUB1, -1) AS SUB1
     , NVL(G.SUB2, -1) AS SUB2
     , NVL(G.SUB3, -1) AS SUB3
     , NVL((G.SUB1 + G.SUB2 + G.SUB3), -1) AS TOT
     , NVL(ROUND((G.SUB1 + G.SUB2 + G.SUB3)/3, 1), -1) AS AVG
     , (CASE WHEN NVL((G.SUB1 + G.SUB2 + G.SUB3)/3, -1) <= 60 THEN '불합격'
             WHEN (G.SUB1<=40) OR (G.SUB2<=40) OR (G.SUB3<=40) THEN '과락'
             ELSE '합격'
        END) AS CH
FROM TBL_STUDENT S LEFT JOIN TBL_GRADE G
ON S.SID = G.SID;
--==>> View GRADEVIEW이(가) 생성되었습니다.

--○ 뷰(STUDENTVIEW) 조회
SELECT SID, NAME, TEL, SUB
FROM STUDENTVIEW
ORDER BY SID;
--==>> 
/*
1	정현욱	010-1111-1111	1
2	이윤수	010-2222-2222	1
3	강혜성	010-3333-3333	1
4	박범구	010-4444-4444	0
*/

--○ 뷰(GRADEVIEW) 조회
SELECT SID, NAME, SUB1, SUB2, SUB3, TOT, AVG, CH
FROM GRADEVIEW
ORDER BY SID;
--==>>
/*
1	정현욱	90	90	80	260	86.7	합격
2	이윤수	92	92	82	266	88.7	합격
3	강혜성	70	60	50	180	60	    불합격
4	박범구	-1	-1	-1	-1	-1	    불합격
*/

--○ 인원 수 확인
SELECT COUNT(*) AS COUNT
FROM TBL_STUDENT;
--==>> 4


--▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩
--▩▩▩▩▩▩▩▩  학생  ▩▩▩▩▩▩▩▩▩
--▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩

--○ 다음번 학생의 번호 구하기
SELECT NVL(MAX(SID), 0)+1 AS NEXTSID
FROM TBL_STUDENT;


--○ 학생 데이터 삭제
DELETE
FROM TBL_STUDENT
WHERE SID=4;


--○ 학생 데이터 검색
SELECT *
FROM STUDENTVIEW
WHERE SID=1;

--○ 학생 데이터 수정
UPDATE TBL_STUDENT
SET NAME='가나다', TEL='010-1111-1111'
WHERE SID=1;




--▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩
--▩▩▩▩▩▩▩▩  성적  ▩▩▩▩▩▩▩▩▩
--▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩

--○ 성적 데이터 삭제
DELETE
FROM TBL_GRADE
WHERE SID=5;

--○ 성적 데이터 검색
SELECT *
FROM GRADEVIEW
WHERE SID=1;


--○ 성적 데이터 업데이트
UPDATE TBL_GRADE
SET SUB1=100, SUB2=100, SUB3=100
WHERE SID=1;

Student

Java Resources > src > com.test.mybatis

Student - DTO (DataTransferObject)

 

StudentDTO.java
package com.test.mybatis;

public class StudentDTO
{
	private String sid, name, tel, sub;

	// getter / setter 구성
	public String getSid()
	{
		return sid;
	}

	public void setSid(String sid)
	{
		this.sid = sid;
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getTel()
	{
		return tel;
	}

	public void setTel(String tel)
	{
		this.tel = tel;
	}
	
	
	public String getSub()
	{
		return sub;
	}

	public void setSub(String sub)
	{
		this.sub = sub;
	}
}

WebContent > WEB-INF

Student  - XML : 스프링 설정 파일

 

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>Mvc00</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>

	<!-- ※ Spring MVC Framework 등록 -->
	<!--    → Front Controller 등록 -->
	<!--    → DispatcherServlet 객체 등록 -->

	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>
	
		<!-- check~!!! -->
	<!-- 필터 등록 → 인코딩 필터 등록 → CharacterEncodingFilter -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		
	<!-- 필터 설정 → 필터 객체에 파라미터 초기값 설정 -->
	<init-param>
		<param-name>encoding</param-name>
		<param-value>UTF-8</param-value>
	</init-param>
		
	</filter>
	
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>	<!-- 어떤 요청이든 다 필터가 작용하도록 처리 『/』 -->
	</filter-mapping>

</web-app>

dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
			http://www.springframework.org/schema/context
			http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	
	<!-- ※ 사용자 정의 Controller 객체 등록 및 URL 매핑 주소 등록 -->
	<!--    - 『name=""』 속성에 매핑 주소를 등록한다. -->
	<!--       이 과정에서 Front Controller 가 갖고있는 확장자의 형태로 구성한다. -->
	<!--    - 『class=""』 속성은 -->
	<!--       Controller 객체의 패키지 경로가 포함된 클래스 이름을 등록한다. -->
	
	<!-- ① 기존 코드 -->
	<!-- ※ Annotation 표기법으로 Controller 객체를 등록할 수 있도록 한다. -->
	<!-- <context:component-scan base-package="org.springframework.samples.petclinic.web" /> -->
	<context:component-scan base-package="com.test.mybatis" />
	
	
	
	<!-- ③ mybatis 등록 과정에서 생겨나는 추가 코드 『2』 -->
	<!-- ※ mybatis 를 사용하기 위한 환경 설정 추가 -->
	<!--    필요한 dataSource 를 사용하기 위한 환경 설정 추가 -->
	<!--    → SimpleDriverDataSource 등록-->
	
	<bean id="localDataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
		<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="url" value="jdbc:oracle:thin:@211.238.142.170:1521:xe"></property>
		<property name="username" value="scott"></property>
		<property name="password" value="tiger"></property>
	</bean>
	
	
	<!-- ② mybatis 등록 과정에서 생겨나는 추가 코드 『1』 -->
	<!-- ※ mybatis 를 사용하기 위한 환경 설정 추가 -->
	<!--    → SqlSessionFactoryBean 등록 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		
		<!-- ④ dataSource 를 등록하고 와서 다시 추가 -->
		<property name="dataSource" ref="localDataSource"></property>
		
		<!-- ⑤ 매퍼 파일을 작성하고 와서 다시 추가 -->
		<!-- value 구성 과정 check~!!! -->
		<property name="mapperLocations" value="classpath:com/test/mybatis/mapper/*.xml"></property>
		
	</bean>
	<!-- DataSource 가 필요하다. -->
	
	<!-- ★ <property> : 해당 빈 객체 클래스에 『setter』 가 구성되어 있고,
	                     이를 이용해 값을 전달하겠다는 의미! -->
	<!-- ★ <constructor-arg> : 매개변수를 받는 생성자에 인자 값을 넘겨주겠다는 의미. -->
	<!--         ▶ index="0" : 첫 번째 매개변수를 넘기겠다는 의미ㅡ -->

	<!-- ⑥ mybatis 등록 과정에서 생겨나는 추가 코드 『3』 -->
	<!-- ※ SqlSession 을 사용하기 위한 환경 설정 추가 -->
	<!--    → SqlSessionTemplate 등록 -->
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
	</bean>
	
	
</beans>

Java Resources > src > com.test.mybatis

Student  - Interface

 

IStudentDAO.java
package com.test.mybatis;

import java.util.ArrayList;

public interface IStudentDAO
{
	public ArrayList<StudentDTO> list();
	public int count();
	public int nextSid();
	public int add(StudentDTO student);
	public int update(StudentDTO student);
	public int delete(String sid);
	public StudentDTO search(String sid);
	
}

Java Resources > src > com.test.mybatis.mapper

Student  - XML : DAO (DataAccessObject)  [Mapper]

 

StudentDAO.xml
<?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 namespace="com.test.mybatis.IStudentDAO">

	<!-- ① 전체 학생 조회 -->
	<select id="list" resultType="com.test.mybatis.StudentDTO">
		SELECT SID, NAME, TEL, SUB
		FROM STUDENTVIEW
		ORDER BY SID
	</select>
	
	<!-- ② 학생 인원수 조회 -->
	<select id="count" resultType="java.lang.Integer">
		SELECT COUNT(*) AS COUNT
		FROM TBL_STUDENT
	</select>
	
	<!-- ③ 다음번 SID 값(학생 번호) 구하기 -->
	<select id="nextSid" resultType="java.lang.Integer">
		SELECT NVL(MAX(SID), 0)+1 AS NEXTSID
		FROM TBL_STUDENT
	</select>
	
	<!-- ④ 학생 정보 입력 -->
	<insert id="add">
		INSERT INTO TBL_STUDENT(SID, NAME, TEL)
		VALUES(#{sid}, #{name}, #{tel})
	</insert>
	
	<!-- ⑤ SID에 해당하는 학생 정보 검색 -->
	<select id="search" resultType="com.test.mybatis.StudentDTO">
		SELECT *
		FROM STUDENTVIEW
		WHERE SID=#{sid}
	</select>
	
	<!-- ⑥ 학생 정보 삭제 -->
	<delete id="delete">
		DELETE
		FROM TBL_STUDENT
		WHERE SID=#{sid}
	</delete>
	
	<!-- ⑦ 학생 정보 수정 -->
	<update id="update">
		UPDATE TBL_STUDENT
		SET NAME=#{name}, TEL=#{tel}
		WHERE SID=#{sid}
	</update>
	
	
	
</mapper>

Java Resources > src > com.test.mybatis

Student  - Controller

 

StudentController.java
package com.test.mybatis;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class StudentController
{
	@Autowired
	private SqlSession sqlSession;
	
	//===============================================================
	// 학생 리스트 조회
	//===============================================================
	@RequestMapping(value = "/studentlist.action", method = RequestMethod.GET)
	public String studentList(ModelMap model)
	{
		IStudentDAO dao = sqlSession.getMapper(IStudentDAO.class);
		
		model.addAttribute("list", dao.list());
		model.addAttribute("count", dao.count());
		
		return "/WEB-INF/view/StudentList.jsp";
		
	}
	
	
	//===============================================================
	// 학생 입력 폼 페이지 접근
	//===============================================================
	@RequestMapping(value = "/studentinsertform.action", method = RequestMethod.GET)
	public String studentInsertForm(ModelMap model)
	{
		IStudentDAO dao = sqlSession.getMapper(IStudentDAO.class);
		
		//System.out.println("테스트" + dao.nextSid());
		model.addAttribute("nextSid", dao.nextSid());
		
		return "/WEB-INF/view/StudentInsertForm.jsp";
	}
	
	//===============================================================
	// 학생 입력 액션 처리
	//===============================================================
	@RequestMapping(value = "/studentinsert.action", method = RequestMethod.POST)
	public String studentInsert(StudentDTO student, ModelMap model)
	{
		IStudentDAO dao = sqlSession.getMapper(IStudentDAO.class);
		
		//***********************************************************
		// 학생 번호 (SID) 가 중복될 경우
		// 학생 입력 액션 처리가 정상적으로 이루어지지 않는다.
		// → 【※ 테이블 TBL_STUDENT : PRIMARY KEY(SID)】
		//***********************************************************
		
		//***********************************************************
		// 따라서, 이 컨트롤러로 전송된 DTO 객체인
		// StudentDTO 의 SID 값이 기존의 값과 중복되는지를 검사한 후
		// 입력할 수 있도록 처리한다.
		//***********************************************************

		//***********************************************************
		// 즉, 매개변수로 넘어온 StudentDTO 객체의 SID 에 해당하는
		// searchStudent 가 『null』 일 경우, 데이터 입력이 가능하다.
		//***********************************************************
		
		StudentDTO searchStudent = dao.search(student.getSid());
		
		String errMsg = "";
		
		//***********************************************
		// ⓐ 새롭게 입력할 학생 데이터의 sid 에 해당하는
		//    기존의 학생 데이터가 존재하지 않으므로
		//    데이터 입력 가능.
		//***********************************************
		if (searchStudent == null)
		{
			dao.add(student);
		}
		//***********************************************
		// ⓑ 새롭게 입력할 학생 데이터의 sid 에 해당하는
		//    기존의 학생 데이터가 존재하므로
		//    데이터 입력 불가능. → 에러 페이지 이동.
		//***********************************************
		else
		{
			errMsg = "현재 입력하고자 하는 " + student.getSid() + "번의 학생 데이터가"
			      + " 이미 존재하므로, 번호가 중복되어 학생 데이터 신규 입력이 불가능합니다.";
		
			model.addAttribute("errMsg", errMsg);
			
			return "/WEB-INF/view/StudentError.jsp";
		
		}
		
		return "redirect:studentlist.action";
		
	}
	
	//===============================================================
	// 학생 삭제 액션 처리
	//===============================================================
	@RequestMapping(value = "/studentdelete.action", method = RequestMethod.GET)
	public String studentDelete(String sid, ModelMap model)
	{
		IStudentDAO dao = sqlSession.getMapper(IStudentDAO.class);
		
		//*********************************************************
		// 학생을 참조하는 성적 레코드가 존재할 경우
		// 학생 데이터를 삭제할 수 없다.
		// → 학생 번호(SID)를 참조하는 성적 레코드 표시 : 『SUB』
		//*********************************************************
		
		StudentDTO searchStudent = dao.search(sid);
		String errMsg = "";
		
		//*********************************************************
		// [null]-----------------------------------------------
		// ⓐ 학생 번호(SID) 에 해당하는 데이터가 없을 경우 : 
		//    → 에러 페이지로 이동한다.
		//
		// [not null]-------------------------------------------
		// ⓑ SUB 가 0 일 때 : 삭제 처리가 가능하도록 처리한다.
		// ⓒ SUB 가 1 일 때 : 에러 페이지로 이동한다.
		//*********************************************************
		if (searchStudent == null)
		{
			errMsg = "선택하신 번호에 해당하는 학생 정보가 존재하지 않아, 『학생 정보 삭제』가 불가능합니다.";
			
			model.addAttribute("errMsg", errMsg);
			return "/WEB-INF/view/StudentError.jsp";
			
		}
		else if (Integer.parseInt(searchStudent.getSub()) == 0)
		{
			dao.delete(sid);
		}
		else if (Integer.parseInt(searchStudent.getSub()) > 0)
		{
			errMsg = "번호 " + searchStudent.getSid() + "번"
				       + " " + searchStudent.getName() + " 학생의"
		               + " 성적 데이터가 존재하여 『학생 정보 삭제』가 불가능합니다.";
			
			model.addAttribute("errMsg", errMsg);
			return "/WEB-INF/view/StudentError.jsp";
		}
		
		
		return "redirect:studentlist.action";
		
	}
	
	
	//===============================================================
	// 학생 업데이트 폼 페이지 접근
	//===============================================================
	@RequestMapping(value = "/studentupdateform.action", method = RequestMethod.GET)
	public String studentUpdateForm(String sid, ModelMap model)
	{
		IStudentDAO dao = sqlSession.getMapper(IStudentDAO.class);
		
		//***************************************************************
		// 이전 페이지(StudentList.jsp) 에서 넘어온 데이터인
		// 학생 번호(sid)를 기반으로 StudentDTO 객체를 찾아내어
		// 업데이트 폼 페이지에 기존 학생 정보를 뿌려줄 수 있도록 한다.
		//***************************************************************
		
		StudentDTO student = dao.search(sid);
		
		model.addAttribute("student", student);
		
		return "/WEB-INF/view/StudentUpdateForm.jsp";
		
	}
	
	
	//===============================================================
	// 학생 업데이트 액션 처리
	//===============================================================
	@RequestMapping(value = "/studentupdate.action", method = RequestMethod.POST)
	public String studentUpdate(StudentDTO student, ModelMap model)
	{
		IStudentDAO dao = sqlSession.getMapper(IStudentDAO.class);
		
		//*******************************************************************
		// 하드 코딩을 통해 URL 에 GET 방식으로 접근했을 경우
		// 존재하지 않는 SID에 대해 학생 정보 수정을 요청했을 때
		// 입력받은 SID에 해당하는 학생 레코드가 존재하지 않아 에러 발생.
		//*******************************************************************
		
		//*******************************************************************
		// 이를 처리하기 위해, 전송받은 DTO 객체 StudentDTO의
		// SID 값을 이용하여 객체를 얻어내보았을 때
		// null 값인지를 확인하여 Error 페이지 전송.
		//*******************************************************************
		
		StudentDTO searchStudent = dao.search(student.getSid());
		String errMsg = "";
		
		if (searchStudent == null)
		{
			//System.out.println("해당 sid에 해당하는 학생 데이터 존재하지 않음.");
			errMsg = "해당 번호에 해당하는 학생 정보가 존재하지 않아"
					+ " 『학생 정보 수정』이 불가능합니다.";
			
			model.addAttribute("errMsg", errMsg);
			return "/WEB-INF/view/StudentError.jsp";
		}
		else
		{
			dao.update(student);
			
		}
		
		
		return "redirect:studentlist.action";
	}
	
	
	
}

Student  - View

 

StudentList.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>StudentList.jsp</title>
<!-- 기본 CSS -->
<link rel="stylesheet" type="text/css" href="<%=cp %>/css/main.css">

<!-- 부트스트랩 적용 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">

<!-- 부트스트랩 부가 테마 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">

<!-- 제이쿼리 적용 JS -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<!-- 부트스트랩 관련 스크립트 적용 JS -->
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

<style type="text/css">
	td {text-align: center;}
	th {text-align: center;}
</style>

<script type="text/javascript">
	
	$(document).ready(function()
	{
		// 학생 입력
		$(".btnInsert").click(function()
		{
			$(location).attr("href", "studentinsertform.action");
		});	
		
		// 학생 수정
		$(".btnUpdate").click(function()
		{
			$(location).attr("href", "studentupdateform.action?sid=" + $(this).val());
		});	
		
		// 학생 삭제
		$(".btnDelete").click(function()
		{
			$(location).attr("href", "studentdelete.action?sid=" + $(this).val());
		});	
		
		// 성적 조회 페이지로 이동
		$(".btnGradeList").click(function()
		{
			$(location).attr("href", "gradelist.action");
		});
		
	});
	


</script>

</head>
<body>

<div>
	<h1>학생 데이터 조회</h1>
	<hr>
</div>

<div class="container">
	<div class="panel-group">
		<div class="panel panel-default">
			<div class="panel-heading">
				<button type="button" class="btn btn-default btnGradeList">성적 조회 페이지</button>
				<button type="button" class="btn btn-default btnInsert">학생 입력</button>
			</div>
		</div>
		<br>
		<div class="panel panel-default">
			<div class="panel-heading">
				학생 정보 출력
				<div>
					<button type="button" class="btn btn-default btn-sm" role="badgeFrame">
						전체 인원 수 : <span class="badge" role="badge">${count }</span>
					</button>
				</div>
			</div>
		
			<div class="panel-body">
				<table class="table">
					<thead>
						<tr>
							<th>번호</th>
							<th>이름</th>
							<th>전화</th>
							<th>SUB</th>
							<th>수정/삭제</th>
						</tr>
					</thead>
					<tbody>
						<c:forEach var="stu" items="${list }">
							<tr>
								<td>${stu.sid }</td>
								<td>${stu.name }</td>
								<td>${stu.tel }</td>
								<td>${stu.sub }</td>
								<td>
									<button type="button" class="btn btn-default btn-xs btnUpdate"
									value="${stu.sid }">수정</button>
									<c:choose>
										<c:when test="${stu.sub == 0 }">
											<button type="button" class="btn btn-default btn-xs btnDelete"
											value="${stu.sid }">삭제</button>
										</c:when>
										<c:otherwise>
											<button type="button" class="btn btn-default btn-xs btnDelete"
											disabled="disabled">삭제불가</button>
										</c:otherwise>
									
									
									</c:choose>
								</td>
							</tr>
						</c:forEach>
					</tbody>
				</table>
			</div><!-- end panel-body -->
		
		</div><!-- end panel panel-defalut -->

	</div><!-- panel-group -->
	
</div>

</body>
</html>

StudentInsertForm.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>StudentList.jsp</title>
<!-- 기본 CSS -->
<link rel="stylesheet" type="text/css" href="<%=cp %>/css/main.css">

<!-- 부트스트랩 적용 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">

<!-- 부트스트랩 부가 테마 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">

<!-- 제이쿼리 적용 JS -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<!-- 부트스트랩 관련 스크립트 적용 JS -->
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

<style type="text/css">
	td {text-align: center;}
	th {text-align: center;}
	.panel-heading {text-align: center;}
	.err {display: none; font-weight: bold; font-size: small; color: red;}
</style>

<script type="text/javascript">
	
	$(document).ready(function()
	{
		// 뒤로가기 클릭시, 학생 전체 조회 페이지로 이동.
		$(".btnBack").click(function()
		{
			$(location).attr("href", "studentlist.action")
		});
		
		
		// 모든 입력값을 제대로 입력했는지에 대한 처리.
		$("#btnCheck").click(function()
		{
			//*******************************************************
			// formCheck() == true  : 모든 입력 값 제대로 입력.
			// formCheck() == false : 입력 값이 제대로 입력되지 않음. 
			//*******************************************************
			if (formCheck())
			{
				stuInsertForm.submit();
			}
			
		});
	});
	
	function formCheck()
	{
		// 테스트
		//alert($("#name").val());
		
		var msg = "";
		
		$(".err").css("display", "none");
		
		if ($("#name").val()=="" || $("#name").val()==null)
		{
			//alert("이름을 입력하지 않으셨습니다.");
			
			$("#nameErrMsg").html("이름을 입력하지 않으셨습니다.");
			$("#nameErrMsg").css("display", "inline");
			$("#name").focus();
			return false;
		}
		if ($("#tel").val()=="" || $("#tel").val()==null)
		{
			//alert("전화번호를 입력하지 않으셨습니다.");
			
			$("#telErrMsg").html("전화번호를 입력하지 않으셨습니다.");
			$("#telErrMsg").css("display", "inline");
			$("#tel").focus();
			return false;
			
		}
		
		return true;
		
	}

</script>

</head>
<body>

<div>
	<h1>학생 데이터 입력</h1>
	<hr>
</div>

<div class="container">
	<div class="panel-group">
		<div class="panel panel-default">
		
			<div class="panel-heading">
				학생 정보 입력
			</div>
		
			<div class="panel-body">
				<form role="form" action="studentinsert.action?sid=${nextSid }" method="post" name="stuInsertForm">
					
					<div class="form-group">
						<label for="sid">
						번호(자동지정) :
						</label>
						<input type="text" class="form-control" id="sid" name="sid" disabled="disabled"
						value="${nextSid }">
					</div>
					
					<div class="form-group">
						<label for="name">
						이름 :
						</label>
						<input type="text" class="form-control" id="name" name="name">
						<span id="nameErrMsg" class="err"></span>
					</div>
					<div class="form-group">
						<label for="tel">
						전화 :
						</label>
						<input type="text" class="form-control" id="tel" name="tel">
						<span id="telErrMsg" class="err"></span>
					</div>
					
					<button type="button" class="btn btn-default" id="btnCheck">입력 완료</button>
					<button type="reset" class="btn btn-default btnCancel">취소</button>
					<button type="button" class="btn btn-default btnBack">학생 리스트 페이지로</button>
					
				</form>
			</div><!-- end panel-body -->
		
		</div><!-- end panel panel-defalut -->

	</div><!-- panel-group -->
	
</div>

</body>
</html>

StudentUpdateForm.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>StudentList.jsp</title>
<!-- 기본 CSS -->
<link rel="stylesheet" type="text/css" href="<%=cp %>/css/main.css">

<!-- 부트스트랩 적용 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">

<!-- 부트스트랩 부가 테마 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">

<!-- 제이쿼리 적용 JS -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<!-- 부트스트랩 관련 스크립트 적용 JS -->
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

<style type="text/css">
	td {text-align: center;}
	th {text-align: center;}
	.panel-heading {text-align: center;}
	.err {display: none; font-weight: bold; font-size: small; color: red;}
</style>

<script type="text/javascript">
	
	$(document).ready(function()
	{
		// 뒤로가기 클릭시, 학생 전체 조회 페이지로 이동.
		$(".btnBack").click(function()
		{
			$(location).attr("href", "studentlist.action")
		});
		
		
		// 모든 입력값을 제대로 입력했는지에 대한 처리.
		$("#btnCheck").click(function()
		{
			//*******************************************************
			// formCheck() == true  : 모든 입력 값 제대로 입력.
			// formCheck() == false : 입력 값이 제대로 입력되지 않음. 
			//*******************************************************
			if (formCheck())
			{
				stuUpdateForm.submit();
			}
			
		});
	});
	
	function formCheck()
	{
		// 테스트
		//alert($("#name").val());
		
		var msg = "";
		
		$(".err").css("display", "none");
		
		if ($("#name").val()=="" || $("#name").val()==null)
		{
			//alert("이름을 입력하지 않으셨습니다.");
			
			$("#nameErrMsg").html("이름을 입력하지 않으셨습니다.");
			$("#nameErrMsg").css("display", "inline");
			$("#name").focus();
			return false;
		}
		if ($("#tel").val()=="" || $("#tel").val()==null)
		{
			//alert("전화번호를 입력하지 않으셨습니다.");
			
			$("#telErrMsg").html("전화번호를 입력하지 않으셨습니다.");
			$("#telErrMsg").css("display", "inline");
			$("#tel").focus();
			return false;
			
		}
		
		return true;
		
	}

</script>

</head>
<body>

<div>
	<h1>학생 데이터 수정</h1>
	<hr>
</div>

<div class="container">
	<div class="panel-group">
		<div class="panel panel-default">
		
			<div class="panel-heading">
				학생 정보 수정
			</div>
		
			<div class="panel-body">
				<form role="form" action="studentupdate.action?sid=${student.sid }" method="post" name="stuUpdateForm">
					
					<div class="form-group">
						<label for="sid">
						번호 :
						</label>
						<input type="text" class="form-control" id="sid" name="sid" disabled="disabled"
						value="${student.sid }">
					</div>
					
					<div class="form-group">
						<label for="name">
						이름 :
						</label>
						<input type="text" class="form-control" id="name" name="name"
						value="${student.name }">
						<span id="nameErrMsg" class="err"></span>
					</div>
					<div class="form-group">
						<label for="tel">
						전화 :
						</label>
						<input type="text" class="form-control" id="tel" name="tel"
						value="${student.tel }">
						<span id="telErrMsg" class="err"></span>
					</div>
					
					<button type="button" class="btn btn-default" id="btnCheck">입력 완료</button>
					<button type="reset" class="btn btn-default btnCancel">취소</button>
					<button type="button" class="btn btn-default btnBack">학생 리스트 페이지로</button>
					
				</form>
			</div><!-- end panel-body -->
		
		</div><!-- end panel panel-defalut -->

	</div><!-- panel-group -->
	
</div>

</body>
</html>

StudentError.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>GradeInsertError.jsp</title>
<link rel="stylesheet" type="text/css" href="<%=cp %>/css/main.css">

<style type="text/css">
	
	#errMsg		{ color: red; font-size: 20px; text-align: center; font-weight: bolder;}
	
</style>

<!-- 부트스트랩 적용 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">

<!-- 부트스트랩 부가 테마 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">

<!-- 제이쿼리 적용 JS -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<!-- 부트스트랩 관련 스크립트 적용 JS -->
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

<script type="text/javascript">

	$(document).ready(function()
	{
		$(".btnBack").click(function()
		{
			// 테스트
			//alert("뒤로가기 확인~!!!");
			
			$(location).attr("href", "studentlist.action");
			//--> 학생 조회 리스트 페이지로 돌아가기
			
		});
		
	});

</script>

</head>
<body>
<div>
	<h1>학생 데이터 에러</h1>
	<hr />
</div>

<div class="container">
	<div class="panel-group">
		<div class="panel panel-default">
			<div class="panel-heading">
				
				<!-- [에러 발생 상황에 따른 분류]=========================================-->
				<!-- 
					 ① 학생 번호(sid)가 이미 존재하는데도, INSERT 요청시
					    → TBL_STUDENT 에서의 PRIMARY KEY (SID) 중복되어 에러. (unique 만족Ⅹ)
					    
					 ② 학생 데이터가 존재하지 않는 상황에서 수정 요청시
					    → TBL_STUDENT 에 존재하지 않는 레코드를 수정하려 하기 때문에 에러.
				
					 ③ 학생 데이터가 존재하지 않는 상황에서 삭제 요청시
					    → TBL_STUDENT 에 존재하지 않는 레코드를 삭제하려 하기 때문에 에러.
				
				===========================================================================-->
				
				<span id="errMsg">
					${errMsg }
				</span>
			</div>
		</div>
	</div>
	<div>
		<button type="button" class="btn btn-default btnBack">학생 리스트 페이지로</button>
	</div>
</div>

</body>
</html>

Grade

Java Resources > src > com.test.mybatis

Grade  - DTO (DataTransferObject)

 

GradeDTO.java
package com.test.mybatis;

public class GradeDTO
{
	private String sid, name, ch;
	private int sub1, sub2, sub3, tot;
	private double avg;
	
	// getter / setter 구성
	
	public String getSid()
	{
		return sid;
	}
	public void setSid(String sid)
	{
		this.sid = sid;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	public String getCh()
	{
		return ch;
	}
	public void setCh(String ch)
	{
		this.ch = ch;
	}
	public int getSub1()
	{
		return sub1;
	}
	public void setSub1(int sub1)
	{
		this.sub1 = sub1;
	}
	public int getSub2()
	{
		return sub2;
	}
	public void setSub2(int sub2)
	{
		this.sub2 = sub2;
	}
	public int getSub3()
	{
		return sub3;
	}
	public void setSub3(int sub3)
	{
		this.sub3 = sub3;
	}
	public int getTot()
	{
		return tot;
	}
	public void setTot(int tot)
	{
		this.tot = tot;
	}
	public double getAvg()
	{
		return avg;
	}
	public void setAvg(double avg)
	{
		this.avg = avg;
	}
	



}

WebContent > WEB-INF

Grade - XML : 스프링 설정 파일

 

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>Mvc00</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>

	<!-- ※ Spring MVC Framework 등록 -->
	<!--    → Front Controller 등록 -->
	<!--    → DispatcherServlet 객체 등록 -->

	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>
	
		<!-- check~!!! -->
	<!-- 필터 등록 → 인코딩 필터 등록 → CharacterEncodingFilter -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		
	<!-- 필터 설정 → 필터 객체에 파라미터 초기값 설정 -->
	<init-param>
		<param-name>encoding</param-name>
		<param-value>UTF-8</param-value>
	</init-param>
		
	</filter>
	
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>	<!-- 어떤 요청이든 다 필터가 작용하도록 처리 『/』 -->
	</filter-mapping>

</web-app>

dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
			http://www.springframework.org/schema/context
			http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	
	<!-- ※ 사용자 정의 Controller 객체 등록 및 URL 매핑 주소 등록 -->
	<!--    - 『name=""』 속성에 매핑 주소를 등록한다. -->
	<!--       이 과정에서 Front Controller 가 갖고있는 확장자의 형태로 구성한다. -->
	<!--    - 『class=""』 속성은 -->
	<!--       Controller 객체의 패키지 경로가 포함된 클래스 이름을 등록한다. -->
	
	<!-- ① 기존 코드 -->
	<!-- ※ Annotation 표기법으로 Controller 객체를 등록할 수 있도록 한다. -->
	<!-- <context:component-scan base-package="org.springframework.samples.petclinic.web" /> -->
	<context:component-scan base-package="com.test.mybatis" />
	
	
	
	<!-- ③ mybatis 등록 과정에서 생겨나는 추가 코드 『2』 -->
	<!-- ※ mybatis 를 사용하기 위한 환경 설정 추가 -->
	<!--    필요한 dataSource 를 사용하기 위한 환경 설정 추가 -->
	<!--    → SimpleDriverDataSource 등록-->
	
	<bean id="localDataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
		<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="url" value="jdbc:oracle:thin:@211.238.142.170:1521:xe"></property>
		<property name="username" value="scott"></property>
		<property name="password" value="tiger"></property>
	</bean>
	
	
	<!-- ② mybatis 등록 과정에서 생겨나는 추가 코드 『1』 -->
	<!-- ※ mybatis 를 사용하기 위한 환경 설정 추가 -->
	<!--    → SqlSessionFactoryBean 등록 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		
		<!-- ④ dataSource 를 등록하고 와서 다시 추가 -->
		<property name="dataSource" ref="localDataSource"></property>
		
		<!-- ⑤ 매퍼 파일을 작성하고 와서 다시 추가 -->
		<!-- value 구성 과정 check~!!! -->
		<property name="mapperLocations" value="classpath:com/test/mybatis/mapper/*.xml"></property>
		
	</bean>
	<!-- DataSource 가 필요하다. -->
	
	<!-- ★ <property> : 해당 빈 객체 클래스에 『setter』 가 구성되어 있고,
	                     이를 이용해 값을 전달하겠다는 의미! -->
	<!-- ★ <constructor-arg> : 매개변수를 받는 생성자에 인자 값을 넘겨주겠다는 의미. -->
	<!--         ▶ index="0" : 첫 번째 매개변수를 넘기겠다는 의미ㅡ -->

	<!-- ⑥ mybatis 등록 과정에서 생겨나는 추가 코드 『3』 -->
	<!-- ※ SqlSession 을 사용하기 위한 환경 설정 추가 -->
	<!--    → SqlSessionTemplate 등록 -->
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
	</bean>
	
	
</beans>

Java Resources > src > com.test.mybatis

Grade - Interface

 

IGradeDAO.java
package com.test.mybatis;

import java.util.ArrayList;

public interface IGradeDAO
{
	public ArrayList<GradeDTO> list();
	public int add(GradeDTO grade);
	public int update(GradeDTO grade);
	public int delete(String sid);
	public GradeDTO search(String sid);
}

Java Resources > src > com.test.mybatis.mapper

Grade - XML : DAO (DataAccessObject)  [Mapper]

 

GradeDAO.xml
<?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 namespace="com.test.mybatis.IGradeDAO">

	<!-- ① 전체 성적 조회 -->
	<select id="list" resultType="com.test.mybatis.GradeDTO">
		SELECT SID, NAME, SUB1, SUB2, SUB3, TOT, AVG, CH
		FROM GRADEVIEW
		ORDER BY SID
	</select>
	
	<!-- ② SID 에 해당하는 학생 성적 조회 -->
	<select id="search" resultType="com.test.mybatis.GradeDTO">
		SELECT *
		FROM GRADEVIEW
		WHERE SID=#{sid }
	</select>
	
	<!-- ③ 성적 입력 -->
	<insert id="add">
		INSERT INTO TBL_GRADE(SID, SUB1, SUB2, SUB3)
		VALUES(#{sid}, #{sub1}, #{sub2}, #{sub3})
	</insert>

	<!-- ④ 성적 삭제 -->
	<delete id="delete">
		DELETE
		FROM TBL_GRADE
		WHERE SID=#{sid}
	</delete>
	
	<!-- ⑤ 성적 수정 -->
	<update id="update">
		UPDATE TBL_GRADE
		SET SUB1=#{sub1}, SUB2=#{sub2}, SUB3=#{sub3}
		WHERE SID=#{sid}
	</update>
	
	
</mapper>

Java Resources > src > com.test.mybatis

Grade - Controller

 

GradeController.java
package com.test.mybatis;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class GradeController
{
	@Autowired
	private SqlSession sqlSession;
	
	//==============================================================
	// 성적 리스트 조회
	//==============================================================
	@RequestMapping(value = "gradelist.action", method = RequestMethod.GET)
	public String gradeList(ModelMap model)
	{
		IGradeDAO dao = sqlSession.getMapper(IGradeDAO.class);
		
		model.addAttribute("list", dao.list());
		
		return "/WEB-INF/view/GradeList.jsp";
		
	}
	
	//==============================================================
	// 성적 입력 폼 페이지 접근
	//==============================================================
	@RequestMapping(value = "gradeinsertform.action", method = RequestMethod.GET)
	public String gradeInsertForm(String sid, ModelMap model)
	{
		model.addAttribute("sid", sid);
		
		return "/WEB-INF/view/GradeInsertForm.jsp";
	}
	
	//==============================================================
	// 성적 입력 액션 처리
	//==============================================================
	@RequestMapping(value = "gradeinsert.action", method = RequestMethod.POST)
	public String gradeInsert(GradeDTO grade, ModelMap model)
	{
		//=================================================================
		// GET 방식으로 전송한 sid를 수신하여 자동으로 GradeDTO 객체에 
		// set 해 준 상태이다.
		//=================================================================
		IGradeDAO dao = sqlSession.getMapper(IGradeDAO.class);
		
		//=================================================================
		// ★ 이때, 이미 성적 입력이 처리되어 있는 학생의 성적을
		//    다시 INSERT 하려는 경우
		//    PRIMARY KEY인 SID 가 중복되어 아래의 Exception이 발생한다. 
		//   『ORA-00001: unique constraint (SCOTT.GRADE_SID_PK) violated』
		//=================================================================
		
		//=================================================================
		// 따라서, 사용자가 입력한 GradeDTO 객체의 sid 를 기반으로
		// 성적이 이미 입력이 완료된 상태인지 아닌지를 확인한 후에만
		// 성적 입력이 가능하도록 처리해야 한다.
		//=================================================================
		
		
		GradeDTO searchGrade = dao.search(grade.getSid());
		String errMsg = "";
		
		
		//**********************************************************************
		// ※ 총점 TOT 값을 기준으로, 이미 성적 처리가 완료된 학생인지 판별한다.
		//**********************************************************************
		System.out.println(searchGrade.getTot());
		//▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩
		//--ⓐ -1 일 경우 : 성적 데이터가 존재하지 않는 상태. 【입력 가능!】
		//--ⓑ -1 이 아닐 경우 : 성적 데이터가 존재하는 상태. 【입력 불가능!】
		//▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩▩
		
		
		if (searchGrade.getTot() == -1) // [성적 존재Ⅹ → 성적 입력 가능]
		{
			dao.add(grade);
			
		}
		else							// [성적 존재○ → 성적 입력 불가능!]
		{
			errMsg = "이미 성적 정보가 존재하여 성적 입력을 처리할 수 없습니다.";
			model.addAttribute("sid", grade.getSid());
			model.addAttribute("name", searchGrade.getName());
			model.addAttribute("errMsg", errMsg);
			return "/WEB-INF/view/GradeError.jsp";
		}
		
		return "redirect:gradelist.action";
	}
	
	//==============================================================
	// 성적 삭제 액션 처리
	//==============================================================
	@RequestMapping(value = "gradedelete.action", method = RequestMethod.GET)
	public String gradeDelete(String sid, ModelMap model)
	{
		IGradeDAO dao = sqlSession.getMapper(IGradeDAO.class);
		
		GradeDTO searchGrade = dao.search(sid);
		
		String errMsg = "";
		
		//*********************************************************
		// ⓐ 성적이 존재하지 않는 상황인데도 삭제를 요청했을 경우
		//    → 【삭제 불가】 : Error 페이지 이동.
		//*********************************************************
		if (searchGrade.getTot() == -1)
		{
			errMsg = "해당 학생에 대한 성적 데이터가 존재하지 않아, 『성적 삭제』가 불가능합니다.";
			
			model.addAttribute("errMsg", errMsg);
			
			return "/WEB-INF/view/GradeError.jsp";
		}
		//*********************************************************
		// ⓑ 성적이 존재하는 상황에 삭제를 요청했을 경우
		//    → 【삭제 가능】 : 성적 데이터 삭제
		//*********************************************************
		else
		{
			dao.delete(sid);
		}
		
		
		
		return "redirect:gradelist.action";
	}
	
	//==============================================================
	// 성적 업데이트 폼 페이지 접근
	//==============================================================
	@RequestMapping(value = "gradeupdateform.action", method = RequestMethod.GET)
	public String gradeUpdateForm(String sid, ModelMap model)
	{
		IGradeDAO dao = sqlSession.getMapper(IGradeDAO.class);
		
		//***********************************************************
		// ① sid 에 해당하는 성적 정보 객체(GradeDTO) 가져오기
		//***********************************************************
		GradeDTO grade = dao.search(sid);
		
		//***********************************************************
		// ② 해당하는 객체를 model 에 addAttribute 하여
		//    입력폼에서 기존 성적 데이터를 뿌려줄 수 있도록 처리하기.
		//***********************************************************
		model.addAttribute("grade", grade);
		
		return "/WEB-INF/view/GradeUpdateForm.jsp";
		
	}
	
	//==============================================================
	// 성적 업데이트 액션 처리
	//==============================================================
	@RequestMapping(value = "gradeupdate.action", method = RequestMethod.POST)
	public String gradeUpdate(GradeDTO grade, ModelMap model)
	{
		IGradeDAO dao = sqlSession.getMapper(IGradeDAO.class);
		
		GradeDTO searchGrade = dao.search(grade.getSid());
		
		String errMsg = "";
		
		//*********************************************************
		// ⓐ 성적이 존재하지 않는 상황인데도  수정을 요청했을 경우
		//    → 【수정 불가】 : Error 페이지 이동.
		//*********************************************************
		if (searchGrade.getTot() == -1)
		{
			errMsg = "해당 학생에 대한 성적 데이터가 존재하지 않아, 『성적 수정』이 불가능합니다.";
			
			model.addAttribute("errMsg", errMsg);
			
			return "/WEB-INF/view/GradeError.jsp";
		}
		
		
		//*********************************************************
		// ⓑ 성적이 존재하는 상황에서 수정을 요청했을 경우
		//    → 【수정 가능】 : 성적 정보 수정 처리.
		//*********************************************************
		
		
		dao.update(grade);
		
		return "redirect:gradelist.action";
	}
	
	
}

Java Resources > src > com.test.mybatis

Grade - View

 

GradeList.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>StudentList.jsp</title>
<!-- 기본 CSS -->
<link rel="stylesheet" type="text/css" href="<%=cp %>/css/main.css">

<!-- 부트스트랩 적용 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">

<!-- 부트스트랩 부가 테마 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">

<!-- 제이쿼리 적용 JS -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<!-- 부트스트랩 관련 스크립트 적용 JS -->
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

<style type="text/css">
	td {text-align: center;}
	th {text-align: center;}
</style>

<script type="text/javascript">
	
	$(document).ready(function()
	{
		// 성적 입력
		$(".btnInsert").click(function()
		{
			$(location).attr("href", "gradeinsertform.action?sid=" + $(this).val());
		});	
		
		// 성적 수정
		$(".btnUpdate").click(function()
		{
			$(location).attr("href", "gradeupdateform.action?sid=" + $(this).val());
		});	
		
		// 성적 삭제
		$(".btnDelete").click(function()
		{
			//alert($(this).val());
			$(location).attr("href", "gradedelete.action?sid=" + $(this).val());
		});	
		
		// 학생 조회 페이지로
		$(".btnStudentList").click(function()
		{
			$(location).attr("href", "studentlist.action");
		});
		
	});

</script>

</head>
<body>

<div>
	<h1>성적 데이터 조회</h1>
	<hr>
</div>

<div class="container">
	<div class="panel-group">
		<div class="panel panel-default">
			<div class="panel-heading">
				<button type="button" class="btn btn-default btnStudentList">학생 조회 페이지</button>
			</div>
		</div>
		<br>
		<div class="panel panel-default">
			<div class="panel-heading">
				성적 정보 출력
			</div>
		
			<div class="panel-body">
				<table class="table">
					<thead>
						<tr>
							<th>번호</th>
							<th>이름</th>
							<th>과목1</th>
							<th>과목2</th>
							<th>과목3</th>
							<th>총점</th>
							<th>평균</th>
							<th>등급</th>
							<th>입력</th>
							<th>수정/삭제</th>
						</tr>
					</thead>
					<tbody>
						<c:forEach var="grade" items="${list }">
							<tr>
								<td>${grade.sid }</td>
								<td>${grade.name }</td>
								<td>${grade.sub1 }</td>
								<td>${grade.sub2 }</td>
								<td>${grade.sub3 }</td>
								<td>${grade.tot }</td>
								<td>${grade.avg }</td>
								<td>${grade.ch }</td>
								<td>
								
								<%-- Ⅰ. [<c:choose> EL 을 이용한 처리] --%>
								<%-- 
									<c:choose>
										<c:when test="${grade.tot == -1}">
											<button type="button" class="btn btn-default btn-xs btnInsert"
											value="${grade.sid }" id="inputBtn">입력</button>
										</c:when>
										<c:otherwise>
											<button type="button" class="btn btn-default btn-xs btnInsert"
											disabled="disabled">입력불가</button>
										</c:otherwise>
									</c:choose>
								 --%>	
								
								<!-- Ⅱ. [삼항 연산자를 이용한 처리 - ⓐ 입력 / 입력불가 분기 : 버튼 태그 포함] -->
								<%-- <button> 태그를 닫지 않아 에러가 발생하지만, 제대로 뷰 페이지에 분기 처리가 가능하다. --%>
								<%--
								<button type="button" class="btn btn-default btn-xs btnInsert"
								${grade.tot == -1 ? "value='${grade.sid }'>입력" : "disabled='disabled'>입력불가"}</button>
								</td>
								--%>
								
								<!-- Ⅲ. [삼항 연산자를 이용한 처리 - ⓑ 입력 / 입력불가 분기 : 두 번의 삼항 연산자] -->
								<%--     → <c:set> 을 통한 변수 --%>
								<%-- 		
								<c:set var="testSid" value="${grade.sid }" />
								<button type="button" class="btn btn-default btn-xs btnInsert"
								 ${grade.tot == -1 ? "value=" += testSid : "disabled='disabled'"}>${grade.tot == -1 ? "입력" : "입력 불가"}
								</button>
								</td>
								--%>
								
								<!-- Ⅳ. [삼항 연산자를 이용한 처리 - ⓑ 입력 / 입력불가 분기 : 두 번의 삼항 연산자] -->
								<!--     → EL 로 받아온 변수 바로 삽입 -->
								<button type="button" class="btn btn-default btn-xs btnInsert"
								 ${grade.tot == -1 ? "value=" += grade.sid : "disabled='disabled'"}>${grade.tot == -1 ? "입력" : "입력 불가"}
								</button>
								</td>
								
								
								
								<td>
									 		
								<%-- Ⅰ. [<c:choose> EL 을 이용한 처리] --%>
								<%-- 
									<c:choose>
										<c:when test="${grade.tot == -1 }">
											<button type="button" class="btn btn-default btn-xs btnUpdate"
											disabled="disabled">수정불가</button>
											<button type="button" class="btn btn-default btn-xs btnDelete"
											disabled="disabled">삭제불가</button>
										</c:when>
										<c:otherwise>
											<button type="button" class="btn btn-default btn-xs btnUpdate"
											value="${grade.sid }">수정</button>
											<button type="button" class="btn btn-default btn-xs btnDelete"
											value="${grade.sid }">삭제</button>
										</c:otherwise>
									</c:choose>
								 --%>
								 
								 <%-- Ⅱ. [삼항 연산자를 이용한 처리 - 입력 / 입력불가 분기 : 세 번의 삼항 연산자] --%>
								 <!--      → ① disabled 분기 ③ 버튼명 분기 -->	
									<button type="button" class="btn btn-default btn-xs btnUpdate"
									${grade.tot == -1 ? "disabled='disabled'" : "value=" += grade.sid}
									>
										${grade.tot == -1 ? "수정불가" : "수정"}
									</button>
									<!-- EL 을 통한 삼항연산자 -->
									<c:set var="testSid" value="${grade.sid }" />
									
									<button type="button" class="btn btn-default btn-xs btnDelete"
									${grade.tot == -1 ? "disabled='disabled'" : "value=" += testSid}
									>
										${grade.tot == -1 ? "삭제불가" : "삭제"}
									</button>
								</td>
							</tr>
						</c:forEach>
					</tbody>
				</table>
			</div><!-- end panel-body -->
		
		</div><!-- end panel panel-defalut -->

	</div><!-- panel-group -->
	
</div>

</body>
</html>

GradeInsertForm.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>StudentList.jsp</title>
<!-- 기본 CSS -->
<link rel="stylesheet" type="text/css" href="<%=cp %>/css/main.css">

<!-- 부트스트랩 적용 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">

<!-- 부트스트랩 부가 테마 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">

<!-- 제이쿼리 적용 JS -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<!-- 부트스트랩 관련 스크립트 적용 JS -->
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

<style type="text/css">
	td {text-align: center;}
	th {text-align: center;}
	.panel-heading {text-align: center;}
	.err {display: none; font-weight: bold; font-size: small; color: red;}
</style>

<script type="text/javascript">
	
	$(document).ready(function()
	{
		// 성적 조회 리스트로 돌아가기.
		$(".btnBack").click(function()
		{
			$(location).attr("href", "gradelist.action")
		});
		
		// 모든 입력값을 제대로 입력했는지에 대한 처리.
		$("#btnCheck").click(function()
		{
			//*******************************************************
			// formCheck() == true  : 모든 입력 값 제대로 입력.
			// formCheck() == false : 입력 값이 제대로 입력되지 않음. 
			//*******************************************************
			if (formCheck())
			{
				gradeInsertForm.submit();
			}
			
		});
	});
	
	function formCheck()
	{
		// 테스트
		//alert($("#sub1").val());
		
		var sub1 = $("#sub1").val(); 
		var sub2 = $("#sub2").val();
		var sub3 = $("#sub3").val();
		
		var msg = "";
		
		$(".err").css("display", "none");
		
		//******************************************************
		// 과목 성적 입력 값이 숫자 형태가 아닐 경우 → true
		// 과목 성적 입력 값이 숫자 형태일 경우      → false
		//******************************************************
		//→ alert(isNaN(sub1));
		
		//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
		// [SUB1]
		//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
		// ⓐ 과목의 성적 점수가 지정된 값을 초과할 경우
		if (parseInt(sub1) > 100 || parseInt(sub1) < 0)
		{
			//alert("입력하신 과목1의 성적 점수가 0부터 100까지의 범위 안에 속하지 않습니다.");
			msg = "입력하신 과목1의 성적 점수가 0부터 100까지의 범위 안에 속하지 않습니다.";
			
			$("#errMsg1").css("display", "inline");
			$("#errMsg1").html(msg);
			$("#sub1").val("");
			$("#sub1").focus();
			return false;
		}
		// ⓑ 성적 점수를 입력하지 않았을 경우 
		if (sub1=="" || sub1==null)
		{
			//alert("첫 번째 과목의 성적이 입력되지 않았습니다.");
			msg = "첫 번째 과목의 성적이 입력되지 않았습니다.";
			
			$("#errMsg1").css("display", "inline");
			$("#errMsg1").html(msg);
			$("#sub1").val("");
			$("#sub1").focus();
			return false;
			
		}
		// ⓒ 성적 점수가 숫자 형태가 아닌 문자 형태일 경우
		if (isNaN(sub1))
		{
			
			//alert("첫 번째 과목의 성적 입력값이 숫자 형식의 입력값이 아닙니다.");
			msg = "첫 번째 과목의 성적 입력값이 숫자 형식의 입력값이 아닙니다.";
			
			
			$("#errMsg1").css("display", "inline");
			$("#errMsg1").html(msg);
			$("#sub1").val("");
			$("#sub1").focus();
			return false;
			
		}
		//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
		
		//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
		// [SUB2]
		//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
		// ⓐ 과목의 성적 점수가 지정된 값을 초과할 경우
		if (parseInt(sub2) > 100 || parseInt(sub2) < 0)
		{
			//alert("입력하신 과목2의 성적 점수가 0부터 100까지의 범위 안에 속하지 않습니다.");
			msg = "입력하신 과목2의 성적 점수가 0부터 100까지의 범위 안에 속하지 않습니다.";
			
			$("#errMsg2").css("display", "inline");
			$("#errMsg2").html(msg);
			$("#sub2").val("");
			$("#sub2").focus();
			return false;
		}
		// ⓑ 성적 점수를 입력하지 않았을 경우 
		if (sub2=="" || sub2==null)
		{
			//alert("두 번째 과목의 성적이 입력되지 않았습니다.");
			msg = "두 번째 과목의 성적이 입력되지 않았습니다.";
			
			$("#errMsg2").css("display", "inline");
			$("#errMsg2").html(msg);
			$("#sub2").val("");
			$("#sub2").focus();
			return false;
			
		}
		// ⓒ 성적 점수가 숫자 형태가 아닌 문자 형태일 경우
		if (isNaN(sub2))
		{
			//alert("두 번째 과목의 성적 입력값이 숫자 형식의 입력값이 아닙니다.");
			msg = "두 번째 과목의 성적 입력값이 숫자 형식의 입력값이 아닙니다.";
			
			$("#errMsg2").css("display", "inline");
			$("#errMsg2").html(msg);
			$("#sub2").val("");
			$("#sub2").focus();
			return false;
			
		}
		//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
		
		//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
		// [SUB3]
		//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
		// ⓐ 과목의 성적 점수가 지정된 값을 초과할 경우
		if (parseInt(sub3) > 100 || parseInt(sub3) < 0)
		{
			//alert("입력하신 과목3의 성적 점수가 0부터 100까지의 범위 안에 속하지 않습니다.");
			msg = "입력하신 과목3의 성적 점수가 0부터 100까지의 범위 안에 속하지 않습니다.";
			
			$("#errMsg3").css("display", "inline");
			$("#errMsg3").html(msg);
			$("#sub3").val("");
			$("#sub3").focus();
			return false;
		}
		// ⓑ 성적 점수를 입력하지 않았을 경우 
		if (sub3=="" || sub3==null)
		{
			//alert("세 번째 과목의 성적이 입력되지 않았습니다.");
			msg = "세 번째 과목의 성적이 입력되지 않았습니다.";
			
			$("#errMsg3").css("display", "inline");
			$("#errMsg3").html(msg);
			$("#sub3").val("");
			$("#sub3").focus();
			return false;
			
		}
		// ⓒ 성적 점수가 숫자 형태가 아닌 문자 형태일 경우
		if (isNaN(sub3))
		{
			//alert("세 번째 과목의 성적 입력값이 숫자 형식의 입력값이 아닙니다.");
			msg = "세 번째 과목의 성적 입력값이 숫자 형식의 입력값이 아닙니다.";
			
			$("#errMsg3").css("display", "inline");
			$("#errMsg3").html(msg);
			$("#sub3").val("");
			$("#sub3").focus();
			return false;
			
		}
		//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
		
		return true;
		
	}

</script>

</head>
<body>

<div>
	<h1>성적 데이터 입력</h1>
	<hr>
</div>

<div class="container">
	<div class="panel-group">
		<div class="panel panel-default">
		
			<div class="panel-heading">
				성적 정보 입력
			</div>
		
			<div class="panel-body">
				<form role="form" action="gradeinsert.action?sid=${sid }" method="post" name="gradeInsertForm">
					
					<div class="form-group">
						<label for="sid">
						번호(자동지정) :
						</label>
						<input type="text" class="form-control" id="sid" name="sid" disabled="disabled"
						value="${sid }">
					</div>
					
					<div class="form-group">
						<label for="sub1">
						과목1 :
						</label>
						<input type="text" class="form-control" id="sub1" name="sub1">
						<span id="errMsg1" class="err"></span>
					</div>
					<div class="form-group">
						<label for="sub2">
						과목2 :
						</label>
						<input type="text" class="form-control" id="sub2" name="sub2">
						<span id="errMsg2" class="err"></span>
					</div>
					<div class="form-group">
						<label for="sub3">
						과목3 :
						</label>
						<input type="text" class="form-control" id="sub3" name="sub3">
						<span id="errMsg3" class="err"></span>
					</div>
					
					<button type="button" class="btn btn-default" id="btnCheck">입력 완료</button>
					<button type="reset" class="btn btn-default btnCancel">취소</button>
					<button type="button" class="btn btn-default btnBack">성적 리스트 페이지로</button>
					
				</form>
			</div><!-- end panel-body -->
		
		</div><!-- end panel panel-defalut -->

	</div><!-- panel-group -->
	
</div>

</body>
</html>

GradeUpdateForm.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>StudentList.jsp</title>
<!-- 기본 CSS -->
<link rel="stylesheet" type="text/css" href="<%=cp %>/css/main.css">

<!-- 부트스트랩 적용 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">

<!-- 부트스트랩 부가 테마 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">

<!-- 제이쿼리 적용 JS -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<!-- 부트스트랩 관련 스크립트 적용 JS -->
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

<style type="text/css">
	td {text-align: center;}
	th {text-align: center;}
	.panel-heading {text-align: center;}
	.err {display: none; font-weight: bold; font-size: small; color: red;}
</style>

<script type="text/javascript">
	

$(document).ready(function()
{
	// 성적 조회 리스트로 돌아가기.
	$(".btnBack").click(function()
	{
		$(location).attr("href", "gradelist.action")
	});
	
	// 모든 입력값을 제대로 입력했는지에 대한 처리.
	$("#btnCheck").click(function()
	{
		//*******************************************************
		// formCheck() == true  : 모든 입력 값 제대로 입력.
		// formCheck() == false : 입력 값이 제대로 입력되지 않음. 
		//*******************************************************
		if (formCheck())
		{
			gradeUpdateForm.submit();
		}
		
	});
});

function formCheck()
{
	// 테스트
	//alert($("#sub1").val());
	
	var sub1 = $("#sub1").val(); 
	var sub2 = $("#sub2").val();
	var sub3 = $("#sub3").val();
	
	var msg = "";
	
	$(".err").css("display", "none");
	
	//******************************************************
	// 과목 성적 입력 값이 숫자 형태가 아닐 경우 → true
	// 과목 성적 입력 값이 숫자 형태일 경우      → false
	//******************************************************
	//→ alert(isNaN(sub1));
	
	//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
	// [SUB1]
	//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
	// ⓐ 과목의 성적 점수가 지정된 값을 초과할 경우
	if (parseInt(sub1) > 100 || parseInt(sub1) < 0)
	{
		//alert("입력하신 과목1의 성적 점수가 0부터 100까지의 범위 안에 속하지 않습니다.");
		msg = "입력하신 과목1의 성적 점수가 0부터 100까지의 범위 안에 속하지 않습니다.";
		
		$("#errMsg1").css("display", "inline");
		$("#errMsg1").html(msg);
		$("#sub1").val("");
		$("#sub1").focus();
		return false;
	}
	// ⓑ 성적 점수를 입력하지 않았을 경우 
	if (sub1=="" || sub1==null)
	{
		//alert("첫 번째 과목의 성적이 입력되지 않았습니다.");
		msg = "첫 번째 과목의 성적이 입력되지 않았습니다.";
		
		$("#errMsg1").css("display", "inline");
		$("#errMsg1").html(msg);
		$("#sub1").val("");
		$("#sub1").focus();
		return false;
		
	}
	// ⓒ 성적 점수가 숫자 형태가 아닌 문자 형태일 경우
	if (isNaN(sub1))
	{
		
		//alert("첫 번째 과목의 성적 입력값이 숫자 형식의 입력값이 아닙니다.");
		msg = "첫 번째 과목의 성적 입력값이 숫자 형식의 입력값이 아닙니다.";
		
		
		$("#errMsg1").css("display", "inline");
		$("#errMsg1").html(msg);
		$("#sub1").val("");
		$("#sub1").focus();
		return false;
		
	}
	//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
	
	//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
	// [SUB2]
	//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
	// ⓐ 과목의 성적 점수가 지정된 값을 초과할 경우
	if (parseInt(sub2) > 100 || parseInt(sub2) < 0)
	{
		//alert("입력하신 과목2의 성적 점수가 0부터 100까지의 범위 안에 속하지 않습니다.");
		msg = "입력하신 과목2의 성적 점수가 0부터 100까지의 범위 안에 속하지 않습니다.";
		
		$("#errMsg2").css("display", "inline");
		$("#errMsg2").html(msg);
		$("#sub2").val("");
		$("#sub2").focus();
		return false;
	}
	// ⓑ 성적 점수를 입력하지 않았을 경우 
	if (sub2=="" || sub2==null)
	{
		//alert("두 번째 과목의 성적이 입력되지 않았습니다.");
		msg = "두 번째 과목의 성적이 입력되지 않았습니다.";
		
		$("#errMsg2").css("display", "inline");
		$("#errMsg2").html(msg);
		$("#sub2").val("");
		$("#sub2").focus();
		return false;
		
	}
	// ⓒ 성적 점수가 숫자 형태가 아닌 문자 형태일 경우
	if (isNaN(sub2))
	{
		//alert("두 번째 과목의 성적 입력값이 숫자 형식의 입력값이 아닙니다.");
		msg = "두 번째 과목의 성적 입력값이 숫자 형식의 입력값이 아닙니다.";
		
		$("#errMsg2").css("display", "inline");
		$("#errMsg2").html(msg);
		$("#sub2").val("");
		$("#sub2").focus();
		return false;
		
	}
	//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
	
	//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
	// [SUB3]
	//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
	// ⓐ 과목의 성적 점수가 지정된 값을 초과할 경우
	if (parseInt(sub3) > 100 || parseInt(sub3) < 0)
	{
		//alert("입력하신 과목3의 성적 점수가 0부터 100까지의 범위 안에 속하지 않습니다.");
		msg = "입력하신 과목3의 성적 점수가 0부터 100까지의 범위 안에 속하지 않습니다.";
		
		$("#errMsg3").css("display", "inline");
		$("#errMsg3").html(msg);
		$("#sub3").val("");
		$("#sub3").focus();
		return false;
	}
	// ⓑ 성적 점수를 입력하지 않았을 경우 
	if (sub3=="" || sub3==null)
	{
		//alert("세 번째 과목의 성적이 입력되지 않았습니다.");
		msg = "세 번째 과목의 성적이 입력되지 않았습니다.";
		
		$("#errMsg3").css("display", "inline");
		$("#errMsg3").html(msg);
		$("#sub3").val("");
		$("#sub3").focus();
		return false;
		
	}
	// ⓒ 성적 점수가 숫자 형태가 아닌 문자 형태일 경우
	if (isNaN(sub3))
	{
		//alert("세 번째 과목의 성적 입력값이 숫자 형식의 입력값이 아닙니다.");
		msg = "세 번째 과목의 성적 입력값이 숫자 형식의 입력값이 아닙니다.";
		
		$("#errMsg3").css("display", "inline");
		$("#errMsg3").html(msg);
		$("#sub3").val("");
		$("#sub3").focus();
		return false;
		
	}
	//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
	
	return true;
	
}

</script>

</head>
<body>

<div>
	<h1>성적 데이터 입력</h1>
	<hr>
</div>

<div class="container">
	<div class="panel-group">
		<div class="panel panel-default">
		
			<div class="panel-heading">
				성적 정보 수정
			</div>
		
			<div class="panel-body">
				<form role="form" action="gradeupdate.action?sid=${grade.sid }" method="post" name="gradeUpdateForm">
					
					<div class="form-group">
						<label for="sid">
						번호 :
						</label>
						<input type="text" class="form-control" id="sid" name="sid" disabled="disabled"
						value="${grade.sid }">
					</div>
					
					<div class="form-group">
						<label for="sub1">
						과목1 :
						</label>
						<input type="text" class="form-control" id="sub1" name="sub1"
						value="${grade.sub1 }">
						<span id="errMsg1" class="err"></span>
					</div>
					<div class="form-group">
						<label for="sub2">
						과목2 :
						</label>
						<input type="text" class="form-control" id="sub2" name="sub2"
						value="${grade.sub2 }">
						<span id="errMsg2" class="err"></span>
					</div>
					<div class="form-group">
						<label for="sub3">
						과목3 :
						</label>
						<input type="text" class="form-control" id="sub3" name="sub3"
						value="${grade.sub3 }">
						<span id="errMsg3" class="err"></span>
					</div>
					
					<button type="button" class="btn btn-default" id="btnCheck">입력 완료</button>
					<button type="reset" class="btn btn-default btnCancel">취소</button>
					<button type="button" class="btn btn-default btnBack">성적 리스트 페이지로</button>
					
				</form>
			</div><!-- end panel-body -->
		
		</div><!-- end panel panel-defalut -->

	</div><!-- panel-group -->
	
</div>

</body>
</html>

GradeError.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>GradeInsertError.jsp</title>
<link rel="stylesheet" type="text/css" href="<%=cp %>/css/main.css">

<style type="text/css">
	
	#errMsg		{ color: red; font-size: 20px; text-align: center; font-weight: bolder;}
	
</style>

<!-- 부트스트랩 적용 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">

<!-- 부트스트랩 부가 테마 CSS -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">

<!-- 제이쿼리 적용 JS -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<!-- 부트스트랩 관련 스크립트 적용 JS -->
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

<script type="text/javascript">

	$(document).ready(function()
	{
		$(".btnBack").click(function()
		{
			// 테스트
			//alert("뒤로가기 확인~!!!");
			
			$(location).attr("href", "gradelist.action");
			//--> 성적 조회 리스트 페이지로 돌아가기
			
		});
		
		$(".btnUpdate").click(function()
		{
			// 테스트
			//alert("성적 업데이트 확인~!!!");
			
			$(location).attr("href", "gradeupdateform.action?sid=${sid }");
			//--> 성적 수정 폼 페이지로, 해당 학생의 번호(SID)를 갖고 이동.
			
		});
		
	});

</script>

</head>
<body>
<div>
	<h1>성적 데이터 에러</h1>
	<hr />
</div>

<div class="container">
	<div class="panel-group">
		<div class="panel panel-default">
			<div class="panel-heading">
				
				<!-- [에러 발생 상황에 따른 분류]=========================================-->
				<!-- 
					 ① 성적 데이터가 이미 존재하는데도 INSERT 요청시
					    → TBL_GRADE 에서의 PRIMARY KEY (SID) 중복되어 에러. (unique 만족Ⅹ)
					    
					 ② 성적 데이터가 존재하지 않는 상황에서 수정 요청시
					    → TBL_GRADE 에 존재하지 않는 레코드를 수정하려 하기 때문에 에러.
				
					 ③ 성적 데이터가 존재하지 않는 상황에서 삭제 요청시
					    → TBL_GRADE 에 존재하지 않는 레코드를 삭제하려 하기 때문에 에러.
				
				===========================================================================-->
				
				<span id="errMsg">
					${errMsg }
				</span>
			</div>
		</div>
	</div>
	<div>
		<button type="button" class="btn btn-default btnBack">성적 리스트 페이지로</button>
	</div>
</div>

</body>
</html>