0. MySQL DB생성, Table생성
create database lmsdb;
use lmsdb;
create table membertbl (
userid char(20) primary key not null,
pwd char(20) not null,
name char(20) not null,
email char(20)
);
desc lmsdb.membertbl;
1. 사용자(Client)의 요청(Request)(VIEW)
index.jsp
memberInsert.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<%@ 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>
<form action=memberInsert.do>
ID : <input name=userid><br>
PW : <input name=pwd><br>
NAME : <input name=name><br>
EMAIL : <input name=email><br>
<input type=submit value=가입>
</form>
<a href="/HTMLCSSJS/Ch18JSP/VIEW/index.jsp">첫화면 이동</a>
</body>
</html>
|
cs |

url 패턴에 의해 <servlet-class>에 작성한 주소로 이동하게 된다.
여기선 다음과 같이 작성해주자(주의 : 위 그림은 예시!)
1
2
3
4
5
6
7
8
9
10
11
12
|
<servlet>
<servlet-name>FrontControl</servlet-name>
<servlet-class>Ch18.controller.FrontController</servlet-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>FrontControl</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
|
cs |
*형식으로 지정했기 때문에, 클라이언트가 요청하는 URL 값의 패턴과 무관하게 항상 수행된다.

사용자가 내용을 입력하면 <form action=memberInsert.do>에 의해 Servlet에서 Controller로 mapping해서 보낸다
2. Controller(Servlet)가 요청을 받아 처리
request 객체의 메소드에 자세히 알고 싶다면 다음을 참고하자
(http://www.devkuma.com/books/pages/1190)
HttpServlet클래스를 상속받은 Controller가 실행되고
1. init()메서드가 실행되면서
참조변수 list에 Map형태로 객체를 생성해 저장하고
그 list에
String타입의 jsp주소를 Map의 키(Key)로 저장하고,
Controller타입으로 "기능객체"를 생성하여 값(Value)로 저장(list.put())한다.
2. service()메서드가 실행되면서
action태그로 jsp에서 실행되는 주소를 가져와(Key이기 때문에 그 키에 해당하는 값을 가져올 수 있음)
list.get()메서드로 실행할 "기능객체"의 주소값을(Value)
Controller인터페이스의 controller 참조변수에 담는다(controller인터페이스는 아래 코드 참고, ).
Controller인터페이스의 execute()메소드를 실행하면
service()메소드에서 매개변수로 받은 request와 response가 담겨
해당 기능객체(MemberInsertController.java)의 오버라이딩된 execute()메서드가 실행된다.↓
public class MemberInsertController implements Controller { @Override public void execute(HttpServletRequest request, HttpServletResponse response) { System.out.println("---------------------------------"); System.out.println("MemberInsertController의 처리중"); System.out.println("---------------------------------"); System.out.println("1) 파라미터 값 추출"); |
FrontController.java
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
31
32
33
34
35
36
37
38
39
40
41
|
package Ch18.controller;
import java.io.IOException;
import java.util.HashMap;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class FrontController extends HttpServlet{
HashMap<String, Controller> list = null; //Key : URL주소 저장, Value : 기능별(De, In, Se, Update)Controller객체들을 저장
@Override
public void init() throws ServletException {
System.out.println("---------------------------------");
System.out.println("FrontController의 init() 메서드 실행!");
System.out.println("---------------------------------");
list = new HashMap();
list.put("/HTMLCSSJS/Ch18JSP/VIEW/memberInsert.do", new MemberInsertController());
list.put("/HTMLCSSJS/Ch18JSP/VIEW/memberSearch.do", new MemberSearchController());
list.put("/HTMLCSSJS/Ch18JSP/VIEW/memberUpdate.do", new MemberUpdateController());
list.put("/HTMLCSSJS/Ch18JSP/VIEW/memberDelete.do", new MemberDeleteController());
list.put("/HTMLCSSJS/memberList.do", new MemberListController());
}
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("---------------------------------");
System.out.println("FrontController의 service() 메서드 실행!");
System.out.println("---------------------------------");
System.out.println("1. 클라이언트의 Action URL경로를 받아 해당 기능 처리 객체의 execute() 실행");
String URL = request.getRequestURI(); //action경로 받아옴, URL에서 스키마, 서버이름, 포트번호를 제외한 나머지 주소와 파라미터
//참고 : http://www.devkuma.com/books/pages/1190
System.out.println("URL : " + URL);
Controller controller = list.get(URL); //Map에서 해당 action경로에 대한 기능객체를 가져옴
controller.execute(request, response); //해당기능객체를 실행
}
}
|
cs |
Controller.java
1
2
3
4
5
6
7
8
9
10
|
package Ch18.controller;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public interface Controller { //interface 강제성!
void execute(HttpServletRequest request, HttpServletResponse response);
}
|
cs |
MemberInsertController.java
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
package Ch18.controller;
import Ch18.service.MemberService;
import Ch18.vo.MemberVO;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class MemberInsertController implements Controller {
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) {
System.out.println("---------------------------------");
System.out.println("MemberInsertController의 처리중");
System.out.println("---------------------------------");
System.out.println("1) 파라미터 값 추출");
//파라미터 정보 가져오기(클라이언트에서 요청한 정보?)
String userid = request.getParameter("userid");
String pwd = request.getParameter("pwd");
String name = request.getParameter("name");
String email = request.getParameter("email");
//입력값 검증
System.out.println("2) 입력값 검증 -> 잘못된 값 전달 시 다시 HttpUtil.forward()사용");
if(userid.isEmpty() || pwd.isEmpty() || name.isEmpty() || email.isEmpty())
{
//다시 memberinsert로 이동(HttpUtil.java에서 처리)
request.setAttribute("error", "올바른 값이 입력되지 않았습니다");
HttpUtil.forward(request, response, "/Ch18JSP/VIEW/memberInsert.jsp");
}
//MemberVO에 값 설정
System.out.println("3) 멤버정보 VO에 저장");
MemberVO member = new MemberVO(userid, pwd, name, email);
//Service 실행(저장?)
System.out.println("4) Service 실행 -> MemberService의 MemberJoin()함수 실행");
MemberService service = MemberService.getInstance();
service.MemberJoin(member);
//DAO -> DB연결 + 값 삽입/수정/삭제
//service객체 -> DAO객체 이용해서 삽입함수를 사용하여 멤버정보삽입
//결과를 화면으로 구현
System.out.println("5) 결과페이지로 이동 -> HttpUtil.forward() 사용");
request.setAttribute("userid", userid);
//유저ID를 포함한 정보를 /HTMLCSSJS/Ch18JSP/RESULT/memberInsertOutput.jsp로 전달
HttpUtil.forward(request, response, "/Ch18JSP/RESULT/memberInsertOutput.jsp");
}
}
|
cs |
//파라미터 정보를 가져오면서
//입력값을 검증하고 올바른 값이 입력되지 않았을 시엔 다시 회원가입하는 페이지로 보내는 작업을 수행한다.
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
|
package Ch18.controller;
import java.io.IOException;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class HttpUtil {
public static void forward(HttpServletRequest req, HttpServletResponse resp, String URL)
{
RequestDispatcher disp = req.getRequestDispatcher(URL);
try {
disp.forward(req, resp);
} catch (ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
|
cs |
회원가입페이지로 다시 돌려보낼 때 사용하는 HttpUtil클래스의 forward()메서드
3. Model(java파일)에 입력값들을 전달하고 저장
//MemberVO에 값 설정
부분에 MemberVO member = new MemberVO(userid, pwd, name, email);
로 파라미터로 받아온 값들을 저장해주고 있다.
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
package Ch18.vo;
//DTO(Data Transfer Object0
//계층간 데이터 교환을 위한 자바빈즈를 의미
//값 저장과 값확인 모두 가능(getter/setter함수 존재)
//VO에 비해 사용효율성이 높으나 보안적인 측면에서 다소 취약
//값의 수정이 가능
//VO(Value Object)
//계층간 데이터 교환을 위한 자바빈즈를 의미
//VO객체의 값은 저장만 가능(getter함수만 존재)하다(ReadOnly)
public class MemberVO {
String userid;
String pwd;
String name;
String email;
//생성자
public MemberVO(String userid, String pwd, String name, String email)
{
this.userid=userid; this.pwd=pwd; this.name=name; this.email=email;
}
public MemberVO(String userid2, String pwd2) {
this.userid=userid2; this.pwd=pwd2;
}
//getter만!
public String getUserid() {
return userid;
}
public String getPwd() {
return pwd;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
}
|
cs |
4. Service실행(DB연결 및 저장)
MemberInsertController.java에서
MemberService service = MemberService.getInstance(); service.MemberJoin(member); |
가 실행되면서 MemberService클래스의 MemberJoin()메서드가 실행된다.
MemberJoin()메서드는 DAO객체의 주소와 연결이 되면서
dao.MemberJoin(member);메서드가 실행이되고
MemberService.java
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
package Ch18.service;
import Ch18.dao.MemberDAO;
import Ch18.vo.MemberVO;
public class MemberService {
//DB처리 객체 받아옴
public MemberDAO dao = MemberDAO.getInstance();
//싱글톤 패턴 구현
private static MemberService service = new MemberService();
private MemberService() {}
public static MemberService getInstance() {
return service;
}
public void MemberJoin(MemberVO member) {
System.out.println("---------------------------------");
System.out.println("MemberService의 MemberJoin() 메서드 사용");
System.out.println("---------------------------------");
System.out.println("DAO객체의 MemberJoin(member)메서드로 DB연결 후 회원정보 INSERT 처리");
dao.MemberJoin(member);
System.out.println("DAO객체의 MemberJoin(member)메서드로 DB연결 후 회원정보 INSERT 완료");
}
// public void MemberUpdate(MemberVO member) {
// System.out.println("---------------------------------");
// System.out.println("MemberService의 MemberUpdate() 메서드 사용");
// System.out.println("---------------------------------");
// System.out.println("DAO객체의 MemberUpdate(member)메서드로 DB연결 후 회원정보 UPDATE 처리");
// dao.MemberUpdate(member);
// System.out.println("DAO객체의 MemberUpdate(member)메서드로 DB연결 후 회원정보 UPDATE 완료");
// }
// public MemberVO MemberSearch(String userid, String pwd) {
// System.out.println("---------------------------------");
// System.out.println("MemberService의 MemberUpdate() 메서드 사용");
// System.out.println("---------------------------------");
// System.out.println("DAO객체의 MemberUpdate(member)메서드로 DB연결 후 회원정보 UPDATE 처리");
// dao.Member();
// System.out.println("DAO객체의 MemberUpdate(member)메서드로 DB연결 후 회원정보 UPDATE 완료");
// return null;
// }
// public void MemberDelete(String userid) {
//
// }
// public ArrayList<MemberVO> MemberList(MemberVO member) {
//
// }
}
|
cs |
MemberDAO.java의 MemberJoin()메서드는
DBConnection매니저를 사용해서 하나의 객체만 사용함으로
사용자의 무한한 객체 생성을 제어하고
DB에 연결함과 동시에(22번째 줄)
(입력받은 값들과 함께) SQL명령어를 전달한다(23~27)
SQL명령어가 실행된 결과를 result변수에 담고
finally에서 자원을 제거해주면서 끝이난다.
MemberDAO.java
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
package Ch18.dao;
import Ch18.vo.MemberVO;
import java.sql.*;
public class MemberDAO {
DBConnectionMgr pool = DBConnectionMgr.getInstance();
//싱글턴패턴
private static MemberDAO instance = new MemberDAO();
private MemberDAO() {}
public static MemberDAO getInstance()
{
return instance;
}
public void MemberJoin(MemberVO member) {
Connection conn = null;
PreparedStatement pstmt = null;
try
{
conn = pool.getConnection();
pstmt = conn.prepareStatement("insert into membertbl values(?,?,?,?)"); //전달할 SQL 지정
pstmt.setString(1, member.getUserid());
pstmt.setString(2, member.getPwd());
pstmt.setString(3, member.getName());
pstmt.setString(4, member.getEmail());
int result = pstmt.executeUpdate();
System.out.println("쿼리 전송이후 변화된 행의 수 : " + result);
}catch(Exception e) {
e.printStackTrace();
}finally {
pool.freeConnection(conn, pstmt);
}
}
// public void MemberSearch(MemberVO member)
// {
// Connection conn=null;
// PreparedStatement pstmt = null;
// ResultSet rs = null; //조회
//
// }
// public void MemberUpdate(MemberVO member) {
// Connection conn = null;
// PreparedStatement pstmt = null;
// try
// {
// conn = pool.getConnection();
// pstmt = conn.prepareStatement("update membertbl set pwd=?, name=?, email=? where userid=?"); //전달할 SQL 지정
// pstmt.setString(1, member.getPwd());
// pstmt.setString(2, member.getName());
// pstmt.setString(3, member.getEmail());
// pstmt.setString(4, member.getUserid());
// int result = pstmt.executeUpdate();
// System.out.println("쿼리 전송이후 변화된 행의 수 : " + result);
//
// }catch(Exception e) {
// e.printStackTrace();
// }finally {
// pool.freeConnection(conn, pstmt);
// }
// }
// public void MemberDelete() {
//
// }
// public void MemberList() {
//
// }
}
|
cs |
DBConnectionMgr.java
(다 읽을 수 있다면 읽으면 좋다. 간단하게 무한한 객체 생성을 방지하는 관리시스템 정도로 보면 될 것 같다.
그리고 사용할 때는 Driver주소와 _url주소와 아이디 패스워드를 꼭 사용하고자하는 DB에 맞게 수정하자.)
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
|
/**
* Copyright(c) 2001 iSavvix Corporation (http://www.isavvix.com/)
*
* All rights reserved
*
* Permission to use, copy, modify and distribute this material for
* any purpose and without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies, and that the name of iSavvix Corporation not be used in
* advertising or publicity pertaining to this material without the
* specific, prior written permission of an authorized representative of
* iSavvix Corporation.
*
* ISAVVIX CORPORATION MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES,
* EXPRESS OR IMPLIED, WITH RESPECT TO THE SOFTWARE, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR ANY PARTICULAR PURPOSE, AND THE WARRANTY AGAINST
* INFRINGEMENT OF PATENTS OR OTHER INTELLECTUAL PROPERTY RIGHTS. THE
* SOFTWARE IS PROVIDED "AS IS", AND IN NO EVENT SHALL ISAVVIX CORPORATION OR
* ANY OF ITS AFFILIATES BE LIABLE FOR ANY DAMAGES, INCLUDING ANY
* LOST PROFITS OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES RELATING
* TO THE SOFTWARE.
*
*/
package dao;
import java.sql.*;
import java.util.Properties;
import java.util.Vector;
/**
* Manages a java.sql.Connection pool.
*
* @author Anil Hemrajani
*/
public class DBConnectionMgr {
private Vector connections = new Vector(10);
private String _driver = "com.mysql.cj.jdbc.Driver",
_url = "jdbc:mysql://localhost:3306/lmsdb?useUnicode=true&characterEncoding=UTF-8",
_user = "root",
_password = "1234";
private boolean _traceOn = false;
private boolean initialized = false;
private int _openConnections = 10; //기본값 10
private static DBConnectionMgr instance = null; //싱글턴패턴
public DBConnectionMgr() {
}
/** Use this method to set the maximum number of open connections before
unused connections are closed.
*/
public static DBConnectionMgr getInstance() { //싱글턴패턴, 관리객체는 하나만 만듦
if (instance == null) {
synchronized (DBConnectionMgr.class) {
if (instance == null) {
instance = new DBConnectionMgr();
}
}
}
return instance;
}
public void setOpenConnectionCount(int count) {
_openConnections = count;
}
public void setEnableTrace(boolean enable) {
_traceOn = enable;
}
/** Returns a Vector of java.sql.Connection objects */
public Vector getConnectionList() {
return connections;
}
/** Opens specified "count" of connections and adds them to the existing pool */
public synchronized void setInitOpenConnections(int count) //추가로 확장시킨 연결객체
throws SQLException {
Connection c = null;
ConnectionObject co = null;
for (int i = 0; i < count; i++) {
c = createConnection();
co = new ConnectionObject(c, false);
connections.addElement(co);
trace("ConnectionPoolManager: Adding new DB connection to pool (" + connections.size() + ")");
}
}
/** Returns a count of open connections */
public int getConnectionCount() {
return connections.size();
}
/** Returns an unused existing or new connection. */
public synchronized Connection getConnection() //★
throws Exception {
if (!initialized) { //초기화 되어있지 않으면
Class c = Class.forName(_driver); //드라이버에 적재
DriverManager.registerDriver((Driver) c.newInstance());
initialized = true;
}
Connection c = null;
ConnectionObject co = null;
boolean badConnection = false;
for (int i = 0; i < connections.size(); i++) { //10
co = (ConnectionObject) connections.get(i); //i번째 커넥션오브젝트 객체
// If connection is not in use, test to ensure it's still valid!
if (!co.inUse) { //사용중이지 않다면
try {
badConnection = co.connection.isClosed(); //닫혀있으면? true 열려있으면? false
if (!badConnection) //false면 올바르게 연결되어있지 않음(사용중이 아닌데 열려있다??) ↓아래와 같이 처리
badConnection = (co.connection.getWarnings() != null); //true넣기
} catch (Exception e) {
badConnection = true;
e.printStackTrace();
}
// Connection is bad, remove from pool
if (badConnection) { //연결객체가 문제가 있다면
connections.removeElementAt(i); //해당연결객체 제거
trace("ConnectionPoolManager: Remove disconnected DB connection #" + i); //문제가 있다고 화면에 출력
continue; //다음요소 확인 //false라면 아래 코드로 이동
}
c = co.connection;
co.inUse = true; //사용중으로 바꿈
trace("ConnectionPoolManager: Using existing DB connection #" + (i + 1)); //표시
break;
}
}
if (c == null) {
c = createConnection();
co = new ConnectionObject(c, true);
connections.addElement(co);
trace("ConnectionPoolManager: Creating new DB connection #" + connections.size());
}
return c;
}
/** Marks a flag in the ConnectionObject to indicate this connection is no longer in use */
public synchronized void freeConnection(Connection c) {
if (c == null)
return;
ConnectionObject co = null;
for (int i = 0; i < connections.size(); i++) {
co = (ConnectionObject) connections.get(i);
if (c == co.connection) {
co.inUse = false;
break;
}
}
for (int i = 0; i < connections.size(); i++) {
co = (ConnectionObject) connections.get(i);
if ((i + 1) > _openConnections && !co.inUse)
removeConnection(co.connection);
}
}
public void freeConnection(Connection c, PreparedStatement p, ResultSet r) { //오버로딩
try {
if (r != null) r.close();
if (p != null) p.close();
freeConnection(c);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void freeConnection(Connection c, Statement s, ResultSet r) {
try {
if (r != null) r.close();
if (s != null) s.close();
freeConnection(c);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void freeConnection(Connection c, PreparedStatement p) {
try {
if (p != null) p.close();
freeConnection(c);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void freeConnection(Connection c, Statement s) {
try {
if (s != null) s.close();
freeConnection(c);
} catch (SQLException e) {
e.printStackTrace();
}
}
/** Marks a flag in the ConnectionObject to indicate this connection is no longer in use */
public synchronized void removeConnection(Connection c) { //연결 객체 제거
if (c == null)
return;
ConnectionObject co = null;
for (int i = 0; i < connections.size(); i++) {
co = (ConnectionObject) connections.get(i);
if (c == co.connection) {
try {
c.close();
connections.removeElementAt(i);
trace("Removed " + c.toString());
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}
}
private Connection createConnection() //연결객체 추가할 때 createConnection() 위 코드에 있음
throws SQLException {
Connection con = null;
try {
if (_user == null)
_user = "";
if (_password == null)
_password = "";
Properties props = new Properties(); //map과 유사 키와 값 넣을 수 있음
props.put("user", _user);
props.put("password", _password);
con = DriverManager.getConnection(_url, props);
} catch (Throwable t) {
throw new SQLException(t.getMessage());
}
return con;
}
/** Closes all connections and clears out the connection pool */
public void releaseFreeConnections() {
trace("ConnectionPoolManager.releaseFreeConnections()");
Connection c = null;
ConnectionObject co = null;
for (int i = 0; i < connections.size(); i++) {
co = (ConnectionObject) connections.get(i);
if (!co.inUse)
removeConnection(co.connection);
}
}
/** Closes all connections and clears out the connection pool */
public void finalize() {
trace("ConnectionPoolManager.finalize()");
Connection c = null;
ConnectionObject co = null;
for (int i = 0; i < connections.size(); i++) {
co = (ConnectionObject) connections.get(i);
try {
co.connection.close();
} catch (Exception e) {
e.printStackTrace();
}
co = null;
}
connections.removeAllElements();
}
private void trace(String s) {
if (_traceOn)
System.err.println(s);
}
}
class ConnectionObject {
public java.sql.Connection connection = null;
public boolean inUse = false;
public ConnectionObject(Connection c, boolean useFlag) {
connection = c;
inUse = useFlag;
}
}
|
cs |
5. 결과를 화면으로 구현(VIEW)
DAO의 MemberJoin()메서드가 끝이나면,
여전히 아직 MemberInsertController.java의 execute()메서드가 실행중이기 때문에 돌아오게 되고
마지막 결과를 화면으로 구현하는 작업을 코드로 수행하게 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<%@ 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>
<h1>멤버가입확인</h1>
<%
String userid = request.getParameter("userid");
%>
<%=userid %>님 가입 완료!!<br>
<a href="/HTMLCSSJS/Ch18JSP/VIEW/index.jsp">첫번째페이지로 이동</a>
</body>
</html>
|
cs |

마지막으로 정리..
Console 창을 보면 System.out.println()으로
"임의적으로 넣은 문자열들"이 실행되고 있음을 알 수 있는데,
이렇게 Console창을 통해 각각의 파일들이
어떤 순서로 실행되는지를 확인할 수 있다.
이 Console창을 보고
전체적인 실행 흐름이 어떻게 되는지 따라가보며 정리해보았다.
MVC모델2의 실행 과정
index.jsp → memberinsert.jsp |
Client | 입력 View |
||
→ web.xml(servlet -name> -class>Ch18.controller-Frontcontroller servlet -mapping> url-pattern>*.do) → FrontController.java(Hashmap<string, controller=""></string,> init()메서드에 list.put()메서드로 map에 담고 service()메서드의 list.get(URL)메서드로 Map에서 해당 action경로에 대한 기능객체 불러옴 Controller인터페이스의 참조변수 controller에 list.get()으로 가져온 기능객체를 담음 controller.execute(request, response)로 해당 기능객체 실행) |
연결 Cont- roller |
|||
→ 기능객체 MemberInsertConroller.java(implements Controller) 실행 execute(H..S..Rq reqest, H..S..Rp response) 오버라이딩 메서드 실행 //파라미터 정보 가져오기 //입력값 검증하기 //MemberVO에 값 설정(클래스 필드에 입력받은 값들을 (파라미터정보로 가져와) 저장) MemberVo member = new MemberVO(userid, pwd, name, email); → MemberVO.java |
저장 Model |
|||
//Service실행하기 MemberService service = MemberService.getInstance(); service.MemberJoin(member); //MemberVO에 저장된 값을 Service객체로 전달해서 실행 → MemberService.java의 MemberJoin(MemberVO member)메서드 실행 {dao.MemberJoin(member)} *DB처리하는 코드를 가진 객체의 MemberJoin(MemberVO member)메서드 실행 여기서 사용자의 입력값을 저장한 VO(주소값)를 SQL명령어를 사용하여 DB에 연결해서 저장 → MemberDAO.java의 MemberJoin(MemberVO member)메서드.. {Connection.. PreParedStatement ... ...getConnection();... ...prepareStatement("insert into table... values(?, ?, ?, ?)")... ...executeUpdate();... } |
연결 및 저장 DB |
|||
//MemberInsertController.java로 돌아와 결과를 화면으로 구현 request.setAttribute("userid", userid); HttpUtil.forward(request, response, "/Ch18JSP/RESULT/memberInsertOutput.jsp"); → HTTPUtil.java → MemberInsertOutput.jsp 첫번째 페이지로 이동 클릭하면 다시 index.jsp에서 시작! |
출력 View |
db나 table 생성을 하지 않았을 때 에러
db나 table을 생성하지 않으면 DB로 전달하여 저장하는 순서에서
다음과 같이 에러가 발생함을 알 수 있다.
--------------------------------- FrontController의 init() 메서드 실행! --------------------------------- --------------------------------- FrontController의 service() 메서드 실행! --------------------------------- 1. 클라이언트의 Action URL경로를 받아 해당 기능 처리 객체의 execute() 실행 URL : /HTMLCSSJS/Ch18JSP/VIEW/memberInsert.do --------------------------------- MemberInsertController의 처리중 --------------------------------- 1) 파라미터 값 추출 2) 입력값 검증 -> 잘못된 값 전달 시 다시 HttpUtil.forward()사용 3) 멤버정보 VO에 저장 4) Service 실행 -> MemberService의 MemberJoin()함수 실행 --------------------------------- MemberService의 MemberJoin() 메서드 사용 --------------------------------- DAO객체의 MemberJoin(member)메서드로 DB연결 후 회원정보 INSERT 처리 java.sql.SQLSyntaxErrorException: Table 'lmsdb.membertbl' doesn't exist |
따라서 꼭 실행하기 전에 Server단에서
입력받은 값들을 저장할 DB와 Table을 미리 생성해야 한다.
참고 : Table생성할 때 볼 만한 글(not null에 대한 정보)
http://tcpschool.com/mysql/mysql_constraint_notNull
코딩교육 티씨피스쿨
4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등
tcpschool.com
'코딩 > JDBC_JavaDatabaseConnectivity' 카테고리의 다른 글
JDBC_execute, executeQuery, executeUpdate메서드 (0) | 2021.08.09 |
---|---|
JDBC_ResultSet을 통해 결과값을 불러오기 (0) | 2021.08.05 |
DBConnectionMgr?_Vector_Singleton패턴 (0) | 2021.07.29 |
JDBC_MySQL명령어 정리 (0) | 2021.07.28 |
JDBC 데이터베이스 연결(Connect)이 안될 때 해결 방법 (0) | 2021.07.27 |