게시판 만들기 - 수정, 삭제하기(펌)
![]() |
다사다난했던 2001년도.. 약 6시간 후면 다시 돌아올 수 없는 시간이 되어버리는군요.
아마 여러분들께서 이 강좌를 보실때 쯤이면 2002년이 시작되어 있을 것 같네요. ^^
뒤돌아보면 개인적으로 아쉽고, 안타까웠던 순간들이 참 많았던 것 같습니다.
하지만.. 이제는 어쩔 수 없는 서운한, 아쉬운 감정들을 저물어 가는 2001년의 석양에 얹혀서 멀리 떠나보내고..
새해에는 저나 여러분들 모두 올해보다는 더 나은 한해가 되시기를 기도드립니다.
새해 복 많이많이 받으시고요.. (일단 넙죽~)
자.. 그럼 오늘의 강좌를 시작하도록 하겠습니다.
오늘 다룰 내용은 '수정하기' 와 '삭제하기' 부분이 되겠습니다.
오늘의 내용을 미리 말씀드리면 다음과 같습니다.
지난 강좌까지 차근차근 따라오신 분이시라면 '내용보기' 페이지(content.asp) 페이지에서
'수정' 과 '삭제' 버튼이 있다는 사실을 기억하실 것입니다. (기억이 안난다면 잠시 다녀 오시지요..)
이곳에서 '수정' 버튼을 클릭하게 되면 글을 수정하는 화면(edit.asp)이 뜨게 됩니다.
그 곳에서 글을 수정하고 난 다음 기존에 입력했던 비밀번호와 동일한 비밀번호를 입력한 후
'수정 완료' 버튼을 누르게 되면, 실제 수정이 이루어지는 페이지(edit_ok.asp)로 이동을 합니다.
이 edit_ok.asp 페이지에서는 기존의 정보를 변경한 다음 목록 페이지(list.asp)로 다시 이동을 시킵니다.
'삭제' 를 눌렀을 경우에는 비밀번호를 확인하는 화면(delete.asp)이 뜨게 되고요.
그곳에서 입력한 비밀번호가 원래의 비밀번호와 일치하면 실제 삭제 페이지(delete_ok.asp)로 이동한 후에
해당 게시를 삭제한 다음 목록 페이지(list.asp)로 이동을 시키게 됩니다.
'아... 무언지 몰라도 오늘 무지하게 복잡한거 하나보다. 잘못 걸렸다...' 싶으신 분들 계신가요?
걱정하실 것 하나 없습니다. 오늘의 강좌는 그동안의 강좌를 복습하는 수준이라고 생각하셔도 되겠습니다.
삭제를 하기 위해 'delete 문' 을 새로 만나게 되실테지만..
지금껏 강좌를 잘 따라오신 분들에게는 이정도는 감히 '껌값' 이라고 말씀드릴 수 있겠습니다.
(아.. 그러고보니 요즘 껌값은 엄청 비싸더군요. 자XX톨이 무려 4000원이던가..? -_-a)
그렇다면 먼저 '수정하기' 부터 알아보겠습니다.
'taiji' 폴더 바로 밑에 'edit ' 라는 이름의 폴더를 하나 생성해 주시고요.
이 폴더 안에 'edit.asp ' 파일을 만드신 후에 다음 내용을 입력해 주시기 바랍니다.
<edit.asp>
01 |
<% |
위의 소스를 실행한 화면은 아마도 다음처럼 보여지게 될 것입니다.
<그림 1>
지금까지 작성한 소스 중에서 줄(line) 수로 따지면 가장 길어보이는군요..
그래도 웬지 낯설지는 않으실거라는 생각이 듭니다. 어디선가 본듯한 소스이지 않습니까? ^^
그렇습니다. 두번째 강좌에서 살펴본 글쓰기('regist.asp') 페이지와 놀랄만큼 흡사하지요..
(물론 regist.asp 페이지에서는 1~37번 줄까지의 ASP 코드는 없었지만요.. 그 뒷 부분은 거의 판박이죠)
혹시 기억이 가물가물 하시고, 잘 모르겠다.. 싶더라도 이럴때에는 상당히 반가운 척 해주시는 것이 좋습니다.
(아이 러부 스쿨에서 초등학교 시절 친구들을 만났을 때, 잘 몰라두 반가운 척.. 요거이 고저 왔담다~!)
위의 소스중에서 꼭 알아두셔야 할 점은 75~76번은 두줄이지만 반드시 '한줄로' 쳐야 한다는 것 입니다.
위에서는 칸이 짧은 관계로 두줄로 나누어 쳤지만, 여러분들께서 코딩하실 때는 꼭 한줄로 쳐주세요.
(이 부분을 읽지 않으시고 제게 에러가 난다는 둥.. 메일을 주시는 분들, 과연 몇분이나 계실지 세어 볼겁니다~)
자.. 그러면 본격적으로 소스를 분석해 보도록 하지요.
먼저 2번 줄에는 변수 선언에 관련된 Option Explicit 명령어를 실행했고요.
4~8번 줄까지는 이 페이지에서 사용할 변수 선언을 했습니다.
그리고 10번 줄에서는 content.asp 에서 해당하는 게시의 번호를 받아왔습니다. 해당하는 번호의 게시만을
수정하기 위해서이지요. Request.QueryString 으로 값을 받아왔다는 것, 이제는 낯설지 않으시겠죠?
12~13번 줄에서는 Connection 개체의 RecordSet 개체의 인스턴스 objDBConn, objRs 를 생성했습니다.
15번 줄에서는 objDBConn 개체를 이용하여 test DB로의 연결을 시도하고 있고요.
(그냥 마구 넘어가는군여. 설마 성의가 없다구 질책하지는 않으시겠져.. ^^a)
17번 줄부터 23번 줄까지는 상당히 자주 보아왔던 'Select ' 문이 다시 등장을 했습니다.
일반적으로 수정하는 페이지에서는 예전에 사용자가 입력했던 내용을 그대로 보여지게 합니다.
그래서 기존에 입력되어 있던 정보들을 가져오기 위해서 'Select' 문을 사용했습니다.
가져온 순서대로.. 이름, Email, 제목, 내용, 태그허용 여부의 다섯가지 항목이 되겠습니다.
마지막에 'Where + 조건절 '을 사용하고 있는 것을 보실 수 있을 텐데요..
이 조건절로 인해서 모든 게시의 내용이 아닌 해당 게시의 내용만을 가져오게 된다는 사실.. 다 아시겠지요?
25번 줄에서는 objRs(RecordSet 개체의 인스턴스)에 SQL문(strSQL 변수에 담긴)을 실행한 내용을
Open 메소드를 통해 모아모아서~ 고이 저장하는 줄이 되겠습니다.
그리고 27~31번 줄은 objRs에 담겨진 정보들을 각각의 변수에 할당하는 내용이 되겠습니다.
예리한 분들께서는 이 부분에서 지난 시간(내용보기 강좌)과의 차이를 발견하실 수 있을 텐데요. 지난 시간에는 objRs(0), objRs(1) 과 같이 순서로 접근 을 했는데 반해, 오늘은 objRs("strName"), objRs("strEmail") 처럼 테이블의 컬럼명으로 접근 을 했습니다. 순서로 접근을 하는 방식은 일반적으로 컬럼명으로 접근하는 방식보다 속도면에서 더 낫다 고 하는데요. 번호로 표기되기 때문에 알아보기 힘들다는 단점과, 수정시 불편하다는 약점 을 안고 있습니다. 예를 들어서 위의 SQL 문에서 strEmail 항목을 삭제한다고 하면.. 삭제 후 그 뒷부분에 있는 항목들의 번호들은 하나씩 줄어들어야 할 것입니다. 이경우, 이미 작성된 소스에서 뒷부분에 해당되는 항목은 모두 찾아서 하나하나 수작업으로 바꾸어 주어야 하지요.. 이것은 상당한 일거리가 될 수 있습니다. 닷넷 게시판에서 시삽을 맡고 계신 꽤싸뚜(cassatt) 님께서는 이런 이유로 후자의 방법을 권유하시더군여. |
각각의 변수들에 해당하는 정보를 모두 담은 후에 33~36번 줄에서는, 사용을 마친 objRs 와 objDBConn 을
닫고 해제시키게 됩니다.
그리고 38~94번 줄에서는 본격적으로 html 이 등장하게 되는데요.
43번 줄에서는 regist.asp 때와 마찬가지로 form을 정의하게 됩니다.
(form의 방식(method)은 지난번과 마찬가지로 'post' 방식을 선택했고요, form의 이름(name)은 'editForm',
그리고 정보를 이동시킬 목적지(action)는 'edit_ok.asp' 로 설정했습니다.)
여기 action 에서 'edit_ok.asp' 다음에 '?seq=<%= intSeq%>' 라는 문장이 추가되었다는 점이 눈에 띄네요.
다음 페이지로 지금 현재 게시에 해당하는 번호(intSeq) 값을 넘기기 위해 위의 문장이 추가되었다는 사실을
반드시 기억하시기 바랍니다.
그 이후의 내용에서는 그다지 특별한 것이 없어 보입니다.
<input type= "text"> 안에서 value="<%= strName%>" 과 같은 내용을 입력한 덕분에
페이지가 보여지게 될 때에는 각각 입력하는 칸 안에 값이 이미 들어 있는 모습을 보실 수가 있을 겁니다.
노파심에서 말씀 드리면 69번 줄에 있는 textarea 는다른항목처럼value="<%=strContent%>" 을
사용하는 것이 아니라 <textarea>와 </textarea> 사이에 내용을 넣는다는 사실 을 기억해 주세요.
(왜 얘만 틀리냐구요? 에.. 그건 이거 만든 사람한테 물어봐야 하는데 말이져.. 외국인이라서.. -_-a)
그리고 주목해주셔야 하는 곳은 75~76번 줄이 되겠습니다.
다른 부분은 regist.asp와 별 다를바가 없는데.. 뒤에 이상한 내용이 붙어 있군요.
75번 줄 ...전략... name="tag" value="T" <% If blnTag = "T" Then Response.Write "checked" %>>적용
76번 줄 ...전략... name="tag" value="F" <% If blnTag = "F" Then Response.Write "checked" %>>비적용
이부분은.. 기존에 입력한 사람의 선택이 어떤 것이었느냐에 따라 미리 체크해 주기 위한 부분입니다.
만약 태그 사용 여부(blntag)가 'T' 로 체크되어 있었다면.. 위의 줄의 If 문이 참이고 밑의 줄은 거짓일 것입니다.
그러므로 75번줄은 '<input type="radio" name="tag" value="T" checked>적용' 처럼 될 것입니다.
그렇다면 76번줄은 '<input type="radio" name="tag" value="F" >비적용' 처럼 되겠지요?
'엇, 지난 번에는 If 문을 쓸때에는 End If 를 꼭 써야 한다면서? ' 라고 질문하시는 분들 계실지도 모르겠네요.
(혹시 속으로라도 이 질문을 생각하신 분이 계시다면.. 정말 제 강좌를 열심히 보신 분입니다. 감사.. 감사..)
물론입니다. If 문을 쓸때에는 If 문이 끝나는 곳에 반드시 End If 라는 문장을 입력 해 주어야 합니다.
단 하나의 예외가 있는데.. 그 예외는 If 문이 바로 그 줄에서 끝나는 경우 입니다. (위의 경우가 바로 그 예지요)
하지만 이 경우에는 Else 문을 사용할 수가 없습니다. Else 문을 사용하고 싶은 경우에는 End If 가 반드시
뒤따라야 합니다.
(왜 한줄에서 끝나면 End If 를 안써도 괜찮냐구요? 에.. 그것도 말이져.. 이걸 만든 사람이 외국인이라서... -_-a)
수정을 마치신 후 87번 줄에 있는 '작성 완료' 버튼을 누르면 기록되어 있는 모든 내용은 'edit_ok.asp' 페이지로
이동을 하게 됩니다. 그 다음 줄에 있는 88번 줄에서도 버튼을 하나 만들었는데요..
이 버튼을 클릭(onClick)하게 되면, 자바스크립트 함수인 history.back(); 함수가 호출이 됩니다.
이 함수는 페이지를 이전 페이지로 이동시켜주는 역할을 합니다. (아마도 content.asp 페이지가 되겠지요)
이정도로 edit.asp 페이지에 대한 소스 분석을 마치도록 하고, 다음은 받아온 정보를 처리하는 edit_ok.asp
페이지를 만들어 보겠습니다. 'taiji' 폴더 밑에 있는 'edit' 폴더 안에 'edit_ok.asp ' 파일을 생성해 주신 후에
다음 소스를 입력해 주시면 되겠습니다.
<edit_ok.asp >
01 |
<% |
자.. 이 페이지에는 html 이 보이지를 않는군요.. 그렇다면 이 페이지는 무엇을 하는 페이지 일까요?
그렇습니다.. edit.asp 에서 받아온 값들로 board 테이블에 있는 기존의 내용을 수정하는 페이지가 되겠습니다.
자.. 그럼 한번 천천히 훑어 볼까요?
9번 줄까지는 설명을 생략하도록 하겠습니다. 더 이상의 반복학습은 무의미 하다는 판단하에.. ^^
그런데.. 8번 줄에서 웬지 미심쩍은(?) 변수가 등장을 하게 됩니다. (strRealPassword 와 strPassword 말이지요)
잠시 설명을 드리자면.. strRealPassword 는 기존에 입력되어 있던 비밀번호를 담을 변수 가 되겠고요.
strPassword 는 방금 전에 수정을 위해 사용자가 입력한 비밀번호 가 되겠습니다.
(이 두가지를 비교해서 비밀번호가 틀리다면.. 글 쓴 사람이 아니므로 글을 수정하지 않을 생각입니다.)
11~18번 줄까지는 앞에서 넘겨준 값들을 신나게 받아오는 항목이 되겠습니다.
그런데.. 대부분 Request.Form 으로 받는데.. 제일 처음에 나온 intSeq 만 Request.QueryString 으로 받는 것을
의아하게 여기실 분이 있으실 것 같은데요.. intSeq 값은 'edit.asp' 에서 url의 뒤에 붙여 값을 넘기는 get 방식 을
사용했다는 것을 기억해 주시기 바랍니다. (edit.asp 페이지의 43번 줄이 되겠습니다.. 친절하기도 하지~)
사실 이것들을.. Request.QueryString("seq") 이든 Request.Form("seq") 이든 상관 없이 그냥 통합해서 Request("seq") 라고 받아올 수 있습니다. 실제로 이 방법이 오타 걱정도 없고, 타이핑도 편하답니다. (굳이 속도적인 측면을 논하라고 하면 QueryString 이나 Form 으로 받아오는게 조금 더 빠르다고 하네요.) '그래? 그런데 왜 위처럼 각각 틀리게 써가지구 사람을 헷갈리게 만드는데? 오호라~ 아는척 좀 해보시겠다?' 에~. .그런 의도는 아니고요. -_-a 아무래도 제가 대상으로 하는 분들은 초보분들 이시기 때문에.. 처음 배우실 때 위와 같은 기초적인 내용들에 빨리 익숙해 지시라고 귀찮더라도 구분을 짓는 것이랍니다. 이제 Get 방식과 Post 방식의 차이를 이해하고 계시는 여러분들께서는 Request("seq") 처럼 약식으로 쓰는 방법에 대해 상당히 반가워 하실 것 같고, 또한 그 사용을 즐겨하실 지도 모르겠습니다. 하지만 제가 처음부터 약식을 먼저 설명드렸다면... Get 방식은 QueryString 이고, Post 방식은 Form 이다 라는 설명을 드려도 이해하려는 것보다는 그냥 약식만을 즐겨 사용하실지도 모른다는 우려가 있었습니다. '정확한 개념은 모르고, 사용법만을 이해한 후 슬금슬금 넘어가는 것은.. 마치 모래 지반 위에 집을 세우는 것과 같은 것이다' 라고 저는 배워왔고, 또한 지금 여러분들께 감히 말씀드리고 싶습니다. (사실 이런 주제넘은 말씀을 드리는 제 자신도 지금 무지 찔리고 있습니다. 아.. 피난다. -_-a) |
20, 21, 23번 줄은 더이상 설명이 필요없는 Connection 개체의 인스턴스 objDBConn 와 RecordSet 개체의
인스턴스 objRs 를 생성한 후 test DB에 연결시키는 작업이 되겠습니다.
그리고 25~32번 줄은 지금 수정하고자 하는 게시물의 원래의 비밀번호를 알아오는 SQL 문(25~27줄)을
작성한 후 정보를 가져와서(29), strRealPassword 라는 변수에 그 비밀번호를 담은 다음(30), 레코드셋 개체의
인스턴스 objRs 를 닫고(31), 해제시키는(32) 내용이 되겠습니다. 어렵지 않으시지요?
자.. 그렇게 가져온 비밀번호가 사용자가 edit.asp 페이지에서 입력한 비밀번호와 틀리다면 어떻게 할까요?
그렇다면.. 원래의 입력자가 아니라는 뜻이 되므로, 바꾸려고 하는 내용을 적용하지 않고 원래의 페이지로
돌려버려야 할 것입니다. (여기서는 edit.asp 페이지로 되돌려 주는 것이 가장 좋겠지요)
그 내용이 34~44번 줄에 나와 있습니다.
만약 비밀번호가 일치하지 않는다면 자바스크립트 알림창이 "비밀번호가 일치하지 않습니다" 하는 경고 문구와
함께 뜬 후, '확인' 버튼을 누르면 원래의 페이지인 edit.asp 페이지로 돌려 보낼 것입니다.
그런데.. 43번 줄에 있는 Response.End 라는 녀석이 눈에 거슬리시나요?
이 친구는.. 여기까지만 실행하고 이 페이지의 실행을 여기서 마치라는 의미 를 가진 친구입니다.
만약 이 친구를 넣지 않으신다면 현재의 페이지가 edit.asp 페이지로 돌아가는 것과는 별개로 46번줄 이하가
진행이 되어서 우리가 다시금 내용을 보려고 한다면 비밀번호가 틀리는데도 수정이 되어버리는 황당한
사태가 발생할 수도 있습니다. 그렇기에 이 부분은 꼭 넣어주셔야 하는 부분이 되겠습니다.
본론으로 돌아와서.. 만약 받아온 비밀번호가 원래의 비밀번호와 일치한다면 어떻게 될까요..?
그렇습니다. 34~44번 줄은 실행이 되지 않고, 대신 46번줄 이하가 실행되게 될것입니다.
이곳의 If 문은 '원래의 비밀번호와 사용자가 입력한 비밀번호가 틀리다' 는 조건일 때만 실행이 되기 때문이지요.
46번줄 이하는 이곳은 사용자가 edit.asp 에서 입력한 내용으로 기존의 내용들을 수정하는 내용이 되겠습니다.
여기서 등장한 'Update 문'은 '수정/변경을 담당하는 구문 '이라고 말씀드린 기억이 나네요. (바로 지난 시간인
내용보기 - content.asp - 강좌가 되겠습니다.. 기억이 나지 않으신다면 잠시 살펴보고 오심이 좋겠죠)
실제로 수정할 Update 문을 작성하고 있는 부분이 46~54줄이 되겠습니다. 그리고 작성된 Update 문을
실제로 실행(56) 시키고, Connection 개체의 인스턴스인 objDBConn 을 닫고(57), 해제합니다.(58)
이렇게 되면 실제 board 테이블의 intSeq 번호에 해당하는 내용들은 edit.asp 에서 작성한 내용대로
수정이 되어져 있을 것입니다. 그럼 수정이 완료된 다음에는 어떻게 할까요?
저는 그냥 원래의 목록 페이지(list.asp)로 돌려주는 방법을 택해보았습니다.
62번 줄에서 자바 스크립트 알림창이 "수정되었습니다" 라는 문구와 함께 뜬 후, 확인 버튼을 누르면
list.asp 페이지로 돌려주게(63) 됩니다. 만약 여러분들께서 63번 줄을 적당히 바꾸신다면 목록 페이지가 아닌
수정된 내용이 적용된 내용보기(content.asp) 페이지로 이동시킬 수도 있을 것입니다.
이정도로 수정에 관련된 부분을 마치도록 하겠습니다..
생각보다 어렵지 않았지요? 여러분들께서는 자신도 모르는 사이 조금씩 공력이 증가되었던 것입니다. 오오옷~
그럼.. 이제 그동안 모은 공력이 사라지기 전에 여세를 몰아 삭제하기 페이지에 도전해 보도록 하겠습니다.
'taiji' 폴더 밑에 'delete ' 라는 폴더를 새롭게 하나 만들어 주시고요. 그 안에 다음 소스를 참고하셔서
'delete.asp' 페이지를 작성해 주시기 바랍니다.
<delete.asp >
01 |
<% |
이 페이지를 실행한 결과는 다음과 같을 것입니다. 아주 간단하지요.
<그림 2>
아... 정말 짧고 간단하지 않습니까? 거기다가 ASP 코드는 단지 7줄.. (실제로는 3줄이군요)
아무래도 이 페이지는 그냥 페이지가 아니라 '쉬어가는 페이지' 인가 봅니다. 헐헐~
자.. 그럼 오래 끌것 없이 신속하게 살펴보도록 하겠습니다.
이 페이지에서는 'content.asp' 에서 넘겨준 해당 게시의 번호(intSeq) 만을 받아오고 있는 것을 보게 됩니다.
그리고 '수정하기' 페이지 때와 마찬가지로 13번 줄에서 url의 뒤에 이 번호값을 붙여서 전송하고 있는 것을
보실수가있습니다. (delete_ok.asp?seq=<%=intSeq%>)
사용자에게 입력받는 것도 '수정하기' 페이지와는 달리 단 하나밖에 없군요.
21번줄에 등장하는 '비밀번호' 항목이 바로 그것인데요..
그도 그럴 것이 비밀번호만 일치하면 다른 항목들의 수정 또는 삽입 없이 그냥 삭제해 버리면 되기 때문입니다.
그러므로 이 '삭제하기' 페이지에서 필요한 항목은..
해당하는 게시물의 번호(intSeq)와 비밀번호(strPassword) 이렇게 두개뿐인 것입니다.
음.. 이 페이지에서 무언가 더 말씀을 드리려고 해도, 이제는 더 말씀드릴 것이 없네요. -_-a
그럼 얼른 delete_ok.asp 페이지를 보도록 하겠습니다.
아까 작성하신 'delete.asp' 와 같은 디렉토리('delete 폴더 밑')에 'delete_ok.asp ' 페이지를 만드신 후
다음 소스를 입력해 주시기 바랍니다.
<delete_ok.asp >
01 |
<% |
이 부분도 edit_ok.asp 페이지와 큰 차이는 없어 보입니다. (사실.. 거의 판박이 수준이네요)
단지 Update 문을 사용하던 부분이 delete 문으로 바뀐 점이.. 달라졌다면 달라진 점이라고 할 수 있겠네요.
그러면 소스를 분석해 보도록 하겠습니다.
2~7번줄 까지는 Option Explicit 와 변수 선언을 하는 줄이 되겠습니다.
그리고 9~10번 줄에서는 바로 이전페이지(delete.asp)에서 받아온 두 값을 intSeq, strPassword 라는 변수에
담고 있습니다. (intSeq 는 Get 방식, strPassword 는 Post 방식으로 값을 전달하고 있지요)
12~15번 줄은 Connection, RecordSet 개체의 인스턴스를 각각 만들고 DB에 연결하는 부분이 되겠고요.
17~24번 줄까지는 이 게시의 진짜 비밀번호를 가져와서 strRealPassword 라는 변수에 담는 부분이 됩니다.
26~36번 줄은 사용자가 입력한 비밀번호와 실제 비밀번호를 비교해서.. 만약 그 값이 틀리다면
경고 화면을 보여준 후 이전 페이지로 돌려보내는 역할을 하는 부분이 되겠습니다.
그리고 이 페이지의 핵심인 38~39번 줄에서는 삭제를 담당하는 'Delete 문' 이 등장을 합니다.
지금까지 다루어 보았던 Select, Insert, Update 문과 함께 4대 천황(?)을 이루는 Delete문..
그 사용법을 살펴보도록 하겠습니다.
Delete 문의 형식은 다음과 같습니다.
"Delete from" + Table 명 + " Where " + 조건절
'에게? 4대 천황 어쩌구.. 해서 복잡할 줄 알았더니 뭐야. 무지하게 간단하잖아?'
라고 비웃으시는 분들이 계시겠지요? 그렇습니다.. Delete 문은 상당히 사용법이 간단합니다.
하지만.. '간단해 보이는 것'과 '실제로 테스트를 해보고 넘어가는 것'은 차이가 있겠지요.
자.. 그럼 간만에 테스트를 해 보도록 하지요.. 모두 다 같이 Query Analyzer 를 실행시켜 주시기 바랍니다.
(아직도 기억하시는 분들을 위해.. '시작 -> 프로그램 -> Microsoft SQL Server -> Query Analyzer ' 입니다.)
그리고는 다음과 같은 문장을 실행해 보도록 할까요?
Delete from board Where intSeq = 1
실행하신 후 'Select * from board' 로 확인을 해보시면 아래의 '그림 3' 처럼
1번 게시가 소리소문없이 조용히~ 사라진 것을 보실 수가 있을 것입니다.
<그림 3>
그렇다면.. 만약 다음과 같은 구문을 실행하게 되면 결과는 어떻게 될까요?
Delete from board Where strName = '김덕영'
Select 문으로 결과를 보셨겠지만 strName(이름)이 '김덕영' 으로 되어 있는 게시는 두개가 있는데요.
(하나는 제가 이전의 '수정하기' 페이지에서 이름을 '전람회' 로 변경하였답니다. 2번 게시네요.)
이중에서 어떤 것을 지우게 될까요..? 첫번째? 아니면 두번째?
그런거 없습니다. Delete 문은 조건에 해당되면 아래 '그림 4' 처럼 무조건 지워버립니다.
<그림 4>
사실.. 이 Delete 문은 사용법이 상당히 간단한 대신, 오타나 실수에 상당한 주의를 요하는 구문 입니다.
만약 다음과 같은 구문을 실행했다면 어떻게 될까요?
Delete from board
이 구문을 작성하고 실행했다면.. board 테이블 안에 있는 모든 자료들이 지워지게 됩니다.
(단 한개도 남기지 않고 가차없이 지워버리지요. 아래의 '그림 5' 처럼 말이지요)
<그림 5>
지금이야.. 우리 테이블에 한두개 정도밖에 자료가 없으니까 웃을 수 있지만..
자료가 많은 테이블의 경우에는 위와 같은 구문을 아무 생각없이 실행했을때 모든 데이터가 날라가는 것은
물론, 복구가 불가능하다는 사실을 꼭 기억하시기 바랍니다.
'잠깐.. delete from board' 라고 하면 board 테이블이 없어지는거 아닐까?' 하는 걱정을 하는 분들이 계실지도 모르겠습니다.. 하지만 delete 라는 명령어는 테이블을 지우는 명령어가 아니고 테이블 안의 내용만을 지우는 명령어가 되겠습니다. 테이블 자체를 제거하고 싶으실 때 사용하는 명령어는 'drop table + table 이름'이 되겠습니다. (심심하다고 괜히 이거 실행하시면 전 뒷감당 못합니다. -_-a) |
본문으로 돌아가서 38~39번 줄은 삭제를 담당하는 'delete문' 을 작성하는 부분이 되겠고요.
41번 줄에서 이 문장을 실행시키는 것을 보실 수 있을겁니다.
(delete 문도 update 문과 같이 objDBConn.Execute 명령어로 실행 하시면 됩니다)
42번줄 이후의 부분은 잘 아시는대로 Connection 개체를 닫고 해제를 한 다음, 자바 스크립트의 알림창을
띄워서 삭제가 된 것을 알려준 후, list.asp 페이지로 이동을 시켜주고 있습니다.
이것으로서 오늘의 주제였던 '수정하기' 와 '삭제하기' 페이지에 대해서 모두 살펴보았습니다.
한꺼번에 4개의 페이지를 살펴보려 해서, 양적으로 조금은 버겨우셨을지도 모르겠습니다만..
내용 자체에서의 어려움은 그다지 느끼지는 않으셨으리라는 추측을 감히(!) 해보게 됩니다.
실제로 오늘 내용에서 별다른 어려움을 느끼지 않으셨다면, 여러분들께서도 이제 ASP 라는 녀석과 많이
친해졌다고 말씀드릴 수가 있겠습니다. (벌써부터 지겨우시다고요? 그럼 곤란한데요.. -_-a)
이제.. 우리의 게시판은 정말로 기본적인 게시판의 모습을 갖추게 되었습니다.
(물론 아직도 페이지 나누기와 검색하기.. 강좌가 남아있긴 하지만 말이져.)
조금씩 살이 붙어가는 게시판의 모습을 보시니.. 감회가 새롭지 않으십니까? (저만 새롭나요? -_-a)
다음 시간에는 '페이지 나누기 ' 에 대해서 알아보도록 하겠습니다.
(참고로 '게시판'을 한번이라도 만들어보신 분들께서는 한결같이 이 '페이지 나누기' 부분을
'게시판 만들기의 백미 '로 꼽는 데 주저하지 않으십니다. 그만큼 어렵기도 하고, 또 재미있기도 하지요)
그럼 다음 강좌에서 뵙겠습니다. 모두들 새해에는 항상 행복한 일들만 가득하시길...
'My work space > JSP/Servlet' 카테고리의 다른 글
게시판만들기-검색하기(펌) (0) | 2008.09.08 |
---|---|
게시판만들기-페이지나누기(펌)ASP (0) | 2008.09.08 |
Database Connection Pool (DBCP)의 사용 (0) | 2008.09.08 |
서블릿 forward와 include의 비교 (0) | 2008.09.08 |
쿠키 관련 (0) | 2008.09.08 |
Database Connection Pool (DBCP)의 사용

