싱글톤을 적용한 CRUD를 구성할 것이다.
싱글톤 구현을 위한 web.xml 과 context.xml
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 고정적인 객체를 미리 만들어놓는(객체를 생성하기 위한 주문서) 것. -->
<Context>
<Resource
name="jdbc/oracle"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@192.168.1.100:1521:xe"
username="c##itbank"
password="it"
maxidle="10"
maxWait="-1"
/>
</Context>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 초기작동 context의 주문서들을 참조 -->
<resource-ref>
<description>ConnectionPool</description>
<res-ref-name>jdbc/oracle</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
Member2DTO
package member2;
public class Member2DTO {
private int idx;
private String userid;
private String userpw;
private String username;
private String gender;
public int getIdx() {
return idx;
}
public void setIdx(int idx) {
this.idx = idx;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getUserpw() {
return userpw;
}
public void setUserpw(String userpw) {
this.userpw = userpw;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
Member2DAO
package member2;
import java.sql.*;
import java.util.ArrayList;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class Member2DAO {
// 싱글톤과 Connectionpool이 적용된 member2 테이블 관련 DAO를 작성하세요
// 회원 목록을 반환하는 함수를 작성하여 jsp에서 출력합니다
// header.jsp 를 작성하여 tablib, import, dao 선언을 수행합니다
// list.jsp를 작성하여 회원 목록을 table 형식으로 화면에 출력합니다.
private Connection conn;
private PreparedStatement pstmt;
private ResultSet rs;
private Context init;
private DataSource ds; // 여러개의 conn을 가지고 있다가 하나씩 내어주고,
// conn.close()하면 객체를 돌려받아서, 다시 사용할 수 있도록 처리한다
// 컨베이어 벨트 방식으로 conn 객체를 재활용한다
private static Member2DAO instance = new Member2DAO();
public static Member2DAO getInstance() {
return instance;
}
public Member2DAO() {
try {
init = (Context) new InitialContext();
ds = (DataSource) init.lookup("java:comp/env/jdbc/oracle");
} catch (NamingException e) {
e.printStackTrace();
} finally {
if(conn != null) try { conn.close(); } catch (SQLException e) {}
}
}// end of constructor
// select 하는 경우, rs의 데이터를 DTO에 맞게 맵핑하는 과정이 필요하다
// 전체, 검색, 단일 조회 모든 경우에 사용할 수 있도록 함수를 만들어 둔다
private Member2DTO mapping(ResultSet rs) throws SQLException{//함수에서 try catch를 열기때문에 전가 시켜도 됨
Member2DTO dto = new Member2DTO();
dto.setIdx(rs.getInt("idx"));
dto.setUserid(rs.getString("userid"));
dto.setUserpw(rs.getString("userpw"));
dto.setUsername(rs.getString("username"));
dto.setGender(rs.getString("gender"));
return dto;
}
// 모든 함수에서 rs, pstmt, conn을 순서대로 닫아준다 (열기의 역순으로 닫는다)_
private void close() {
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
// dataSource에서 가져온 conn은 close()하면 회수된다
} catch(Exception e) {}
}
public ArrayList<Member2DTO> selectList() {
ArrayList<Member2DTO> list = new ArrayList<Member2DTO>();
String sql = "select * from member3 order by idx";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
Member2DTO dto = mapping(rs);
list.add(dto);
// list.add(mapping(rs));
}
} catch (SQLException e) {
e.printStackTrace();
} finally { close(); }
return list;
}
public Member2DTO selectOne(int idx) {
String sql = "select * from member3 where idx=" + idx;
Member2DTO dto = null;
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while (rs.next()) {
dto = mapping(rs);
}
} catch (SQLException e) {
e.printStackTrace();
} finally { close();}
return dto;
}
public int insert(Member2DTO dto) {
int row = 0;
String sql = "insert into member3 (userid, userpw, username, gender) values(?, ?, ?, ?)";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, dto.getUserid());
pstmt.setString(2, dto.getUserpw());
pstmt.setString(3, dto.getUsername());
pstmt.setString(4, dto.getGender());
row = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally { close();}
return row;
}
public int update(Member2DTO dto) {
int row = 0;
String sql = "update member3 set userid=?, userpw=?, username=?, gender=? where idx=?";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, dto.getUserid());
pstmt.setString(2, dto.getUserpw());
pstmt.setString(3, dto.getUsername());
pstmt.setString(4, dto.getGender());
pstmt.setInt(5, dto.getIdx());
row = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally { close();}
return row;
}
public int delete(int idx) {
int row = 0;
String sql = "delete from member3 where idx=" + idx;
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
row = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e) {
}
}
return row;
}
}
header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="member2.*" %>
<% request.setCharacterEncoding("UTF-8"); %>
<c:set var="cpath" value="${pageContext.request.contextPath }"/>
<c:set var="dao" value="${Member2DAO.getInstance() }"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
table {
width: 100%;
border: 1px solid black;
}
th, td {
border: 1px solid black;
padding: 5px;
}
</style>
</head>
<body>
<header>
<h1><a href="${cpath }">회원 목록</a></h1>
<nav>
<ul>
<li><a href="${cpath }/list.jsp">목록</a></li>
<li><a href="${cpath }/add.jsp">추가</a></li>
<li><a href="${cpath }/modify.jsp">수정</a></li>
<li><a href="${cpath }/delete.jsp">삭제</a></li>
</ul>
</nav>
</header>
index
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
</body>
</html>
list
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<h3>회원 목록</h3>
<table>
<thead>
<tr>
<th>IDX</th>
<th>USERID</th>
<th>USERPW</th>
<th>USERNAME</th>
<th>GENDER</th>
</tr>
</thead>
<tbody>
<c:forEach var="dto" items="${dao.selectList() }">
<tr>
<td>${dto.idx }</td>
<td>
<a href="${cpath }/detail.jsp?idx=${dto.idx }">${dto.userid }</a>
</td>
<td>${dto.userpw }</td>
<td>${dto.username }</td>
<td>${dto.gender }</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<h1>추가</h1>
<form method="POST" action="add-action.jsp">
<fieldset>
<legend>회원정보</legend>
<p><input type="text" name="userid" placeholder="ID"></p>
<p><input type="text" name="userpw" placeholder="PW"></p>
<p><input type="text" name="username" placeholder="NAME"></p>
</fieldset>
<fieldset>
<legend>성별</legend>
<label><input type="radio" name="gender" value="남성">남성</label>
<label><input type="radio" name="gender" value="여성">여성</label>
</fieldset>
<p><input type="submit"></p>
</form>
</body>
</html>
add-action.jsp
<%@page import="java.lang.ProcessBuilder.Redirect"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<jsp:useBean id="user" class="member2.Member2DTO"/>
<jsp:setProperty property="*" name="user" />
<c:set var="row" value="${dao.insert(user) }" />
<c:if test="${row != 0 }">
<h3>추가되었습니다</h3>
<a href="${cpath }/list.jsp"><button>목록으로</button></a>
</c:if>
<c:if test="${row == 0 }">
<h3>추가 실패</h3>
<button onclick="history.back()">이전으로</button>
</c:if>
</body>
</html>
modify.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<h3>수정</h3>
<table>
<thead>
<tr>
<th>USERID</th>
<th>USERPW</th>
<th>USERNAME</th>
<th>GENDER</th>
</tr>
</thead>
<tbody>
<c:forEach var="dto" items="${dao.selectList() }">
<tr>
<td>${dto.userid }</td>
<td>${dto.userpw }</td>
<td>${dto.username }</td>
<td>${dto.gender }</td>
<td>
<a href="modify-form.jsp?idx=${dto.idx }"><button>수정</button></a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
modify-form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<jsp:useBean id="user" class="member2.Member2DTO"/>
<c:set var="dto" value="${dao.selectOne(param.idx) }" />
<h3>수정</h3>
<form method="POST" action="modify-action.jsp">
<fieldset>
<legend>회원정보</legend>
<p><input type="text" name="userid" placeholder="ID" value="${dto.userid }"></p>
<p><input type="text" name="userpw" placeholder="PW" value="${dto.userpw }"></p>
<p><input type="text" name="username" placeholder="NAME" value="${dto.username }"></p>
</fieldset>
<fieldset>
<legend>성별</legend>
<label><input type="radio" name="gender" value="남성" ${dto.gender == ('남성') ? 'checked' : '' }>남성</label>
<label><input type="radio" name="gender" value="여성" ${dto.gender == ('남성') ? 'checked' : '' }>여성</label>
</fieldset>
<p><input type="submit"></p>
<p><input type="hidden" name="idx" value="${dto.idx }"></p>
</form>
</body>
</html>
modify-action.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<jsp:useBean id="user" class="member2.Member2DTO"/>
<jsp:setProperty property="*" name="user" />
<c:set var="row" value="${dao.update(user) }" />
<c:if test="${row != 0 }">
<h3>수정되었습니다</h3>
<a href="${cpath }/list.jsp"><button>목록으로</button></a>
</c:if>
<c:if test="${row == 0 }">
<h3>수정 실패</h3>
<button onclick="history.back()">이전으로</button>
</c:if>
</body>
</html>
delete.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<h3>회원 삭제</h3>
<table>
<thead>
<tr>
<th>IDX</th>
<th>USERID</th>
<th>USERPW</th>
<th>USERNAME</th>
<th>GENDER</th>
<th></th>
</tr>
</thead>
<tbody>
<c:forEach var="dto" items="${dao.selectList() }">
<tr>
<td>${dto.idx }</td>
<td>
<a href="${cpath }/detail.jsp?idx=${dto.idx }">${dto.userid }</a>
</td>
<td>${dto.userpw }</td>
<td>${dto.username }</td>
<td>${dto.gender }</td>
<td><button class="deleteBtn" idx="${dto.idx }">삭제</button></td>
</tr>
</c:forEach>
</tbody>
</table>
<script>
function deleteHandler() {
const idx = this.getAttribute('idx')
const flag = confirm('정말 ' + idx + '번 회원님을 삭제하시겠습니까?')
if(flag) {
location.href = '${cpath}/delete-action.jsp?idx=' + idx
}
}
const btnList = document.querySelectorAll('.deleteBtn')
btnList.forEach(btn => btn.addEventListener('click', deleteHandler))
</script>
</body>
</html>
delete-action.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<c:set var="row" value="${dao.delete(param.idx) }" />
<c:if test="${row != 0 }">
<% response.sendRedirect("list.jsp"); %>
</c:if>
<c:if test="${row == 0 }">
<h3>삭제 실패</h3>
<button onclick="history.back()">이전으로</button>
</c:if>
</body>
</html>
SQL 구문
--------------------------------------------------------
-- 파일이 생성됨 - 목요일-12월-22-2022
--------------------------------------------------------
--------------------------------------------------------
-- DDL for Sequence MEMBER2_SEQ
--------------------------------------------------------
CREATE SEQUENCE "C##ITBANK"."MEMBER2_SEQ" MINVALUE 1 MAXVALUE 99999999 INCREMENT BY 1 START WITH 1020 NOCACHE NOORDER NOCYCLE NOKEEP NOSCALE GLOBAL ;
--------------------------------------------------------
-- DDL for Table MEMBER2
--------------------------------------------------------
CREATE TABLE "C##ITBANK"."MEMBER2"
( "IDX" NUMBER DEFAULT "C##ITBANK"."MEMBER2_SEQ"."NEXTVAL",
"USERID" VARCHAR2(100 BYTE),
"USERPW" VARCHAR2(255 BYTE),
"USERNAME" VARCHAR2(100 BYTE),
"JOINDATE" DATE DEFAULT sysdate,
"GENDER" VARCHAR2(20 BYTE),
"PROFILEIMG" VARCHAR2(255 BYTE)
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
REM INSERTING into C##ITBANK.MEMBER2
SET DEFINE OFF;
Insert into C##ITBANK.MEMBER2 (IDX,USERID,USERPW,USERNAME,JOINDATE,GENDER,PROFILEIMG) values (1019,'root23','1234','김진형',to_date('22/12/09','RR/MM/DD'),'남성',null);
Insert into C##ITBANK.MEMBER2 (IDX,USERID,USERPW,USERNAME,JOINDATE,GENDER,PROFILEIMG) values (1005,'test','1234','테스트',to_date('22/12/09','RR/MM/DD'),'남성',null);
Insert into C##ITBANK.MEMBER2 (IDX,USERID,USERPW,USERNAME,JOINDATE,GENDER,PROFILEIMG) values (1006,'test2','1234','테스트',to_date('22/12/09','RR/MM/DD'),'여성',null);
Insert into C##ITBANK.MEMBER2 (IDX,USERID,USERPW,USERNAME,JOINDATE,GENDER,PROFILEIMG) values (1007,'test3','1234','테스트',to_date('22/12/09','RR/MM/DD'),'남성',null);
--------------------------------------------------------
-- DDL for Index SYS_C007315
--------------------------------------------------------
CREATE UNIQUE INDEX "C##ITBANK"."SYS_C007315" ON "C##ITBANK"."MEMBER2" ("IDX")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
--------------------------------------------------------
-- DDL for Index SYS_C007316
--------------------------------------------------------
CREATE UNIQUE INDEX "C##ITBANK"."SYS_C007316" ON "C##ITBANK"."MEMBER2" ("USERID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
--------------------------------------------------------
-- Constraints for Table MEMBER2
--------------------------------------------------------
ALTER TABLE "C##ITBANK"."MEMBER2" MODIFY ("USERID" NOT NULL ENABLE);
ALTER TABLE "C##ITBANK"."MEMBER2" MODIFY ("USERPW" NOT NULL ENABLE);
ALTER TABLE "C##ITBANK"."MEMBER2" MODIFY ("USERNAME" NOT NULL ENABLE);
ALTER TABLE "C##ITBANK"."MEMBER2" ADD CHECK (gender in('남성', '여성')) ENABLE;
ALTER TABLE "C##ITBANK"."MEMBER2" ADD PRIMARY KEY ("IDX")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ENABLE;
ALTER TABLE "C##ITBANK"."MEMBER2" ADD UNIQUE ("USERID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ENABLE;
'개발자 > JSP' 카테고리의 다른 글
[JDBC] DBCP(DataBase Conncetion Pool) (0) | 2022.12.12 |
---|---|
[JDBC] SingleTon 패턴 (0) | 2022.12.12 |
[JDBC] XML (0) | 2022.12.12 |
[JDBC] 시퀀스를 활용하여 idx값 출력 (제약조건++) (0) | 2022.12.09 |
[SQL] DB Table 제약조건 (0) | 2022.12.09 |