조회해서 화면에 뿌리는건 해보았고...
DB 테이블에 홍길동만 덜렁 있는건 좀 안쓰러우니깐 등록도 해주고 바꾸고 싶은게 있으면 수정도 시키고 다 필요 없어! 싶으면 삭제도 시켜보자.라고 생각했지만.. 등록만 하자...
1. 목표
index.jsp에 버튼을 추가하고 Insert SQL을 작성하고 userRegistView.jsp 화면도 추가하고 javascript 함수도 만들어보자.
- index.jsp 접근
- 등록버튼을 클릭
- 등록화면으로 이동
- 등록할 데이터를 입력하고 저장 클릭 SQL 실행 완료, 실패 알림 노출
- 알림확인하면 index.jsp 화면으로 이동
2. 테이블 살펴보기 (SQL DESC 명령어)
HeidSql을 통해 데이터를 등록하는건 이미 해보아서 알고 있다.
그런데 누군가 데이터를 등록하고 싶다고 할 때 HeidSql 설치하시고요 Ip, Port, Id, Pw 설정하시고요 OD_MBER에 Insert 하시면 됩니다. 이렇게 설명한 텐가? (개발자면 알아듣겠지...) 그래서 일반 사용자가 쓸 수 있도록 작업을 해보자.
- OD_MBER 테이블 확인
HeidSql을 실행하자 (DESC는 Describe 약어로 해당 테이블의 기술된 설명 좀 보자 정도 된다.)
DESC od_mber;
해당 SQL을 실행하면 아래 표와 같이 조회될 텐데 각 셀이 의미하는 내용은
한글명 : 이건 내가 보기 편하려고 추가한 거임
Field : column 이름 (요기부터 DESC 명령어)
Type : column data type
Null : 빈 값을 허용할지 여부
Key : PK, UNIQUE 등등 제약조건
Default : 빈 값이 들어오면 기본값으로 사용할 데이터 설정
Extra : 특별한 설정 (auto 님은 특별하니깐...)
이렇게 표현되는데 이는 Tool마다 약간씩 차이 나므로 대충 그렇구나 하고 넘어가시면 되겠다.
|
한글명 |
Field |
Type |
Null |
Key |
Default |
Extra |
|
회원 일련번호 |
MBER_SN |
int(11) |
NO |
PRI |
auto_increment |
|
|
회원 아이디 |
MBER_ID |
varchar(100) |
NO |
UNI |
||
|
회원 비밀번호 |
MBER_PWD |
varchar(100) |
NO |
|||
|
회원 이름 |
MBER_NM |
varchar(100) |
NO |
|||
|
회원 휴대폰 |
MBER_MOBLPHON |
varchar(11) |
YES |
|||
|
비고 |
RM |
mediumtext |
YES |
|||
|
등록자 |
REGIST_SN |
int(11) |
NO |
|||
|
등록일시 |
REGT_DTTM |
varchar(14) |
NO |
|||
|
수정자 |
UPDT_SN |
int(11) |
NO |
|||
|
수정 일시 |
UPDT_DTTM |
varchar(14) |
NO |
표시된 테이블 정보를 살펴보면 회원 일려번호를 시작으로 총 10개의 Column이 있고 Type int도 있고 Null이 No인 것도 있고 뭐 그렇다.
칼럼과 그 정보를 살펴보니 회원 일련번호는 auto_increment님께서 자동으로 채워주시니 (MySQL auto_increment를 구글님께 여쭈어 봅시다.) 넘어가고 그럼 나머지 9개의 칼럼에 데이터를 넣어 주면 된다는 건데... 여기 Null이 NO 인 것은 not null column이라 해서 빈 값이 들어올 수 없다.
즉 등록 시 반드시 값이 들어와야 하는 건데 아이디, 비밀번호, 이름은 필수로 받아야 하고 휴대폰, 비고는 뭐 없음 말고 그래서 이것들은 화면으로부터 받아서 데이터를 채워주자.
그럼 등록자, 등록일시(어라 오타가 있었네 ㅠ), 수정자, 수정 일시 이것들은? 언급이 없는 거 보니 받아서 넣는게 아닌거 같은데??
그렇다 테이블에 뭔가 하나가 등록되면 예를 들어 지금 글을 쓰는 것처럼 글의 등록자, 등록일시, 수정자, 수정 일시는 실제로 데이터가 들어가는 시점에 입력되어야 할 것 같지 않은가?
만약 글을 쓰다가 중간에 취소할 수도 있고 글을 수정하다 취소할수도 있는데 화면에서 받는게 의미가 있는가?(있을 수도 있지만...) 아 그럼 이건 진짜 Insert나 update 발생하는 시점에 들어가야겠구나 하고 생각하자는 거고 글을 뭐 1초 만에 작성하는 것도 아니고 상황에 따라서 1분이 걸리수도 있고 1시간이 걸릴 수도 있는데 실제로 데이터가 들어가진 시간을 넣어 주는게 좋지 않을까? 제대로 된 예시인지는 모르겠지만 뭐 어쨌든 그렇다는 거고.... 넘어가자.. 호다닥
이렇게 작업 대상이 되는 테이블 정보를 숙지함으로써 화면에서도 어떤 항목은 필수 체크하고 어떤 항목은 SQL 실행 시점에서 넣어 줄건지 인지도 하고 두루두루 좋은게 아니겠는가? 참고로 실제 프로젝트를 개발하면 ERD(entity-relationship diagram)를 보라는 소리를 왕왕 듣는다. ERD가 있으면 그거보고 하면 되는 ERD를 보는건 보는 거고 SQL을 작성하기 전 대상 테이블의 정보를 확인하는 습관은 좋을 것 같다. (ERD는 데이터 모델링 용어이므로 지금은 또 넘어가자.. 맨날 넘어네...)
3. index.jsp 수정하기
userSample.jsp로 이동하기 위해 사용했던 input='submit'을 button type으로 변경 조회, 등록 2개의 버튼으로 나누고 두 버튼은 어차피 xxx.jsp로 이동할 테니 같이 사용할 함수(function)를 만들어 클릭 이벤트를 붙여주자.
소스코드 :
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
olDevStudy Hello World!<br/>
<form id="testFrm" name="testFrm" >
<input type="button" onclick="fnPageChange('/userSample.jsp');" value="조회">
<input type="button" onclick="fnPageChange('/userRegistView.jsp');" value="등록">
</form>
</body>
<script type="text/javascript">
function fnPageChange(pageUrl) {
var frm = document.getElementById("testFrm");
frm.action = pageUrl;
frm.submit();
}
</script>
</html>
jquery는 사용하지는 않았고 소스코드를 좀 살펴보자면
javascript는 element(요소 즉 태그들)에 ducument로 접근하는데 이게 DOM Parser를.. 이해하면 쉬운데.. 그니깐 음... ducument가 문서고 get은 가져오기고.. element는 요소니깐... 지금 작성하는 문서(jsp)의 ID라는 요소가 testFrm인 녀석의 정보 가져와 정도로 이해하면 되겠다. 그래서 ID요소가 testFrm인 녀석을 찾고 보니 Form인 거고 해당 Form의 속성으로 action, submit이 있으니깐 java로 생각하면 new Class 하고 해당 메서드에 접근했다고 생각하면 쉬울 것 같다.
input='submit'은 사실 별로 쓸 일이 없다. 퍼블리싱 파일을 보면 간혹 써져있기도 하지만 <a> 태그나 <button> 태그를 주로 사용하는데 굳이 input='button'을 한 것은 복붙.... 뭐 그렇다. ㅎㅎ;;
두 버튼이 모두 페이지 이동이 주목적이기 때문에 하나의 함수에 인자로 page url 넘겨주었고 document를 이용해 form을 찾아 해당 page url을 설정하고 submit을 실해시켰다.
onclick="fnPageCh..." 이벤트를 주었는데 input 외에 다른 태그들에도 onclick뿐만 아니라 onmouseover, onkeydown 등등 많은 이벤트가 있으니 구글님께 문의드려가며 하나씩 익혀나가자. (절대 몰라서 그런 거 아니다! 구글님이 갓일 뿐...)
위 내용에서 잠시 DOM Parser 얘기를 꺼냈는데 SAX Parser도 있고 뭐.. 있는데 그냥 아 있구나 하고 넘어가자... 머리 아프다... 필요할 때 찾아보자... (그냥 document만 외우고 있자!)