Database Connection Pool (DBCP)의 사용
관련 사이트
http://jakarta.apache.org/commons/dbcp/
http://jakarta.apache.org/tomcat/tomcat-4.1-doc/jndi-datasource-examples-howto.html#Database%20Connection%20Pool%20(DBCP)%20Configurations
http://jakarta.apache.org/tomcat/tomcat-4.1-doc/config/globalresources.html#Resource%20Parameters
http://jakarta.apache-korea.org/tomcat/tomcat-4.0-doc/jndi-resources-howto.html
Introduction
DBCP는 jakarta 프로젝트에서 지원하는 JDBC connection pool로 "http://jakarta.apache.org/commons/dbcp/" 이 곳에서 자세한 정보를 얻을 수 있으며 여기서는 Tomcat 4에서 제공하는 JNDI InitialContext 구현 인스턴스를 이용하여 사용하는 법에 대해 알아본다.
Download
"http://jakarta.apache.org/builds/jakarta-commons/release/commons-dbcp/v1.0/"
현재 release 버전은 v1.0이며 이곳에서 예제 및 샘플을 얻을 수 있다.
JNDI(Java Naming and Directory Interface)란?
네이밍 서비스(naming service)와 디렉토리 서비스(directory service)가 합쳐진 것으로 네이밍 서비스는 객체, 자원 서비스 등을 찾아주는 서비스를 의미하며 디렉토리 서비스는 트리 형태의 계층적인 정보를 서비스 하기 위한 것입니다. JNDI API는 javax.naming, javax.naming.directory, javax.naming.event, javax.naming.ldap, javax.naming.spi 패키지에서 지원된다.
Configurations
DBCP는 JVM 1.4를 이용하는 시스템과 JDBC 2.0에 제공된다.
DBCP INSTALL
구성파일
Jakarta-Commons DBCP 1.0 : commons-dbcp.jar
Jakarta-Commons Pool 1.0 : commons-pool.jar
Jakarta-Commons Collections 2.0 : commons-collections.jar
Jdbc Driver : oracle(classes12.zip), mssql(freetds_jdbc.snapshot.jar), mysql(mm.mysql-2.0.2-bin.jar)
사용하는 DB에 따라 적절한 드라이버가 필요하다.
위 jar 파일들은 $CATALINA_HOME/common/lib 이곳 폴더아래 위치해야만 한다.
만약 /WEB-INF/lib, 또는 $JAVA_HOME/jre/lib/ext, 또는 다른곳에 위치한다면 "드라이버를 찾을 수 없다"는 에러가 발생한다.
또한 Tomcat은 오직 jar 파일만 클래스패스에 추가가 되므로 zip파일은 가능하면 jar파일로 바꿔줘야 한다.
DBCP 설정
혹시 제주도에 가본적이 있는가?
갑자기 왠 제주도 얘길까 싶겠지만 딱딱하기만 한 커넥션 풀을 쉽게 풀기 위해 제주도를 무대로 설명하려 한다.
제주도는 우리나라의 대표적인 관광지이다. 매년 많은 USER가 방문하는 곳으로 보통 하루에 만명정도가 방문하며 동시 이용자가 200명 정도 된다. 제주도에는 가진거라곤 돈 뿐인 까오기라는 뚱땡이 부자가 있었다. 어느날 많은 방문자들을 보고 자신의 전재산을 털어 자동자 렌트 사업을 하기로 했다. 우선 전체 방문자와 그중에 자동차 이용자를 어느 정도 파악하고 그다음에 자신의 재산을 고려하여 주차 공간과 차를 사기로 했다. 회사이름을 꺼내숑뿔이라고 짓고 대지 천평에 자동차 100대(maxActive:100)를 샀다. 돈많은 관광객들이 많아 한동안 사업이 나날이 번창 했다. 그러던 어느날 문제가 발생하기 시작했다. 차가 여기 저기 고장도 나고 사람들이 별로 선호 하지 않는 자동차가 생긴것이다. 이용자는 많은데 안쓰는 차가 주차 공간을 차지 하고 있어 이를 처리해야 할 처지이다. 그래서 리무브 대리가 폐차 계획(removeAbandoned:TRUE)을 짜기로 했다. 우선 무조건 팔아버리긴 아까우니 최소 한달은 기다렸다가 그때도 사람들이 안쓰면 팔기로 했다. (removeAbandonedTimeout:30일) 근데 사장은 리무브 대리가 무슨 짓을 저지르는지 알고 싶어 일일이 기록하라고 로그장부(logAbandoned:TRUE)에 기재 토록 시켰다. 또 똥돼지 파동으로 냄새난다고 관광객이 줄어 들어 놀고 있는 차를 팔고 필요하면 다시 사기로 했다. 어찌나 냄새가 나는지 관광객이 너무 줄어서 100대의 차중에 80대가 놀고 있었다. 이차들을 계속 유지하는 것도 힘들어 맥씨 아들(maxIdle)에게 노는 차를 조사하다 20대가 넘으면 나머진 팔아 버리라고 시켰다. 똥돼지들은 나날이 냄새를 풍기고 관광객은 점점 줄어만 갔다. 그러던중 사업장 부지에 대규모 관광단지가 조성되게 되어 땅값이 엄청나게 올랐다. 그래서 꺼내숑뿔 회사는 부자가 됐다. ^^
위에 웃기지도 않은 이야기가 대강의 이해를 도왔다면 아래 실제 소스를 보겠다.
server.xml에 다음과 같은 코딩이 필요하다.
removeAbandonedTimeout은 어느 정도의 시간 지나면 버릴것인가를 결정하는 것이다.(60초라면)
<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>
<parameter>
<name>removeAbandonedTimeout</name>
<value>60</value>
</parameter>
logAbandoned 파라미터는 커넥션 자원이 버려질때 로그로 기록 될것인가를 결정하는 것으로 기본은 false이다.
<parameter>
<name>logAbandoned</name>
<value>true</value>
</parameter>
MySQL DBCP Example
Configurations
MySQL 3.23.47, MySQL 3.23.47 using InnoDB, MySQL 4.0.1alpha
mm.mysql 2.0.14 (JDBC Driver)
testdata 테이블 생성
mysql> create table testdata (
-> id int not null auto_increment primary key,
-> foo varchar(25),
-> bar int);
테스트 데이터의 삽입
mysql> insert into testdata values(null, 'hello', 12345);
Query OK, 1 row affected (0.00 sec)
mysql> select * from testdata;
+----+-------+-------+
| ID | FOO | BAR |
+----+-------+-------+
| 1 | hello | 1234 |
+----+-------+-------+
1 row in set (0.00 sec)
mysql>
server.xml 설정
$CATALINA_HOME/conf/server.xml 이곳에 파일을 열고 해당 컨텍스트를 수정한다.
기존 컨텍스트
<Context path="/kkaok" docBase="c:/kkaok" debug="0" reloadable="true"/>
변경
<Context path="/kkaok" docBase="c:/kkaok" debug="0" reloadable="true"> <!-- 이름과 어플리케이션에서 유효한 자원의 데이터 형을 지정합니다. --> <Resource name="jdbc/jack1972" auth="Container" type="javax.sql.DataSource"/> <!-- 사용할 자원 factory implementation 의 자바 클래스명과 자원 factory 를 설정하는 데 사용되는 JavaBeans 프로퍼티를 설정합니다.--> <ResourceParams name="jdbc/jack1972"> <!-- 아이디 --> <parameter> <name>username</name> <value>userName</value> </parameter> <!-- 패스워드 --> <parameter> <name>password</name> <value>userPassword</value> </parameter> <!-- 드라이버 --> <parameter> <name>driverClassName</name> <value>org.gjt.mm.mysql.Driver</value> </parameter> <!-- url --> <parameter> <name>url</name> <value>jdbc:mysql://localhost/kkaokDB</value> </parameter> <!-- 불필요한 커넥션 제거 --> <parameter> <name>removeAbandoned</name> <value>true</value> </parameter> <!-- 삭제할 최대 시간 결정 --> <parameter> <name>removeAbandonedTimeout</name> <value>60</value> </parameter> <!-- 삭제 기록 유무 --> <parameter> <name>logAbandoned</name> <value>true</value> </parameter> <!-- 사용하는 커낵션 최대수 --> <parameter> <name>maxActive</name> <value>25</value> </parameter> <!-- 사용 안하고 있는 커넥션의 최대수 --> <parameter> <name>maxIdle</name> <value>10</value> </parameter> <!-- 커넥션을 열기위해 최대 기다리는 시간 "-1"이라면 무기한 기다린다. --> <parameter> <name>maxWait</name> <value>-1</value> </parameter> </ResourceParams> </Context> |
web.xml 설정
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd> <web-app> <resource-ref> <description>DB Connection</description> <res-ref-name>jdbc/jack1972</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </web-app> |
Test code
<%@ page contentType="text/html;charset=MS949"%> |
tomcat을 재시동하시고 브라우져를 통해 확인하면 된다.
'My work space > JSP/Servlet' 카테고리의 다른 글
게시판만들기-페이지나누기(펌)ASP (0) | 2008.09.08 |
---|---|
게시판 만들기 - 수정, 삭제하기(펌) (0) | 2008.09.08 |
서블릿 forward와 include의 비교 (0) | 2008.09.08 |
쿠키 관련 (0) | 2008.09.08 |
HttpSessionBindingListener로 구현한 중복로그인체크(3) (0) | 2008.09.08 |
forward와 include 모두 서블릿에서 흐름을 제어할때 쓰이는 메소드 입니다.
forward는 A에서 forward(B)를 한다면 forward를 호출하기전까지 전부 해석하다가
호출하는 시점에 B로 흐름이 넘어갑니다.
즉 아직까지 request는 한번 입니다
include는 A에서 include(B)를 한다면 A에서 include 호출하기전까지 모두 해석
-> B로 흐름 넘어가서 B 전부 해석하고 끝나면 -> 다시 A의 호출문장으로 넘어옵니다.
여기서도 request는 한번입니다.
근데 sendRedirect 라는 놈이 있는데요 이놈은 request가 두번이 일어납니다.
왜냐면 sendRedirect는 특정주소를 호출할 것을 요청하는 응답신호를 브라우저에게 보내기 때문입니다.
즉 A에서 sendeRedirect(B)를 한다면 A -> B -> A -> B
그래서 request 가 두번 발생하는것입니다.
감이 잘 안오시죠? 하하.. 저두 그렇답니다 -_-;;
그래서 소스를 준비했답니다 -_-v
Strat.html
<html>
<head>
<title> forward 및 include , sendRedirect 때려잡기! </title>
</head>
<body>
<form action="Check.jsp" method="post">
당신의 나이는?
<input type="text" name="test"><br><br>
<input type="radio" name="check" value="forward"> forward 방식
<input type="radio" name="check" value="include"> include 방식
<input type="submit" value="Confirm">
</form>
</body>
</html>
간단히 forward와 include중 어느 형식으로 보낼것인치 체크하고 나이를 넣게 했습니다.
Check.jsp
<%
String check = request.getParameter("check");
java.util.Date today = java.util.Calendar.getInstance().getTime();
%>
이건 include 할때만 보여요~ ^^
<hr>
<% if (check.equals("forward"))
{%>
<jsp:forward page="./Result.jsp" >
<jsp:param name="check" value="<%=check%>"/>
<jsp:param name="today" value="<%=today%>"/>
</jsp:forward>
<hr>
<% } else if (check.equals("include")) { %>
<jsp:include page="./Result.jsp">
<jsp:param name="check" value="<%=check%>"/>
<jsp:param name="today" value="<%=today%>"/>
</jsp:include>
<% } %>
이것은 결과 페이지(result.jsp)에 가기전에 forward와 include의 차이점을 보여주는 페이지
일단 포워드는 호출하면 그 위까지만 해석하고 바로 흐름이 바뀌기 때문에 " 이건 include 할때만 보여요~ ^^"라는 문장은 해석은 하지만 뿌리지는 못합니다.
그래서 그럼 이넘이 과연 해석은 정말 하고 가는가 의문이 들어서 시간을 넘는 today를 만들어서 넘겼습니다.
Result.jsp
<br>
이것은 <%= request.getParameter("check") %> 방식입니다.
<hr>
나이 : <%=request.getParameter("test")%>
<hr>
현재 시간 : <%= request.getParameter("today")%>
이건 결과 페이지입니다.
forward의 실행화면




'My work space > JSP/Servlet' 카테고리의 다른 글
게시판 만들기 - 수정, 삭제하기(펌) (0) | 2008.09.08 |
---|---|
Database Connection Pool (DBCP)의 사용 (0) | 2008.09.08 |
쿠키 관련 (0) | 2008.09.08 |
HttpSessionBindingListener로 구현한 중복로그인체크(3) (0) | 2008.09.08 |
HttpSessionBindingListener로 구현한 중복로그인체크(2) (0) | 2008.09.08 |