데이터를 등록했으니 수정도 해보고 삭제도 해보자. 기능이 딸랑 조회에서 등록, 수정, 삭제도 생기니 Connection Resource를 좀 닫아줄 필요가 있겠다.
1. 목표
회원 상세에서 수정, 삭제 기능을 추가하고 Connection도 알아보자.
- 회원 상세에서 수정, 삭제 버튼을 붙이자.
- 수정 Servlet과 삭제 Servlet을 생성하고 Servlet Mapping 하자
- 각 Servlet에서 SQL을 작성하고 Connection을 알아보자.
- 각 Servlet은 회원 상세로 forward 해서 알림을 띄우고 회원 목록으로 이동하자.
2. 회원 상세 수정 (mberDetailView.jsp)
버튼을 추가하자. 앞서 작업해둔 회원 상세에 버튼만 추가됐으니 추가된 내용만 살짝 보자.
소스코드 :
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<script src="https://code.jquery.com/jquery-3.5.0.js"></script>
<body>
<form id="mberDetailFrm">
<table style="border:1px solid blue;">
<tr>
...
</tr>
<tr>
<td colspan="5">
<div align="right">
<a href="javascript:void(0);" id="btnMberRemove" style="text-decoration:none; border:1px solid; background-color: lightgreen;">회원삭제</a>
<a href="javascript:void(0);" id="btnMberModify" style="text-decoration:none; border:1px solid; background-color: lightgreen;">회원수정</a>
<a href="javascript:void(0);" id="mberListBack" style="text-decoration:none; border:1px solid; background-color: lightgreen;">목록</a>
</div>
</td>
</tr>
</table>
</form>
</body>
<script type="text/javascript">
var isResultType = "${resultType}";
var isResultCode = "${resultCode}";
$(document).ready(function(){
// 삭제
$("#btnMberRemove").click(function() {
var frm = $("#mberDetailFrm");
frm.attr("method", "post");
frm.attr("action", "/mberRrmove.do");
frm.submit();
});
// 수정
$("#btnMberModify").click(function() {
var frm = $("#mberDetailFrm");
frm.attr("method", "post");
frm.attr("action", "/mberModify.do");
frm.submit();
});
// 목록으로
$("#mberListBack").click(function() {
var frm = $("#mberDetailFrm");
frm.attr("method", "post");
frm.attr("action", "/mberList.do");
frm.submit();
});
// 결과가 들어온다면
if (isResultType != "" && isResultType != null && isResultType != undefined) {
// 수정일때
if (isResultType == "U") {
// 정상
if (isResultCode > 0) {
alert("수정이 완료되었습니다.");
$("#mberListBack").trigger("click");
// 실패
} else {
alert("수정이 실패했습니다.");
}
}
// 삭제일때
if (isResultType == "D") {
//정상
if (isResultCode > 0) {
alert("삭제를 완료되었습니다.");
$("#mberListBack").trigger("click");
//실패
} else {
alert("삭제를 실패했습니다.");
}
}
}
});
</script>
등록에서 작업했던 내용이 고스란히 담겨있다. Servlet에서 forward로 데이터를 받아 el로 javascript 변수에 할당하고 그 결과에 따라 분기 처리 후 목록으로 보내거나 화면을 유지하거나 해서 뭐 별로 특별할 건 없다.
3. 회원 수정 (MberModifyServlet.java)
JSP 개발에서 사용했던 내용을 그대로 복붙 하자. 내용도 비슷하니 doPost만 슬쩍 살펴보자.
소스코드 :
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
Connection dbConn = null;
int resultNum = 0;
try {
String paramMberSn = req.getParameter("mberSn");
String paramMberPwd = req.getParameter("mberPwd");
String paramMberNm = req.getParameter("mberNm");
String paramMberMp = req.getParameter("mberMoblphon");
String paramRm = req.getParameter("rm");
Class.forName("org.mariadb.jdbc.Driver");
dbConn = DriverManager.getConnection(
"jdbc:mariadb://127.0.0.1:3306/oldev"
, "olDev"
, "olDev@1234"
);
dbConn.setAutoCommit(false);
Statement stmt = dbConn.createStatement();
String sqlStr = "";
sqlStr += "UPDATE OD_MBER ";
sqlStr += " SET UPDT_SN = '"+paramMberSn+"' ";
sqlStr += " , UPDT_DTTM = DATE_FORMAT(NOW(), '%Y%m%d%H%i%s') ";
if (!"".equals(paramMberPwd) && paramMberPwd != null) {
sqlStr += " , MBER_PWD = '"+paramMberPwd+"' ";
}
if (!"".equals(paramMberNm) && paramMberNm != null) {
sqlStr += " , MBER_NM = '"+paramMberNm+"' ";
}
if (!"".equals(paramMberMp) && paramMberMp != null) {
sqlStr += " , MBER_MOBLPHON = '"+paramMberMp+"' ";
}
if (!"".equals(paramRm) && paramRm != null) {
sqlStr += " , RM = '"+paramRm+"' ";
}
sqlStr += " WHERE MBER_SN = '"+paramMberSn+"' ";
resultNum = stmt.executeUpdate(sqlStr);
dbConn.commit();
} catch (Exception e) {
resultNum = 0;
e.printStackTrace();
try {
if (dbConn != null) {
dbConn.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
}
req.setAttribute("resultType", "U");
req.setAttribute("resultCode", resultNum);
RequestDispatcher rd = req.getRequestDispatcher("/mberDetailView.jsp");
rd.forward(req, resp);
}
소스코드를 보면 이전에 사용했던 내용과 조금 다르게 분기문(if)을 많이 사용했는데 꼭 이렇게 해야 할 필요는 없고 다만 특정 조건을 소스코드와 같이 넣어서 처리할 수 있다 정도로 참고용이다. 위 소스코드는 사실 배포되면 욕 오지게 먹을 것이다 왜냐? 비고 내용을 못 지우지 않은가? ㅋㅋ
화면에서 후처리 할 수 있도록 setAttribute를 2개를 해주었는데 이는 상세화면에서 수정과 삭제의 2가지 이벤트가 발생하게 되니 어떤 수행을 했는지에 대한 구분과 그 결과를 담아서 forward 해준 것이다.
4. 회원 삭제 (MberRemoveServlet.java)
요것도 복붙...ㅎㅎ 수정과 마찬가지로 doPost만 살짝 보자 (근데 볼 게 없는데..;;)
소스코드 :
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
Connection dbConn = null;
int resultNum = 0;
try {
String paramMberSn = req.getParameter("mberSn");
Class.forName("org.mariadb.jdbc.Driver");
dbConn = DriverManager.getConnection(
"jdbc:mariadb://127.0.0.1:3306/oldev"
, "olDev"
, "olDev@1234"
);
dbConn.setAutoCommit(false);
Statement stmt = dbConn.createStatement();
String sqlStr = "";
sqlStr += "DELETE FROM OD_MBER ";
sqlStr += " WHERE MBER_SN = '"+paramMberSn+"' ";
resultNum = stmt.executeUpdate(sqlStr);
dbConn.commit();
} catch (Exception e) {
resultNum = 0;
e.printStackTrace();
try {
if (dbConn != null) {
dbConn.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
}
req.setAttribute("resultType", "D");
req.setAttribute("resultCode", resultNum);
RequestDispatcher rd = req.getRequestDispatcher("/mberDetailView.jsp");
rd.forward(req, resp);
}
수정과 다른 점은 Delete SQL이라는 거? 마찬가지로 setAttribute 2개를 해주고 forward 처리했다.
5. web.xml Servlet mapping
수정과 삭제 두 개의 Servlet이 추가되었으니 소스코드와 같이 매핑하자.
소스코드 :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID"
version="2.5">
<display-name>olDevServlet</display-name>
...
<servlet>
<servlet-name>mberModify</servlet-name>
<servlet-class>com.MberModifyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mberModify</servlet-name>
<url-pattern>/mberModify.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>mberRrmove</servlet-name>
<servlet-class>com.MberRemoveServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mberRrmove</servlet-name>
<url-pattern>/mberRrmove.do</url-pattern>
</servlet-mapping>
</web-app>
Servlet mapping 안 하면 못쓰는데 굳이 올릴 필요가 있겠냐만... 호~~~ 옥시나 싶어서 올려봄 (쓸 내용이 없어서는 아니고... 쩝... ㅎㅎ;;;)
이렇게 작업하고 실행하면 잘된다. 뭐 안되는 걸 올리진 않을 것 아닌가? ㅎㅎ
그래서 실행은 올려둔 소스를 실행해보면 지난 글에서 크게 바뀐 것 없이 상세화면에 회원 삭제와 회원 수정 버튼이 뙇! 하고 붙은걸 확인할 수 있으니 확인해보는 것으로 하고 수정, 삭제 결과에 대한 처리를 지금과 같이 해두면 한 가지 문제가 생기는데 해당 문제가 뭐냐면 성공은 성공을 했으니 목록을 가도 의미상 맞아떨어지는데 실패를 하게 되면 회원 상세 데이터가 텅텅 빈 상태로 보이게 된다. 그래서 이문제를 살펴보자.
6. 회원 상세 결과 처리
수정 또는 삭제 후 상세화면으로 돌아오면 forward로 보내줬으니 데이터 있을 것만 같은 생각이 들 수도 있겠다. 이는 완전히 잘못된 생각인데 지난번에 이야기 한대로 request, response는 세트로 휘발성 1회성 요청과 응답인데 화면에 진입하는 순간에 데이터 조회에 대한 request, response를 수행하고 그 결과를 보여주고 완전히 종료된 상태인 것이고 수정 또는 삭제는 새로운 요청과 응답을 요구하는 것인데 그 결과가 성공이던 실패던 회원 상세 정보를 전달한 적이 없기 때문에 회원 상세 화면에서는 보여줄 데이터가 없는 것이다. 정말 그러한지 테스트를 해보자.
소스코드 :
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
Connection dbConn = null;
int resultNum = 0;
try {
...
dbConn = DriverManager.getConnection(
"jdbc:mariadb://127.0.0.1:3306/oldev"
, "olDev"
, "olDev@1234"
);
dbConn.setAutoCommit(false);
if (true) {
throw new Exception("Modify Exception Test!");
}
Statement stmt = dbConn.createStatement();
...
} catch (Exception e) {
resultNum = 0;
e.printStackTrace();
try {
if (dbConn != null) {
dbConn.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
}
req.setAttribute("resultType", "U");
req.setAttribute("resultCode", resultNum);
RequestDispatcher rd = req.getRequestDispatcher("/mberDetailView.jsp");
rd.forward(req, resp);
}
소스코드와 같이 Connection을 가져오고 바로 Exception을 throw 해보자. 수정했다면 실행하자. 아무 데이터나 회원 이름을 클릭하고 상세로 들어간 후 회원 수정 버튼을 클릭해보자.

회원 수정을 클릭하면 throw Exception 덕분에 실패 알림을 보게 되는데 확인 후 재진입한 회원 상세에는 데이터가 텅텅 비어 있게 된다.
등록과 같은 경우는 사용자 데이터 입력을 유도하므로 지워지면 다시 입력하면 그만이지만 수정과 같은 경우는 이미 등록된 데이터를 수정해야 하기 때문에 실패하면 Connection.rollback()으로 원복 된 즉 처음 화면이 호출될 때의 데이터를 출력해주어야 한다. 그럼 이를 해결하기 위해 mberDetailView.jsp 스크립트를 수정해보자.
소스코드 :
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<script src="https://code.jquery.com/jquery-3.5.0.js"></script>
<body>
<form id="mberDetailFrm">
...
</form>
</body>
<script type="text/javascript">
var isResultType = "${resultType}";
var isResultCode = "${resultCode}";
$(document).ready(function(){
...
// 결과가 들어온다면
if (isResultType != "" && isResultType != null && isResultType != undefined) {
// 수정일때
if (isResultType == "U") {
// 정상
if (isResultCode > 0) {
alert("수정이 완료되었습니다.");
$("#mberListBack").trigger("click");
// 실패
} else {
alert("수정이 실패했습니다.");
fnRefreshPage();
}
}
// 삭제일때
if (isResultType == "D") {
//정상
if (isResultCode > 0) {
alert("삭제를 완료되었습니다.");
$("#mberListBack").trigger("click");
//실패
} else {
alert("삭제를 실패했습니다.");
fnRefreshPage();
}
}
}
});
// 실패시 화면 갱신을 해보자.
function fnRefreshPage() {
var frm = $("#mberDetailFrm");
frm.attr("method", "post");
frm.attr("action", "/mberDetail.do");
frm.submit();
}
</script>
fnRefreshPage() 함수를 추가하고 실패 시 호출하여 MberDetailServlet이 수행되도록 처리했다.
소스코드와 같이 내용을 수정하고 다시 실행해보면 여전히 실패 알림을 받고 회원 상세로 재진입하면 텅텅 빈 화면을 보게 된다. 응? MberDetailServlet이 작동을 안 하나? 하는 생각이 들것이다. 이는 Servlet을 한번 열어보면 Parameter로 mberSn을 받고 있는 것을 알 수 있다. 이거 전달했던가? 없지.. 보낸 적이 없지.. 그럼 이번엔 MberModifyServlet을 수정해보자.
소스코드 :
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
Connection dbConn = null;
int resultNum = 0;
// setAttribute를 위해서 try 문 밖으로 옮겼다.
String paramMberSn = req.getParameter("mberSn");
String paramMberPwd = req.getParameter("mberPwd");
String paramMberNm = req.getParameter("mberNm");
String paramMberMp = req.getParameter("mberMoblphon");
String paramRm = req.getParameter("rm");
try {
....
} catch (Exception e) {
resultNum = 0;
e.printStackTrace();
try {
if (dbConn != null) {
dbConn.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
}
req.setAttribute("resultType", "U");
req.setAttribute("resultCode", resultNum);
// 회원 수정 시 전달받은 Parameter를 추가해주자.
req.setAttribute("resultMberSn", paramMberSn);
RequestDispatcher rd = req.getRequestDispatcher("/mberDetailView.jsp");
rd.forward(req, resp);
}
Servlet을 소스코드와 같이 Parameter 변수를 참조하기 위해서 try 밖으로 옮기고 setAttribute를 추가하자.
소스코드 :
// 실패시 화면 갱신을 해보자.
function fnRefreshPage() {
var frm = $("#mberDetailFrm");
frm.append("<input type='hidden' name='mberSn' value='${resultMberSn}'>");
frm.attr("method", "post");
frm.attr("action", "/mberDetail.do");
frm.submit();
}
Servlet에서 전달하는 mberSn을 받도록 mberDetailView.jsp도 수정하자. 화면 로직상 result가 없을 때 input을 설정하지 않으므로 jquery append 함수로 input을 동적 생성하고 el로 Servlet에서 전달하는 mberSn을 설정하자. (jqeury는 아~ 저런 게 있구나 참고만 하자.)
Servlet과 JSP를 모두 수정했다면 다시 실행해보면 여전히 실패 알림을 보여주지만 이후 데이터가 조회되어 처음 진입 화면과 동일하게 보이는 것을 알 수 있는데 다만 화면이 깜빡이네? 하는 느낌은 받게 될 것이다.
깜빡이던 어쨌든 수행 결과가 실패일 때 첫 진입과 동일한 데이터를 출력할 수 있으므로 된 것 아니겠는가? ㅎㅎ 대충대충 넘어가도록 하고 이렇게 목록 조회, 상세 조회, 등록, 수정, 삭제를 구현하다 보니 Servlet에서 매번 Connection을 받아서 SQL을 수행하게 된다. 지금이야 혼자 개발하고 몇개 안되는 기능을 구현했으니 별 문제없겠지만 실제로 프로젝트라면 수많은 기능과 무수한 사용자(악수 아님)의 Request 받아 Connection 이용하게 될 텐데 사실 이 Connection이라는 게 무한한 자원이 아니다. 그래서 Connection을 한번 알아보자.
7. Connection
언제나 그렇듯 거창하게 시작하지만 맛만 보자.. ㅎㅎ
Connection을 한마디로 정의하자면 DB와 이어주는 통로 또는 연결고리(너와 나 아님)이다.
정말 간단하게 한 줄로 줄여놨는데 근데 이게 말 그대로임. WAS 서버와 DB 서버는 서로 다른 서버이고 이 서로 다른 서버는 서로에게 접근하려면 통로가 있어야 하는게 아니겠는가? 그냥 그게 다임.. DB를 사용하기 위해서 그 통로로 사용하는 것이 Drivermanger로 getConnection 가져와! 하고 요청을 하게 되면 Conneciton이라는 통로를 주는 것인데 이 통로가 무한한 게 아니어서 사용하고 반납해주어야 한다. 자 그럼 앞서 이야기한 대로면 Connection은 사용하고 반납을 해야 한다는 건데... 지금까지 만들어본 소스코드에서 혹시나 Connection을 되돌려 주는 코드 비슷한 게 생각나는가? 없을 것이다 왜? 안 만들었으니깐! 그럼 계속 요청 때리면 뻗겠네? 네 뻗습니다.. 그럼 테스트를 해봅시다.
소스코드 :
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
Connection dbConn = null;
int resultNum = 0;
...
try {
Class.forName("org.mariadb.jdbc.Driver");
for (int i = 0 ; i < 1000 ; i++) {
dbConn = DriverManager.getConnection(
"jdbc:mariadb://127.0.0.1:3306/oldev"
, "olDev"
, "olDev@1234"
);
}
} catch (Exception e) {
....
}
....
}
MberModifyServlet.java에서 소스코드와 같이 DriverManager.getConnection(...)에 반복문을 적용하고 실행해보자.

회원 상세에서 회원 수정 버튼을 다시 클릭해보면 위와 같이 eclipse console 창이 붉은색으로 물들게 되는데 내용을 보면 Too many connection이다. 이거 Drivermanager가 Connection 작작 요청하라고 console을 통해 욕하고 있는 것인데 욕먹긴 싫으니깐 Connection을 여러번 호출해야 할 땐 어떻게 해야할까? 앞서 이야기 한대로 반납을 해주면 된다. 그래서 Connection method를 찾아보면 method type이 void인 close() method가 보이는데 누가 봐도 이거 아니겠는가? 후훗 소스코드를 다시 수정하고 돌려보자.
소스코드 :
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
Connection dbConn = null;
int resultNum = 0;
...
try {
Class.forName("org.mariadb.jdbc.Driver");
for (int i = 0 ; i < 1000 ; i++) {
dbConn = DriverManager.getConnection(
"jdbc:mariadb://127.0.0.1:3306/oldev"
, "olDev"
, "olDev@1234"
);
dbConn.close();
}
} catch (Exception e) {
....
}
....
}
소스코드와 같이 Connection을 받고 바로 close()를 적용 후 실행해보자.

읭? colse() 해주면 오류 안나야 하는거 아닌가? 왜 오류지? 생각이 들겠지만 오류 메시지를 봐보자. reateStatement() is called on closed connection 뭐 딴 나라 말로 이렇게 적혀있는데 이 내용은 반복분에서 순식간에 1000번이나 돌리다 보니 close가 수행되었지만 아직 완전히 없어지지 않은 죽은 connection이 전달 되었을 때의 문제이다. 즉 지금 테스트는 잘된 거임 아니 한 곳에서 1000번씩 날릴 일이 있겠는가? 없을 거임 그래서 늘 그렇듯 아~ 그렇구나 하고 넘어가고 그럼 저 close() method를 어떻게 적용해야 할까? Statement 수행 이후인가? commit(), rollback() 이후 인가? 곰곰이 생각해보면 그냥 doPost 끝날 때 닫으면된다. 어차피 저거 연결해야 SQL 수행하고 Transaction 잡고 어쩌고 저쩌고 할수 있는거고 이들이 끝나는 지점에 닫으면 되는거 아닌가? 그래서 doPost가 끝날때 즉 SQL 수행이 끝나는 지점인 try {} 문의 finally에서 처리할 것이다.
소스코드 :
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
Connection dbConn = null;
int resultNum = 0;
....
try {
....
} catch (Exception e) {
....
} finally {
if (dbConn != null) {
try {
dbConn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
....
rd.forward(req, resp);
}
이렇게 finally로 잡게 되면 Exception이 나든지 말든지 SQL을 수행을 하든지 말든지 try 구문이 끝날 때 반드시 실행되니 사용된 Connection은 colse method를 통해 반납되게 될 것이다. rollback()과 마찬가지로 SQLException을 throwable 하고 있으니 한 번 더 try 구문으로 묶어주고 전역으로 Connection dbConn = null; 선언되었으니 혹여나 생성조차 안됐다면 그냥 pass 시키게 처리하자.
이쯤 되면 이전 글의 Transaction은 commit, rollback으로 완료고 지금의 Connection은 close()라는 명시적인 기능으로 반납도 하는데 Statement는 둬도 되나? 가만히 둬도 된다면 굳이 글을 쓰겠는가? ㅎㅎ Statement 뿐만이 아니라 Statement의 결과 ResultSet도 닫아야 하는데 쉽게 생각하면 DB 작업을 위해 Connection으로부터 제공되는 기능 중 close method를 가지고 있는 모든 기능은 사용후 호출하여 종료를 해야하고 Transaction만 commit 또는 rollback으로 종료 된다는것만 기억하자. 이유는 좀 뻔한데 WAS 서버와 DB 서버는 서로 다른 서버라 하지 않았던가? Connection으로 니꺼 사용한다? 해놓고 다썼어 가져가 하고 알려주지 않으면 DB는 어떻게 알겠는가? 모르면? 유지가 된다는거다 Timout 설정덕에 일정시간이 지나면 해제되겠지만 시간이 10분이면 그 10분간 남겨둬서 뭐하나? 뭐 그런 이유로 Statement 객체도 만차가지로 finally구문으로 추가 하고 close 하도록 하자. 이전 글을 봤다면 음? Conncetion -> Transaction -> Statement 순서 아니었나? Transaction 후에 Statement 닫혀도 되는건가? 하는 생각이 든다면 말안해도 된다는걸 알것인데 이는 Transaction 내에서 수행된 Statement는 colse 이전에 commit(기록) 또는 rollback(원복) 되었기 때문에 Statement를 닫으나 안닫으나 그 수행결과는 적용이 완료되게 된다. 그래서 finally에서 닫는 순서만 Statement를 우선 닫고 Connection을 이후에 닫겠끔 처리하자.
소스코드 :
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
Connection dbConn = null;
Statement stmt = null;
int resultNum = 0;
try {
....
} catch (Exception e) {
....
} finally {
try {
if (stmt != null) {
stmt.close();
}
if (dbConn != null) {
dbConn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
....
rd.forward(req, resp);
}
Connection close와 같은 사유로 소스코드 처럼 finally에 적용하고 프로그램을 종료 하도록 하자.
이렇게 목표를 채우고 간략하게 Connection에 대해서도 알아보았다. 좀 허술해 보이는건 기분탓이려니 하고 넘어가도록 하자 ㅎㅎ;; 뭐 쨌든 글을 보다보면 Connection? Connection Pool과 다른건가? 하는 의문이 든다면 같은 맥락이지만 개념에 차이가 있다? 정도로 생각하고 넘어 가도록 하자 이는 Drivermanager를 사용하는지 아니면 Datasource(DBCP)를 사용하는지에 따라 Connection 사용에 대한 개념이 달라지는데 이를 지금 엮어서 이야기 하자면 내용이 상당히 길어지기도 하고 어차피 뒤로 가면 다뤄야하니 언제나 그렇듯 천천히 알아보도록 하자.
JSP와 마찬가지로 등록, 수정, 삭제, 조회를 만들어 보았는데 아무나 막 보여주긴 뭐하니깐 다음엔 Login Session 뭐 이런거 만들어 보자. ㅎㅎ
'JAVA_Servlet' 카테고리의 다른 글
| 초보의 Servlet 개발 등록과 Transaction (0) | 2020.11.24 |
|---|---|
| 초보의 Servlet 개발 jstl, el 그리고 jquery (0) | 2020.11.23 |
| 초보의 Servlet 개발 조회 (0) | 2020.11.20 |
| 초보의 Servlet 개발 화면이동 (0) | 2020.11.19 |
| 초보의 Servlet 개발 Request, Response (0) | 2020.11.18 |
댓글