수정하고 실행니깐... 정말 볼품없는 화면이지만 잘보인다. (보이면 됐지 뭐..)
4. 등록 화면 (userRegistView.jsp) 만들기
조회 때와 마찬가지로 index.jsp 등록 버튼을 클릭하면 userRegistView.jsp로 이동하자. (화면 설계서에 디자인, 퍼블리셔가 있는 건 아니니 html table tr/td로 대충 만들어보자.)
소스코드 :
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<body>
<form id="registFrm" name="registFrm" method="post">
<table style="border:1px solid blue;">
<tr>
<td>회원 아이디</td>
<td><input type="text" id="mberId" name="mberId"></td>
<td>회원 비밀번호</td>
<td><input type="text" id="mberPwd" name="mberPwd"></td>
</tr>
<tr>
<td>회원 이름</td>
<td><input type="text" id="mberNm" name="mberNm"></td>
<td>회원 휴대폰</td>
<td><input type="text" id="mberMoblphon" name="mberMoblphon"></td>
</tr>
<tr>
<td>비고</td>
<td colspan="3"><input type="text" id="rm" name="rm" style="width: 100%"></td>
</tr>
<tr>
<td colspan="4">
<div align="right">
<input type="button" onclick="fnUserRegist('/userRegist.jsp');" value="저장">
</div>
</td>
</tr>
</table>
</form>
</body>
<script type="text/javascript">
function fnUserRegist(pageUrl) {
var frm = document.getElementById("registFrm");
frm.action = pageUrl;
frm.submit();
}
</script>
소스코드를 살펴보면 index.jsp 와 뭐 크게 다르지 않다.
등록 화면을 만든다고 했는데 진짜 등. 록. 화. 면. 만 만든 것 같다? DB Connection 같은거 쓰고 막 SQL 있어야 할 것 같고 막 그래야 할 것 같은데 왜?! 없지?!라고 생각이 들면 좋겠다... 왜 그런 애들이 하나도 없냐면 JSP가 컴파일되면 스크립트릿이 선순위로 컴파일된다고 했지 않은가? 후순위인 html 태그를 알 길도 없고 input에는 값이 있지도 않다.
그래서 우리는 진짜 insert를 처리해주는 userRegist.jsp를 하나 더 만들어야 한다. 왜 userRegistView.jsp라고 파일을 만들었는지 이해가 되지 않는가? DB에 저장하는 애들 따로 만들어야 하니깐 그랬지~ 아무튼 등록 화면에서 사용된 html 관련된 내용은 구글님께 여쭙기로 하고 기왕 만든 화면 캡처하나 해서 뿌듯함이나 좀 느껴보자.

