06일차_회원관리2차, 성적관리2차
---------------------------------------------
회원관리 JSP(JDBC) 프로그램(2)
-> 데이터베이스 액션 처리 과정을 별도의 클래스로 작성. JSP 페이지는 화면 출력 액션만 작성.
1. 기능 구현
- 이름, 전화번호 입력 받아서 데이터베이스 저장
- 이름, 전화번호를 데이터베이스에서 읽어내서 화면에 출력
2. 데이터베이스 준비
--테이블 생성
CREATE TABLE memberList (
mid NUMBER --PK
,name VARCHAR2(30)
,telephone VARCHAR2(30)
);
--제약 조건 추가
ALTER TABLE 테이블이름
ADD CONSTRAINT 제약이름 제약종류(제약대상);
ALTER TABLE 테이블이름
DROP CONSTRAINT 제약이름;
ALTER TABLE memberList
ADD CONSTRAINT memberList_mid_pk PRIMARY KEY(mid);
CREATE SEQUENCE memberListSeq;
--입력 샘플 쿼리 (프로그램에서 사용 예정)
INSERT INTO memberList (mid, name, telephone) VALUES (memberListSeq.nextval, 'kim', '010-123-1234');
COMMIT;
--권장하지 않는 표현. 컬럼 리스트에서 * 사용하지 않는다.
SELECT * FROM memberList;
--전체 명단 출력 쿼리 (프로그램에서 사용 예정)
--권장하는 표현
SELECT mid, name, telephone FROM memberList ORDER BY mid;
--인원수 출력 쿼리 (프로그램에서 사용 예정)
--함수 사용시 반드시 별칭 사용.
SELECT COUNT(mid) AS count FROM memberList;
3. 화면 구성
-----------------------------------------------------------
[회원 관리]
이름 : hong -> <input type="text">
전화 : 010-123-1234 -> <input type="text">
회원추가버튼 -> <input type="submit">
전체 인원수 : 2명 -> <p> ... </p>
---------------------------- -> <table>...</table>
번호 이름 전화
1 hong 010-123-1234
2 kim 010-222-2222
----------------------------
4. 프로그램 구성
//DBConn.java
//Member.java -> 자료형 클래스
//MemberDAO.java -> 데이터베이스 액션 클래스
//MemberMain.jsp -> JSP 페이지. 입력 폼, 출력 폼 페이지. 실행 페이지.
//MemberInsert.jsp -> JSP 페이지. 액션 전용 페이지.
//요청주소
http://localhost:8090/프로젝트이름/MemberMain.jsp
5. 프로그램 소스 코드
//Member.java
package com.test;
//자료형 클래스
public class Member {
//멤버변수, getter, setter 등록
private String mid, name, telephone;
public String getMid() {
return mid;
}
public void setMid(String mid) {
this.mid = mid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
}
//MemberDAO.java
package com.test;
import java.sql.*;
import java.util.*;
//데이터베이스 액션 클래스
public class MemberDAO {
public int count() {
int result = 0;
Connection conn = null;
Statement stmt = null;
try {
conn = DBConn.getConnection();
stmt = conn.createStatement();
String sql = String.format("SELECT COUNT(*) AS \"count\" FROM memberList");
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()) {
result = rs.getInt("count");
}
rs.close();
}catch(Exception e){
e.printStackTrace();
}finally{
try {
if (stmt != null) {
stmt.close();
}
}catch(Exception e){
}
DBConn.close();
}
return result;
}
public ArrayList<Member> list() {
ArrayList<Member> result = new ArrayList<Member>();
Connection conn = null;
Statement stmt = null;
try {
conn = DBConn.getConnection();
stmt = conn.createStatement();
String sql = "SELECT mid, name, telephone FROM memberList ORDER BY mid";
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()) {
String mid = rs.getString("mid");
String name = rs.getString("name");
String telephone = rs.getString("telephone");
Member member = new Member();
member.setMid(mid);
member.setName(name);
member.setTelephone(telephone);
result.add(member);
}
rs.close();
}catch(Exception e){
e.printStackTrace();
}finally{
try {
if (stmt != null) {
stmt.close();
}
}catch(Exception e){
}
DBConn.close();
}
return result;
}
public int add(Member member) {
int result = 0;
Connection conn = null;
Statement stmt = null;
try {
conn = DBConn.getConnection();
stmt = conn.createStatement();
String sql = String.format("INSERT INTO memberList (mid, name, telephone) VALUES (memberListSeq.nextval, '%s', '%s')"
, member.getName(), member.getTelephone());
result = stmt.executeUpdate(sql);
}catch(Exception e){
e.printStackTrace();
}finally{
try {
if (stmt != null) {
stmt.close();
}
}catch(Exception e){
}
DBConn.close();
}
return result;
}
}
//MemberMain.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.test.*" %>
<%
StringBuilder sb = new StringBuilder(); //명단 출력용 임시 변수
int count = 0; //인원수 출력용 임시 변수
MemberDAO dao = new MemberDAO();
count = dao.count();
for (Member m : dao.list()) {
sb.append(String.format("<tr>\r\n"));
sb.append(String.format("<td>%s</td>", m.getMid()));
sb.append(String.format("<td>%s</td>", m.getName()));
sb.append(String.format("<td>%s</td>", (m.getTelephone()==null)?"전화번호 없음":m.getTelephone() ));
sb.append(String.format("</tr>\r\n"));
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="TableStyle.css">
<link rel="stylesheet" type="text/css" href="DivStyle.css">
<script type="text/javascript">
window.onload=function() {
var myForm = document.getElementById("myForm");
var name = document.getElementById("name");
var telephone = document.getElementById("telephone");
var errorMsg = document.getElementById("errorMsg");
document.getElementById("myForm").onsubmit=function(){
//서브밋 액션을 계속 하거나(return true;), 중단(return false;)하는 것을 선택할 수 있다.
if(name.value == ""){
errorMsg.innerHTML = "이름을 입력하시오.";
return false;
}
if(name.value.length > 30){
errorMsg.innerHTML = "이름을 30자 이내로 입력하시오.";
return false;
}
if(telephone.value.length > 30){
errorMsg.innerHTML = "전화번호를 30자 이내로 입력하시오.";
return false;
}
return true;
};
};
</script>
</head>
<body>
<div>
<h1>회원 관리</h1>
<h2>[입력]</h2>
<form action="MemberInsert.jsp" method="post" id="myForm">
이름(30자 이내)* <input type="text" name="name" id="name">
전화번호(30자 이내) <input type="text" name="telephone" id="telephone">
<input type="submit" value="회원 추가">
<span id="errorMsg" style="color:red;"></span>
</form>
<h2>[출력]</h2>
<!-- <p>인원수 : 1 명</p> -->
<p>인원수 : <%=count%> 명</p>
<table id="t01">
<tr>
<th>번호</th><th>이름</th><th>전화번호</th>
</tr>
<!--
<tr>
<td>1</td><td>hong</td><td>010-123-1234</td>
</tr>
-->
<%=sb.toString()%>
</table>
</div>
</body>
</html>
//MemberInsert.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%-- 액션 전용 페이지 - HTML 코드 삭제, 강제 페이지 전환, 직접 실행 X --%>
<%@ page import="com.test.*"%>
<%
//데이터 수신(한글 인코딩 추가)
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String telephone = request.getParameter("telephone");
//데이터베이스 액션-> MemberDAO 클래스 담당
MemberDAO dao = new MemberDAO();
Member m = new Member();
m.setName(name);
m.setTelephone(telephone);
dao.add(m);
//강제 페이지 전환
response.sendRedirect("MemberMain.jsp");
%>
----------------------------------------------
성적관리 JSP(JDBC) 프로그램(2)
-> 데이터베이스 액션 처리 과정을 별도의 클래스로 작성. JSP 페이지는 화면 출력 액션만 작성.
1. 기능 구현
- 학생 테이블에는 학생의 개인 정보(번호, 학생 이름, 전화번호)가 저장된다.
- 성적 테이블에는 학생의 성적 정보(번호, 과목1, 과목2, 과목3)가 저장된다.
- 번호 항목은 학생 테이블의 PK, 성적 테이블의 PK&FK로 지정한다.
- 학생 출력시 번호, 학생 이름, 전화번호, 성적 입력 여부가 출력된다.
- 학생 입력은 학생 이름, 전화번호를 입력한다.
- 성적 출력시 번호, 학생이름, 과목1, 과목2, 과목3, 총점, 평균, 판정 점수가 출력한다.
- 판정 기준은 합격, 과락, 불합격으로 구분한다.
- 성적 입력이 안된 학생인 경우는 번호, 학생 이름만 출력하고 점수는 null 문자 또는 X 문자로 출력한다.
- 성적 입력은 학생 개개인별로 과목1, 과목2, 과목3 점수를 입력한다.
2. 화면 구성
---------------------------------------------------
학생명단버튼 성적출력버튼
--- 학생 명단 ---
학생추가버튼
전체 학생 수 : 2명
-----------------------------------------
번호, 학생 이름, 전화번호, 성적 입력 여부
-----------------------------------------
1, kim, 010-111-1111, O
2, park, 010-222-2222, X
---------------------------------------------------
학생명단버튼 성적출력버튼
--- 학생 추가 ---
이름 [ ]
전화번호 [ ]
학생추가버튼
---------------------------------------------------
학생명단버튼 성적출력버튼
--- 성적 출력 ---
전체 학생 수 : 2명
-----------------------------------------
번호, 학생이름, 과목1, 과목2, 과목3, 총점, 평균, 판정
-----------------------------------------
1, kim, 100, 100, 100, 300, 100.0, 합격 성적추가버튼(비활성)
2, choi, X, X, X, X, X, 불합격 성적추가버튼(활성)
---------------------------------------------------
학생명단버튼 성적출력버튼
--성적 추가--
번호* [3 ] readonly
학생이름* [choi ] readonly
과목1(0~100) [ ]
과목2(0~100) [ ]
과목3(0~100) [ ]
성적추가버튼
3. 데이터베이스 준비
-- 학생 테이블 생성
CREATE TABLE student (
sid NUMBER --PK
,name VARCHAR2(30) -->NVARCHAR2(30)
,tel VARCHAR2(30)
);
--PK 제약 추가
ALTER TABLE student
ADD CONSTRAINT student_sid_pk PRIMARY KEY(sid);
--방법1
--일련번호 생성을 위한 시퀀스 객체 생성
CREATE SEQUENCE studentSeq;
--INSERT 쿼리 샘플 (프로그램 사용 예정)
INSERT INTO student (sid, name, tel)
VALUES (studentSeq.nextval, 'kim', '010-111-1111');
INSERT INTO student (sid, name, tel)
VALUES (studentSeq.nextval, 'park', '010-222-2222');
--방법2
INSERT INTO student (sid, name, tel)
VALUES ((SELECT NVL(MAX(sid),0)+1 FROM student), '김길동', '010-111-1111');
INSERT INTO student (sid, name, tel)
VALUES ((SELECT NVL(MAX(sid),0)+1 FROM student), '박길동', '010-222-2222');
COMMIT;
--학생 명단 출력
SELECT sid, name, tel
FROM student
ORDER BY sid;
--성적 테이블 생성
CREATE TABLE grade (
sid NUMBER --PK and FK
,sub1 NUMBER(3) --CHECK 제약 추가
,sub2 NUMBER(3) --CHECK 제약 추가
,sub3 NUMBER(3) --CHECK 제약 추가
);
--제약 추가
ALTER TABLE grade
ADD (CONSTRAINT grade_sid_pk PRIMARY KEY(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));
ALTER TABLE grade
ADD CONSTRAINT grade_sid_fk FOREIGN KEY (sid)
REFERENCES student(sid);
SELECT *
FROM constraint_check
WHERE table_name='GRADE';
--INSERT 쿼리 샘플 (프로그램에서 사용 예정)
INSERT INTO grade (sid, sub1, sub2, sub3)
VALUES (1, 100, 100, 100); --O
COMMIT;
--학생 테이블의 자료 2명으로 만들 것.
SELECT * FROM student;
--성적 테이블의 자료 1명으로 만들 것.
SELECT * FROM grade;
--학생수 출력 쿼리
SELECT COUNT(*) AS count FROM student;
--학생 전체 명단 출력 쿼리 (프로그램에서 사용 예정)
--번호, 학생 이름, 전화번호, 성적 입력 여부(0 또는 1)
--학생 테이블 + 성적 테이블 -> JOIN, SUB QUERY
--방법1
--OUTER JOIN의 경우
SELECT s.sid AS sid, name, tel
, DECODE(sub1, NULL, 0, 1) AS gradeCheck --성적 입력 여부 (1 또는 0)
FROM student s, grade g
WHERE s.sid = g.sid(+);
--방법2
SELECT sid, name, tel
, (SELECT COUNT(*) FROM grade WHERE sid=s.sid) AS gradeCheck --성적 입력 여부 (1 또는 0)
FROM student s
ORDER BY sid;
-->뷰(View)로 등록하는 것을 권장
CREATE OR REPLACE VIEW studentView
AS
SELECT sid, name, tel
, (SELECT COUNT(*) FROM grade WHERE sid=s.sid) AS gradeCheck
FROM student s
ORDER BY sid;
-->뷰를 이용한 학생 전체 명단 출력 쿼리
SELECT sid, name, tel, gradeCheck
FROM studentView;
--학생 검색 쿼리(성적 입력 전에 학생 정보 검색 과정에서 사용. 프로그램에서 사용 예정)
SELECT sid, name, tel, gradeCheck
FROM studentView
WHERE sid=1;
--성적 출력 쿼리 (프로그램에서 사용 예정)
--번호, 학생이름, 과목1, 과목2, 과목3, 총점, 평균, 판정(0 합격, 1 과락, 2 불합격)
--학생 테이블->번호, 학생이름
--성적 테이블->과목1, 과목2, 과목3
--총점, 평균, 판정 -> 계산 결과
--학생 테이블 + 성적 테이블 -> JOIN, SUB QUERY
주의) 오라클에서 NULL 데이터는 자바에서는 String 자료형인 경우에만 처리 가능.
NUMBER -> int -> 숫자 서식 지정 가능
VARCHAR2 -> String -> 문자열 서식 지정 가능
NUMBER + NULL -> String -> NULL이 아닌 경우에만 Integer.parseInt(String) 가능
VARCHAR2 + NULL -> String
--OUTER JOIN의 경우
SELECT sid, name, sub1, sub2, sub3, tot, ave
, ( CASE
WHEN ave>=60 AND sub1>=40 AND sub2>=40 AND sub3>=40 THEN 0 --합격
WHEN ave>=60 THEN 1 --과락
ELSE 2 --불합격
END ) AS ch
FROM (SELECT s.sid AS sid, name, sub1, sub2, sub3
, (sub1 + sub2 + sub3) AS tot
, ( (sub1 + sub2 + sub3) / 3 ) AS ave
FROM student s, grade g
WHERE s.sid = g.sid(+));
--> 뷰(View) 등록
CREATE OR REPLACE VIEW gradeView
AS
SELECT sid, name, sub1, sub2, sub3, tot, ave
, ( CASE
WHEN ave>=60 AND sub1>=40 AND sub2>=40 AND sub3>=40 THEN 0 --합격
WHEN ave>=60 THEN 1 --과락
ELSE 2 --불합격
END ) AS ch
FROM (SELECT s.sid AS sid, name, sub1, sub2, sub3
, (sub1 + sub2 + sub3) AS tot
, ( (sub1 + sub2 + sub3) / 3 ) AS ave
FROM student s, grade g
WHERE s.sid = g.sid(+));
--> 뷰를 이용한 성적 출력
SELECT sid, name, sub1, sub2, sub3, tot, ave
, ch --판정(0, 1, 2)
FROM gradeView
ORDER BY sid;
-----------------------------------------------
학생 테이블에서 이름 저장용 컬럼의 자료형을 수정. 한글 자료 저장.
VARCHAR2(30) -> NVARCHAR2(30)
ALTER TABLE student
MODIFY (name NVARCHAR2(30));
DESC student;
4. 프로그램 구성
//DBConn.java
//Student.java -> 자료형 클래스
//Grade.java -> 자료형 클래스
//StudentDAO.java -> 데이터베이스 액션 클래스
//GradeDAO.java -> 데이터베이스 액션 클래스
//StudentMain.jsp -> 학생 명단 출력 페이지. 실행 페이지.
//StudentInsertForm.jsp -> 학생 입력 폼 페이지.
//StudentInsert.jsp -> 학생 입력 액션 페이지. 액션 전용 페이지.
//GradeMain.jsp -> 성적 출력 페이지. 실행 페이지
//GradeInsertForm.jsp -> 성적 입력 폼 페이지.
//GradeInsert.jsp -> 성적 입력 액션 페이지. 액션 전용 페이지.
//TableStyle.css -> 스타일 페이지.
//DivStyle.css -> 스타일 페이지.
//요청주소
http://localhost:8090/프로젝트이름/StudentMain.jsp
5. 프로그램 소스 코드
//StudentMain.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.test.*" %>
<%
//학생 명단 결과 저장용 임시 변수
StringBuilder sb = new StringBuilder();
//인원수 저장용 임시 변수
int count = 0;
StudentDAO dao = new StudentDAO();
count = dao.count();
for (Student s : dao.list()) {
sb.append(String.format("<tr>\r\n"));
sb.append(String.format("<td>%s</td>", s.getSid()));
sb.append(String.format("<td>%s</td>", s.getName()));
sb.append(String.format("<td>%s</td>", s.getTel()));
sb.append(String.format("<td>%s</td>"
, (s.getGradeCheck()==0)?"X":"O" ));
sb.append(String.format("</tr>\r\n"));
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>성적관리</title>
<link rel="stylesheet" type="text/css" href="TableStyle.css">
<link rel="stylesheet" type="text/css" href="DivStyle.css">
</head>
<body>
<div>
<!-- 메인 메뉴 영역 -->
<div class="title">
<h1>성적관리 (JSP버전)</h1>
<p>
[<a href="StudentMain.jsp">학생관리</a>]
[<a href="GradeMain.jsp">성적관리</a>]
</p>
</div>
<!-- 콘텐츠 영역 -->
<div class="main">
<h2>학생 출력</h2>
<form><input type="button" value="학생 추가" onclick="location.href='StudentInsertForm.jsp'"></form>
<!-- <p>전체 학생수 : 1 명 </p> -->
<p>전체 학생수 : <%=count%> 명 </p>
<table id="t01">
<tr>
<th>번호</th><th>이름</th>
<th>전화번호</th><th>성적입력여부</th>
</tr>
<!--
<tr>
<td>1</td><td>홍길동</td>
<td>010-123-1234</td><td>X</td>
</tr>
-->
<%=sb.toString()%>
</table>
</div>
</div>
</body>
</html>
---------------------------------------------------