[JAVA] JDK 실습 (3)
중복 코드 검사 실습
DB 테이블 관리
- cmd > sqlplus system/****(비밀번호)
아래 6개의 테이블을 생성한다.
- login
- test
- board
- boardreply(+시퀀스)
- bbs(+시퀀스)
- bbsreply(+시퀀스)
login 테이블을 생성하고 데이터를 삽입한다.
drop table login ;
create table login(
userid varchar2(10) primary key ,
pwd varchar2(10) not null
);
commit ;
insert into login values('sky', '1234') ;
insert into login values('blue', '1234') ;
commit ;
시퀀스를 생성한다.
drop sequence board_seq;
create sequence board_seq;
그 다음 board 테이블을 생성하던 중 에러가 발생했다.
//에러 발생
drop table board ;
create table board (
bnum number(4) primary key ,
code number(4) primary key
);
아래 두 가지 해결방법이 있다.
//해결 방법 (1) - 이게 제일 좋음
drop table board ;
create table board (
bnum number(4) primary key ,
code number(4) unique
);
//해결 방법(2)
drop table board ;
create table board (
bnum number(4) ,
code number(4) ,
constraint board_pk primary key(bnum, code)
) ;
commit;
- unique : 유일한데 null 허용
- primary key : 유일하고 not null
board 테이블에 데이터를 입력한다.
insert into board values( 1100, 75);
insert into board values( 1100, 95); --에러발생(1)
insert into board values( 2200, 75); --에러발생(2)
insert into board values( 2200, 95);
insert into board values( 1100, 95); --에러발생(3)
insert into board values( 3300, 95);
select constraint_name from user_constraints;
alter table board drop constraint board_pk;
commit ;
select constraint_name from user_constraints;
commit ;
에러 발생(1), (2), (3) - unique constraint (SYSTEM.SYS_C007051) violated
=> 유일하지 않은 데이터에 대해서 에러가 발생한다.
bbs 테이블을 생성한다.
drop sequence bbs_seq ;
create sequence bbs_seq ;
drop table bbs;
create table bbs (
b_no number(3) not null, --bbs_seq.nextVal
b_sabun number(4) not null ,
b_name varchar2(15) not null,
b_title varchar2(30) not null,
b_cnt number(5) default 0 ,
b_content varchar2(50) not null,
b_phone varchar2(20) not null,
b_pwd varchar2(10) not null,
b_wdate date not null,
b_juso1 varchar2(100) not null,
b_juso2 varchar2(50) not null,
b_email varchar2(30) not null,
b_url varchar2(20) null,
b_file1 varchar2(30) null,
b_size1 number(7) default 0 ,
primary key(b_sabun)
);
commit ;
bbsreply_seq 테이블을 생성한다.
drop sequence bbsreply_seq ;
create sequence bbsreply_seq ;
drop table bbsreply;
create table bbsreply (
br_num number(4) not null,
br_writer varchar2(10) not null,
br_content varchar2(20)not null,
br_date date not null,
br_sabun number(4) not null
);
commit ;
시퀀스를 추가한다.
--제약조건 create 키워드 대신 alter table 대상 테이블 이름
alter table bbsreply drop constraint bbs_sabun_fk ;
alter table bbsreply add constraint bbs_sabun_fk
foreign key(br_sabun) references bbs(b_sabun) on delete cascade;
commit ;
테이블 크기를 조정하고 예쁘게 출력해본다.
col b_name for a10 ;
col b_title for a10 ;
col b_file1 for a15 ;
select b_no,b_name,b_title, b_file1 from bbs ;
set linesize 200
set pagesize 200
commit ;
select * from bbs ;
지난 실습 때 만든 test 테이블을 초기화 겸 다시 만들어준다.
drop table test ;
create table test (
title varchar2(10) not null ,
pay number(3) not null ,
wdate date not null ,
code number(4) primary key
);
commit ;
insert into test values('snow', 21, sysdate, 7700);
insert into test values('cake', 91, sysdate, 5500);
delete from test ;
commit ;
select * from test ;
col title for a10
JAVA 코드 작성하기
testWrite.jsp - 코드 중복 입력 체크하기
데이터 입력 검증 함수를 작성한다.
<script type="text/javascript">
Gflag = false; // 코드 중복체크 여부 판단
function nullCheck(){
dcode = document.myform.code.value;
dtitle = document.myform.title.value;
dpay = document.myform.pay.value;
if(dcode==null || dcode==""){
alert("code데이터 공백입니다");
myform.code.focus();
return false;
}else{myform.title.focus();}
if(dtitle==null || dtitle==""){
alert("title데이터 공백입니다");
myform.title.focus();
return false;
}else{myform.pay.focus();}
if(dpay==null || dpay==""){
alert("pay데이터 공백입니다");
myform.pay.focus();
return false;
}
중복체크 검증을 한다.
if(Gflag==false){
alert("아이디=코드 중복체크를 하셔야 합니다.");
}else if(Gflag==true){ document.myform.submit();}
}//function nullCheck() end
코드 중복 체크를 하는 함수를 작성한다.
function codeCheck(){
dcode = document.myform.code.value;
if(dcode==null || dcode==""){
alert("중복코드체크 code데이터 공백입니다");
myform.code.focus();
return false;
}
Gflag=true;
window.open("openID.jsp?idx="+dcode, "bb", "width=500,height=150,left=550,top=200");
}// function codeCheck() end
</script>
- open("./openID.jsp?idx="+dcode, "bb", "width=500, height=130, left=550, top=200")
- 부모창에서 자식 팝업창을 새로 오픈하는 메소드
- openID.jsp 를 자식창으로 오픈하는데, idx 파라미터에 dcode라는 값을 전달하겠다.
- window.open(url, name, specs, replace);
- name 기본값
- _blank : 기본값으로, 새 창에 열린다
- _parent : 부모 프레임에 열린다
- _self : 현재 페이지를 대체한다.
- _top : 로드 된 프레임셋을 대체한다.
- _name(임의의 이름) : 새 창이 열리고, 창의 이름을 지정한다. 동일한 이름에 다시 open() 하면 기존의 열린 창의 내용이 바뀐다. 다른 이름을 사용하면 또 다른 새 창이 열린다.
- specs : 선택적인 값으로 창의 크기, 스크롤 여부, 리사이즈 가능 등의 속성을 지정
- replace : 히스토리 목록에 새 항목을 만들지 현재 항목을 대체할지 지정 (true:대체/false:새항목 만듦)
- name 기본값
html 형태는 다음과 같다.
<body>
<p/>
<h2>testWrite.jsp</h2>
<form name="myform" method="get" action="testWriteSave.jsp">
코드: <input type="text" name="code" id="code" size="6">
<input type="button" onClick="codeCheck();" value="code중복체크"> <br>
제목: <input type="text" name="title" id="title"> <br>
급여: <input type="text" onkeyup="payNumber();" name="pay" id="pay" > <br>
<input type="button" onClick="nullCheck();" value="데이터저장">
<input type="reset" value="입력취소">
</form>
<p>
<a href="testWrite.jsp">[게시판입력화면]</a>
<a href="testList.jsp">[게시판전체출력]</a>
<a href="index.jsp">[index]</a>
</body>
openID.jsp - 중복 체크 팝업창
<body bgcolor=yellow>
<p/>
<h2>openID.jsp</h2>
<%
String Gdata = request.getParameter("idx");
%>
<div>
<img src="images/bar.gif" width=400><br>
<form name="open_form" method="get" action="openIDSave.jsp">
코드:<input type="text" name="mycode" size="10" value="<%=Gdata%>">
<input type="submit" value="중복처리">
</form>
<img src="images/bar.gif" width=400><br>
</div>
</body>
openSaveID.jsp - 코드 중복 여부 검사
오라클 mySQL에서 특정 코드의 데이터 개수를 알 수 있는 명령어를 응용하자.
select count(*) as cnt from test where code=7700 ;
<body bgcolor="yellow">
<div align="center">
<img src="images/bar.gif" width="350"> <br>
<img src="images/bar.gif" width="350"> <br>
</div>
<%
Gdata = request.getParameter("mycode");
msg = "select count(*) as cnt from test where code = " + Gdata;
ST = CN.createStatement();
RS = ST.executeQuery(msg);
if(RS.next()==true){ Gtotal = RS.getInt("cnt");}
if( Gtotal>0 ){ // 이미 그 코드가 DB에 저장되어 있으면
%>
<script type="text/javascript">
alert("<%=Gdata%> 데이터는 이미 사용중입니다");
//아래 세 줄을 이 한 줄로 요약 가능
//location.href='openID.jsp?idx='+"" ;
opener.myform.code.value="";
opener.myform.code.focus();
self.close();
</script>
<%
} else{
%>
<script type="text/javascript">
alert("<%=Gdata%> 데이터는 사용가능한 사번아이디 입니다");
opener.myform.code.value=<%=Gdata%> ;
opener.myform.title.focus();
self.close();
</script>
<% } %>
</body>
</html>
- opener.myform.code.value = " " - 부모창의 window 객체를 참조
- 부모창의 페이지에 접근할 수 있게 된다.
- 부모창과 자식창에 있는 텍스트 입력란을 서로 접근 가능하다.
testWrite.jsp - '급여' 입력란에 숫자를 제외한 글자를 입력하면 알림창 띄우기
자바스크립트 영역에 payNumber() 함수를 추가한다.
'급여' 입력란에 onkeyup 이벤트 함수 속성을 추가한다.
...
function payNumber(){
//onkeyup="payNumber();"
var dpay = myform.pay.value;
var size = myform.pay.value.length;
for(var i=0; i<size; i++){
if(dpay.charAt(i)<'0' || dpay.charAt(i)>'9'){
alert("정확한 숫자를 입력하세요");
myform.pay.value=dpay.substring(0,i);
myform.pay.focus();
}
}//for end
}//end
...
급여: <input type="text" onkeyup="payNumber();" name="pay" id="pay" > <br>
...
testList.jsp - 전체 데이터 개수 표시하기
총 데이터 개수를 구하는 쿼리문을 작성한다.
<%@ include file="ssi.jsp" %>
<body>
<%
msg = "select count(*) as cnt from test";
ST = CN.createStatement();
RS = ST.executeQuery(msg);
if(RS.next()==true){total=RS.getInt("cnt");}
%>
전달받은 데이터가 존재하면 total 변수에 총 개수를 저장한다.
테이블은 이렇게 생겼다.
<h1>testList.jsp</h1>
<table border="1" width="1000" cellspacing="0">
<tr align="right">
<td colspan="4"> 데이터 개수: <%= total %> <td>
</tr>
<tr bgcolor="plum">
<td>코 드</td> <td>제 목</td> <td>날 짜</td> <td>급 여</td>
</tr>
코드 순서대로 데이터를 가져오는 쿼리문을 작성한다.
<%
msg = "select * from test order by code";
ST = CN.createStatement();
RS = ST.executeQuery(msg);
while(RS.next()==true){
Gtitle = RS.getString("title");
Gpay = RS.getInt("pay");
Gwdate = RS.getDate("wdate");
Gcode = RS.getInt("code");
%>
select 된 데이터가 존재하면 제목, 급여, 날짜, 코드를 가져온 뒤
그대로 테이블을 작성한다.
<tr>
<td> <%= Gcode %> </td>
<td> <a href="testDetail.jsp?idx=<%=Gcode%>"><%= Gtitle %></a></td>
<td> <%= Gwdate %> </td>
<td> <%= Gpay %> </td>
</tr>
<% } %>
</table>
<p>
<a href="testWrite.jsp">[게시판입력화면]</a>
<a href="testList.jsp">[게시판전체출력]</a>
<a href="index.jsp">[index]</a>
<a href="login.jsp">[로그인]</a>
</body>
testDetail.jsp - 데이터 한 건 상세보기 페이지
우선 testList.jsp에 제목을 클릭하면 상세보기 페이지로 이동하는 링크를 걸어줘야 한다.
<style type="text/css">
* { font-size:20pt; }
a { font-size:20pt; text-decoration:none; color:lightcoral; }
a:hover{ font-size:24pt; text-decoration:underline ; color:black; fontweight:bold;}
body{margin-left:20px;}
</style>
<tr>
<td> <%= Gcode %> </td>
<td> <a href="testDetail.jsp?idx=<%=Gcode%>"><%= Gtitle %></a></td>
<td> <%= Gwdate %> </td>
<td> <%= Gpay %> </td>
</tr>
testDetail.jsp에서
<%@ include file="./ssi.jsp" %>
<body>
<%
Gdata = request.getParameter("idx");
msg = "select * from test where code ="+Gdata;
ST = CN.createStatement();
RS = ST.executeQuery(msg);
if(RS.next()==true){
Gtitle = RS.getString("title");
Gpay = RS.getInt("pay");
Gwdate = RS.getDate("wdate");
Gcode = RS.getInt("code");
}
%>
클릭한 게시글 코드와 동일한 데이터를 가져오는 쿼리문을 작성한다.
상세보기 html 형태는 다음과 같다.
<p>
<table width="900" border="1" cellspacing="0" cellpadding="7">
<tr align="center">
<td colspan="2">
testDetail.jsp</br>
</td>
</tr>
<tr>
<td rowspan="4" align="center"> <img src="images/pic6.png" width="500" height="300" > </td>
<td width="400"> 코드: <%= Gcode %> </td>
</tr>
<tr> <td> 제목: <%= Gtitle %> </td> </tr>
<tr> <td> 날짜: <%= RS.getDate("wdate") %> </td> </tr>
<tr> <td> 급여: <%= RS.getInt("pay") %> </td> </tr>
<tr align="center">
<td colspan="2">
<a href="testEdit.jsp?idx=<%=Gcode%>">[수정]</a>
<a href="testWrite.jsp">[등록]</a>
<a href="testDeleteSave.jsp?code=<%=Gcode%>">[삭제]</a>
<a href="index.jsp">[index]</a>
<a href="testList.jsp">[전체출력]</a>
</td>
</tr>
</table>
</body>
testEdit.jsp - 데이터 수정 페이지
<%@page import="javax.print.DocFlavor.STRING"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ include file = "./ssi.jsp" %>
<body>
<h2>testEdit.jsp</h2>
<%
Gdata = request.getParameter("idx");
msg="select * from test where code = "+Gdata;
ST = CN.createStatement();
RS = ST.executeQuery(msg);
if(RS.next()==true){
Gtitle = RS.getString("title");
Gpay = RS.getInt("pay");
Gwdate = RS.getDate("wdate");
Gcode = RS.getInt("code");
}
%>
<form name="myform" method="get" action="testEditSave.jsp">
수정코드: <input type="text" name="code" id="code" value="<%=Gcode%>" readonly><br>
수정제목: <input type="text" name="title" id="title" value="<%=Gtitle%>"> <br>
수정급여: <input type="text" name="pay" id="pay" value="<%=Gpay%>"> <br>
<input type="submit" value="수정">
<input type="reset" value="수정입력취소">
</form>
<p>
<a href="testWrite.jsp">[게시판입력화면]</a>
<a href="testList.jsp">[게시판전체출력]</a>
<a href="index.jsp">[index]</a>
</body>
</html>
testEditSave.jsp - 수정한 데이터를 저장
<%@ include file="./ssi.jsp" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.sql.DriverManager"%>
<%@ page import="java.sql.*"%>
update 쿼리문을 작성하여 수정한 데이터를 DB에 저장한다.
<body>
<p>
<img src="./images/bear.gif">
<h2>testEditSave.jsp</h2>
<%
Gtitle = request.getParameter("title");
Gpay = Integer.parseInt(request.getParameter("pay"));
Gcode = Integer.parseInt(request.getParameter("code"));
System.out.println("수정제목데이터 = " + Gtitle);
System.out.println("수정급여데이터 = " + Gpay);
System.out.println("수정코드데이터 = " + Gcode);
msg = "update test set title='" + Gtitle + "', pay=" + Gpay + ", wdate=sysdate
where code =" + Gcode;
System.out.println(msg);
try{
ST = CN.createStatement();
ST.executeUpdate(msg);
System.out.println(Gcode +"코드 데이터 수정 성공 ");
response.sendRedirect("testList.jsp");
}catch(Exception ex){
response.sendRedirect("testList.jsp");
System.out.println("test테이블 수정 실패 에러 " + ex);
}
%>
</body>
testDetailSave.jsp - 데이터 삭제
<%@ include file="./ssi.jsp" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.sql.DriverManager"%>
<%@ page import="java.sql.*"%>
데이터를 삭제하는 delete 쿼리문을 보내 DB에서 데이터를 삭제한다.
<body>
<p>
<img src="./images/bear.gif">
<h2>testDeleteSave.jsp</h2>
<%
Gdata = Integer.parseInt(request.getParameter("code"));
msg = "delete from test where code=" + Gdata ;
System.out.println(msg);
try{
ST = CN.createStatement();
ST.executeUpdate(msg);
System.out.println(Gcode +"코드 데이터 삭제 성공 ");
response.sendRedirect("testList.jsp");
}catch(Exception ex){
System.out.println("test테이블 삭제 실패 에러 " + ex);
response.sendRedirect("testList.jsp");
}
%>
</body>
수정/삭제 권한 만들기
Session 내장 객체를 사용한다.
└▶ 웹 서버에서 제공되는 내장 객체
└▷ page, out(출력), request(값 전달), response(문서 이동), session(권한), application(자원 접근)
- 수정: 관리자/글쓴이만 수정 가능
- 삭제: 관리자/글쓴이만 삭제 가능
- login.jsp에서 userid/pwd 입력 후 loginSave.jsp에서 세션 권한 처리를 하자.
DB 테이블 추가
cmd 오픈 > login 테이블 생성
drop table login ;
create table login(
userid varchar2(10) primary key ,
pwd varchar2(10) not null
);
commit ;
insert into login values('sky', '1234') ;
insert into login values('blue', '1234') ;
commit ;
JAVA 코드 작성
login.jsp - 로그인 페이지
xhr 객체를 생성하는 함수 first()를 작성한다.
<script type="text/javascript">
var xhr; // 전역 변수
function first(){
return new XMLHttpRequest( );
}
input 태그에 입력받은 아이디/비밀번호를 가져온 뒤
function two(){
var a = document.getElementById("userid").value; // myform.userid.value;와 같음
var b = document.getElementById("pwd").value; // myform.pwd.value;와 같음
xhr = first();
xhr.onreadystatechange = display;
xhr.open("GET", url, true);
xhr.send();
}
first() 함수를 호출해 xhr 객체를 생성하고 GET 메서드 요청을 보낸다.
응답 메세지를 저장한뒤 innerHTML로 삽입한다.
function display(){
if(xhr.readyState==4){
if(xhr.status==200){
var message = xhr.responseText;
document.getElementById("msg").innerHTML = message;
}
}
}
</script>
html 형태는 다음과 같다.
<body>
<div id="msg" align="center">
<table width="550" border="1" cellspacing="0">
<form name="myform" method="post" action="loginSave.jsp">
<tr>
<td width=350> <b>userid: </b></td>
<td> <input type="text" name="userid" id="userid" value=""></td>
<td rowspan=3 align="center">
<input type="submit" value="LOG-IN" id="LOG-IN" >
</td>
</tr>
<tr>
<td width=350><b>userpw: </b> </td>
<td>
<input type="text" name="pwd" id="pwd" value="">
</td>
</tr>
<tr>
<td colspan="2" align="center">
<a href="guestWrite.jsp">[데이터 입력]</a>
<a href="index.jsp">[index]</a>
<a href="guestList.jsp">[전체출력]</a>
</td>
</tr>
</form>
</table>
</div>
</body>
loginSave.jsp - 로그인 아이디/패스워드 확인
(실제 로그인을 구현한다기 보다는 글 작성 시 유저에게만 수정/삭제 권한을 부여한다는 기능에 초점을 맞춘다)
<body>
<%
String userA = request.getParameter("userid");
String pwdB = request.getParameter("pwd");
msg="select count(*) as cnt from login where userid=? and pwd=? ";
PST=CN.prepareStatement(msg);
PST.setString(1, userA);
PST.setString(2, pwdB);
RS=PST.executeQuery();
if(RS.next()==true){ Gtotal=RS.getInt("cnt"); }
if(Gtotal>0){
session.setAttribute("naver", userA); //userid값을 가짜변수 세션naver가짜이름에 넘김
response.sendRedirect("index.jsp");
%>
URL파라미터에서 아이디와 비번을 받아온 뒤 존재하는 사용자인지 쿼리문을 작성해 검사한다.
select 된 데이터가 존재하면 세션에 저장한다.
로그인을 성공한 경우 아래와 같이 화면을 출력한다.
<font size=7 color=blue>
<b><%= userA %>님 로그인 성공!!!</b> <br>
</font><p>
<img src="images/bt_login.gif" width=450 height=70><p>
<img src="images/bar.gif" width=450 > <p>
로그인을 실패할 경우 화면 출력
<%
}else{
out.println("<div id='myLogin' align='center'>");
out.println("<b></b>"+userA+"님 로그인실패<br>");
out.println("<a href='login.jsp'>[로그인]</a>");
out.println("<a href='index.jsp'>[index]</a><br>");
out.println("<img src='images/tulips.png' width=400 height=250 >");
out.println("</div>");
%>
<script type="text/javascript">
setTimeout("location.href='login.jsp'", 2000);
</script>
<% } // else end %>
</body>
testDeleteSave.jsp - 로그인을 안 하면 삭제를 못 하도록 만듦
<%@ include file="./ssi.jsp" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.sql.DriverManager"%>
<%@ page import="java.sql.*"%>
로그인이 정상적으로 수행되어 세션에 저장된 사용자인지 검사한다.
<body>
<p>
<img src="./images/bear.gif">
<h2>testDeleteSave.jsp</h2>
<%
String my = (String)session.getAttribute("naver");
if(my==null || my.equals("")){
%>
- (String)session.getAttribute("naver") - 세션에 값을 얻어오기 위한 메소드
- session.setAttribute(String name, Object value) - 세션에 값을 저장하기 위한 메소드
- name : 값을 저장하는 대상. 세션에 저장 된 특정 값을 찾아오기 위한 키.
- value : 키와 일대일 대응으로 저장하는 값
- 동일한 이름으로 세션에 저장 시, 항상 덮어쓰게 된다.
- session.setAttribute(String name, Object value) - 세션에 값을 저장하기 위한 메소드
로그인 하지 않은 사용자라면
<div align="center">
<img src="images/tulips.png" width=450><br>
<script type="text/javascript">
alert("회원전용 서비스입니다\n 반드시 로그인 후 서비스가 가능합니다.");
setTimeout("location.href='testList.jsp'", 3000);
</script>
</div>
로그인한 사용자라면
<%
}else{
Gdata = request.getParameter("code");
msg = "delete from test where code= " + Gdata ;
System.out.println(msg);
ST = CN.createStatement();
ST.executeUpdate(msg);
System.out.println(Gcode +"코드 데이터 삭제성공 ");
response.sendRedirect("testList.jsp");
}
%>
</body>