완성된 화면을 보고 뿌듯함이나 만끽하자. (저장버튼 위치도 기똥차게 맞춘 듯?!)
5. 진짜 등록하기 (Insert SQL 수행)
userRegistView.jsp에서 입력된 데이터를 받아서 Insert SQL을 수행할 userRegist.jsp를 만들어보자.
Servelet Request를 좀 알아야 하는데 요고 건너뛰자 사실 JSP는 컴파일될 때 HttpServlet을 상속한 상태로 컴파일된다.
Request를 내장 객체로 사용할 수 있다는 말이다! 그래서 그냥 아 내가 Form에 데이터 담아서 보내면 Request로 받아내면 되는구나 정도만 보자. (Request, Response는 차차 얘기하는 걸로...)
소스코드 :
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.SQLException" %>
<%@ page import="java.sql.Statement" %>
<%@ page import="java.sql.ResultSet" %>
<%
Connection dbConn = null;
try {
String mberId = request.getParameter("mberId");
String mberPwd = request.getParameter("mberPwd");
String mberNm = request.getParameter("mberNm");
String mberMoblphon = request.getParameter("mberMoblphon");
String rm = request.getParameter("rm");
Class.forName("org.mariadb.jdbc.Driver");
dbConn = DriverManager.getConnection(
"jdbc:mariadb://127.0.0.1:3306/oldev"
, "olDev"
, "olDev@1234"
);
Statement stmt = dbConn.createStatement();
String sqlStr = "";
sqlStr += "INSERT INTO OD_MBER ";
sqlStr += "( ";
sqlStr += " MBER_ID ";
sqlStr += ", MBER_PWD ";
sqlStr += ", MBER_NM ";
sqlStr += ", MBER_MOBLPHON ";
sqlStr += ", RM ";
sqlStr += ", REGIST_SN ";
sqlStr += ", REGT_DTTM ";
sqlStr += ", UPDT_SN ";
sqlStr += ", UPDT_DTTM ";
sqlStr += ") ";
sqlStr += "VALUES ";
sqlStr += "( ";
sqlStr += " '"+mberId+"' ";
sqlStr += ", '"+mberPwd+"' ";
sqlStr += ", '"+mberNm+"' ";
sqlStr += ", NULLIF('"+mberMoblphon+"', '') ";
sqlStr += ", NULLIF('"+mberId+"', '') ";
sqlStr += ", '0' ";
sqlStr += ", DATE_FORMAT(NOW(), '%Y%m%d%H%i%s') ";
sqlStr += ", '0' ";
sqlStr += ", DATE_FORMAT(NOW(), '%Y%m%d%H%i%s') ";
sqlStr += ") ";
int resultNum = stmt.executeUpdate(sqlStr);
if (resultNum < 1) {
%>
<script type="text/javascript">
alert("등록에 실패했어요!");
location.href="/userRegistView.jsp";
</script>
<%
} else {
%>
<script type="text/javascript">
alert("등록이 완료되었습니다.");
location.href="/";
</script>
<%
}
} catch (SQLException e) {
e.printStackTrace();
}
%>
소스코드를 보면 Insert SQL은 HeidSql에서 등록할 때 홍길동으로 고정되었던 내용을 userRegistView.jsp에 입력된 내용을 넣어야 하니깐 request.getParameter로 받아서 변수 처리했다는 정도의 차이뿐이다.
그리고 앞서 이야기한 데로 request 객체가 사용됐는데 잠깐만 살펴보면 getParameter에서 추출하는 데이터 변수명이 입력화면(userRegistView.jsp)의 input 태그 id="", name="" 속성명과 같은 명이 사용되었다.
input의 id="", name=""이 동일한 것은 개발의 편의성을 위해서 같은 명을 사용한 것이고 request에는 id=""가 아니라 name="" 명으로 매핑이 되게 되는데 http request의 데이터 전송 룰이다. 못 바꾼다 그래서 데이터 처리를 할 때 name=""에 설정한 명과 getParameter의 찾을 변수명이 일치해야 한다.
스크립트릿도 한번 살펴보자 여타 html 코드는 없고 <script type="text/javascript"> 태그 속에 alert과 location.href만 덜렁 있다.
JSP가 컴파일되고 browser 쏴줄 때는 html이라 하지 않았던가? 여기 html의 <input type="text">같은걸 넣어주면 보이지 않을까? 당연히 보인다. Insert SQL만 수행하면 되는데 보여줄게 뭐가 있겠는가? 그래서 완료. 실패에 대한 알림만 주고 location.href="/" 명령을 통해 index.jsp로 보내주었다. "/" 이 녀석은 --> http://localhot:8080/ <-- 요놈인데 "/"를 root path라 읽는다. 개발에서 root는 더 이상 올라갈 수 없는 최상단이고 http://localhost:8080/ 요놈보다 더 위에 뭐가 있나? 없다. 그래서 그런 거다.
Statement 객체도 그대로 사용했고 method만 executeQuery를 executeUpdate로 사용했는데 해당 method는 insert, update, delete가 수행되고 영향을 미친게 있으면 1 없으면 0을 return 해준다. 즉 update나 delete와 같이 수정 또는 삭제가 되어야는데 조건에 해당하는 값이 없으면 0을 주겠단거다. insert는 안들어갔으면 오류였겠지... 그래서 요고 뒤에서 좀 활용해보기로 하자.
소스코드 마지막으로 Insert SQL을 살펴보면 등록자, 수정자 뭐 이런거 insert, update 할 때 넣는다 하지 않았었나? 라고 의문이 생길수 있다. 쩝.. 테이블 잘 못 만들었다... oracle Sequence를 헤깔려갖고.. ㅠ 일단 0으로 고정해놓고 수정, 삭제까지 대충 만들어 놓고 상세하게 만들때 다뤄보자.. mariadb, mysql ...아놔 진짜...
기왕 만들었으니깐 아이디 test2, 이름 홍길순으로 데이터를 넣어보자.

HeidSql로 데이터를 확인해보자.

어라? 이름에 저거 무슨 멍멍이 변같은... request character set 설정은 낸중에 해주자 어쨌든 데이터가 들어는 갔잖아? 그럼 된걸로...
오늘 목표는 채웠으니 현재까지 프로젝트 구조를 끝으로 마무리하고 다음은 수정과 삭제를 다뤄보자.

'JAVA_JSP' 카테고리의 다른 글
| 초보의 JSP 개발 다듬기 (1) | 2020.11.16 |
|---|---|
| 초보의 JSP 개발 데이터 수정, 삭제 (0) | 2020.11.13 |
| 초보의 JSP 개발 데이터 조회하기 (0) | 2020.11.11 |
| 초보의 JSP 개발 DB Table 생성 (0) | 2020.11.10 |
| 초보의 JSP 개발 JSP Servlet 비교 (0) | 2020.11.09 |
댓글