일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- ;
- 데이터사이언스
- 동기 부여
- 동기부여
- Alert
- BEANS
- 파일 호출
- 페이지 이동
- 파일호출
- javaBeans
- session.setAttribute
- 향상된 for문
- session.removeAttribute
- 페이지이동
- 팝업창
- 미래직장
- 버리자
- \
- scanner
- 영감
- opener
- 자바빈즈
- Import
- iframe
- 빈즈
- 로그인화면
- target
- "
- session.getAttribute
- static
- Today
- Total
갈림길 이정표
[JSP] beans + dbcp[connection pooling] 본문

[beansDB2.jsp]
<%@page import="pack3.SangpumDTO"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id="cdp" class="pack3.ConnDbPooling" scope="page"/> <%--scope? --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>beans + dbcp</title>
<script type="text/javascript">
function funcUp(){
//alert("a");
var code = prompt("수정할 코드 입력",""); //prompt: alert창에 값을 입력 할 수 있음
//alert(code);
if(code !== "" && code !== null){
location.href="beansDB2_up.jsp?code=" + code; //자바의 response.sendRedirect랑 비슷
}
}
function funcDel(){
//alert("b");
var code = prompt("삭제할 코드 입력",""); //Java의 구식 방법으로 Javascript의 Dialog, 각 포털사이트 API제공 방식으로 세련되게 할 수 있음
if(code !== "" && code !== null){
if(confirm("정말 삭제할까요?") === true){
location.href="beansDB2_del.jsp?code=" + code;
}
}
}
</script>
</head>
<body>
<h2>* 상품자료(beans + dbcp[connection pooling]사용) *</h2>
<!-- 아직 ModelⅠ 방식 -->
<a href="beansDB2_ins.html">상품 추가용</a>
<a href="javascript:funcUp()">상품 수정용</a>
<a href="javascript:funcDel()">상품 삭제용</a><br>
<table border='1'>
<tr><td>코드</td><td>품명</td><td>수량</td><td>단가</td></tr>
<%
ArrayList<SangpumDTO> list = cdp.getDataAll();
for(SangpumDTO s:list){
%>
<tr>
<td><%=s.getCode() %></td>
<td><%=s.getSang() %></td>
<td><%=s.getSu() %></td>
<td><%=s.getDan() %></td>
</tr>
<%
}
%>
</table>
</body>
</html>
▼ 기본 key별 데이터 getter, setter 그리고 DTO from DB
[SangpumBean.java]
package pack3;
public class SangpumBean { //DB 입력 용도
private String code, sang, su, dan;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getSang() {
return sang;
}
public void setSang(String sang) {
this.sang = sang;
}
public String getSu() {
return su;
}
public void setSu(String su) {
this.su = su;
}
public String getDan() {
return dan;
}
public void setDan(String dan) {
this.dan = dan;
}
}
[SangpumDTO.java]
package pack3;
public class SangpumDTO { //용도:
private String code, sang;
private int su, dan;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getSang() {
return sang;
}
public void setSang(String sang) {
this.sang = sang;
}
public int getSu() {
return su;
}
public void setSu(int su) {
this.su = su;
}
public int getDan() {
return dan;
}
public void setDan(int dan) {
this.dan = dan;
}
}
▼ dbcp[connection pooling]
dbcp 기술을 이용하기 위해선 반드시 [content.xml] 파일이 미리 준비되어 있어야 한다.
WebContent > META-INF > [context.xml]
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc_maria" auth="Container" type="javax.sql.DataSource"
driverClassName="org.mariadb.jdbc.Driver" loginTimeout="10" maxWait="5000"
username="root" password="369369" testOnBorrow="true"
maxActive="500" maxIdle="100"
url="jdbc:mysql://localhost:3306/test" />
</Context>
준비가 다 되었다면 드라이버 로딩을 위해 이전 ConnDb class파일처럼 똑같이 java파일을 만들면 되는데 한 가지 차이점만 주의 하면 된다.
순서대로 일반 Connection DB파일과 DB Connection Pooling파일의 차이를 살펴보자.
public ConnDbBean() {
try {
Class.forName("org.mariadb.jdbc.Driver");
} catch (Exception e) {
System.out.println("ConnDbBean err: " + e);
}
}
private DataSource ds;
public ConnDbPooling() {
try {
Context context = new InitialContext();
ds = (DataSource)context.lookup("java:comp/env/jdbc_maria");
} catch (Exception e) {
System.out.println("ConnDbPoolinf err: " + e);
}
}
이렇게 DataSource class의 객체 멤버(ds)를 선언 했다면 아까 준비해 두었던 Context 클래스의 새로운 객체(context)를 선언할 수 있고, context는 내장 함수로써 lookup을 사용하여 mariaDB를 사용 할 수 있게 된다.
단, context.lookup은 Object 타입이기 때문에 [Casting]이 필요하다.
(※ A factory for connections to the physical data source that this DataSource object represents. An alternative to the DriverManager facility, a DataSource object is the preferred means of getting a connection. An object that implements the DataSource interface will typically be registered with a naming service based on the Java™ Naming and Directory (JNDI) API)
[ConnDbPooling.java]
package pack3;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class ConnDbPooling { //Business logic 담당
private Connection conn;
private PreparedStatement pstmt;
private ResultSet rs;
private DataSource ds; //META-INF > context.xml을 만들어서 가능한 것
public ConnDbPooling() {
try {
Context context = new InitialContext(); //JNDI
ds = (DataSource)context.lookup("java:comp/env/jdbc_maria");
//context.xml <Resource> tag의 name과 일치해야 함 (context.lookup은 Object타입이기 때문에 [Casting] 필요)
} catch (Exception e) {
System.out.println("ConnDbPoolinf err: " + e);
}
}
public ArrayList<SangpumDTO> getDataAll(){
ArrayList<SangpumDTO> list = new ArrayList<SangpumDTO>();
try {
// DB연결
String sql = "SELECT * FROM sangdata";
conn = ds.getConnection(); //dbcp(Connection 객체가 여러개 있을 때 사용)
//conn = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "369369"); 이렇게 안해도 됨
//보안 강화, 짧은 코딩
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
SangpumDTO dto = new SangpumDTO();
dto.setCode(rs.getString("code"));
dto.setSang(rs.getString("sang"));
dto.setSu(rs.getInt("su"));
dto.setDan(rs.getInt("dan"));
list.add(dto);
}
//System.out.println("list : " + list.size()); //연결 되면 찍힐 것
} catch (Exception e) {
System.out.println("getDataAll err: " + e);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
return list;
}
public boolean insertData(SangpumBean bean) {
boolean b = false;
String sql = "";
try {
//새상품 코드 구하기 (마지막 최대 코드 구하기 +1)
sql="SELECT MAX(code) as max FROM sangdata";
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
int maxCode = 0; //데이터가 아예 없을 경우를 대비
if(rs.next()) {
maxCode = rs.getInt("max"); //max라는 별명의 column값을 읽어옴
}
maxCode += 1; //데이터가 아예 없어도 1부터 시작
//상품 입력
pstmt.close(); //여러번 사용해야 될 경우 한번 닫고 사용하는 걸 권고
sql = "INSERT INTO sangdata VALUES(?,?,?,?)";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, maxCode);
pstmt.setString(2, bean.getSang()); //client에서 입력한 자료 호출 (argument가 SangpumBean class의 객체이기 때문)
pstmt.setString(3, bean.getSu());
pstmt.setString(4, bean.getDan());
int re = pstmt.executeUpdate(); //re의 의미? 바뀐 데이터 자료수
/*
System.out.println(bean.getSang());
System.out.println(bean.getSu());
System.out.println(bean.getDan());*/
if(re == 1) b = true;
} catch (Exception e) {
System.out.println("insertData err: " + e);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
return b;
}
public SangpumDTO updateDataRead(String code) {
SangpumDTO dto = null;
String sql = "";
try {
sql = "SELECT * FROM sangdata WHERE code=?";
conn =ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, code);
rs = pstmt.executeQuery();
if(rs.next()) { //자료가 하나라는 것을 알때!
dto = new SangpumDTO();
dto.setCode(rs.getString(1));
dto.setSang(rs.getString(2));
dto.setSu(rs.getInt(3)); //SangpumDTO su, dan은 int 타입임
dto.setDan(rs.getInt(4));
}
} catch (Exception e) {
System.out.println("updataDataRead err: " + e);
}finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
return dto; //dto=null이면 수정 못하게
}
public boolean updateData(SangpumBean bean) {
boolean b = false;
try {
conn = ds.getConnection();
String sql = "UPDATE sangdata SET sang=?, su=?, dan=? WHERE code=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, bean.getSang());
pstmt.setString(2, bean.getSu());
pstmt.setString(3, bean.getDan());
pstmt.setString(4, bean.getCode());
if(pstmt.executeUpdate() > 0) b = true; //0보다 크면 뭔가가 바뀌었다는 말 | 값을 받아오는 게 아니라서 rs 안해도 됨
} catch (Exception e) {
System.out.println("updataData err: " + e);
}finally {
try {
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
return b;
}
public boolean deleteData(String code) {
boolean b = false;
try {
conn = ds.getConnection();
String sql = "DELETE FROM sangdata WHERE code=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, code);
if(pstmt.executeUpdate() > 0) b = true; //0보다 크면 뭔가가 바뀌었다는 말 | 값을 받아오는 게 아니라서 rs 안해도 됨
} catch (Exception e) {
System.out.println("deleteData err: " + e);
}finally {
try {
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
return b;
}
//
}

[beansDB2_ins.html]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>beanDB2_ins(상품추가용)</title> <!-- 추가를 내부적으로 하는 용도 -->
<script src="http://code.jquery.com/jquery-latest.js"></script> <!-- jQuery 사용가능 환경 만들기 (type X, src O) -->
<!-- src=주소 | type=xml,text/javascript 등.. -->
<script type="text/javascript">
$(document).ready(function(){ //$표시=jQuery에서 요소 선택 시 선언
$("#btnIns").click(function(){
//alert("a");
if($("#sang").val() === ""){
alert("상품명 입력");
return;
}
//...(나머지 입력자료 유효검사 생략 ex.focus, 정규표현식,...)
$("#frm").submit();
});
$("#btnList").bind("click",listFunc);
});
function listFunc(){
//alert("b");
location.href="beansDB2.jsp" //= history.back();
}
</script>
</head>
<body>
*상품 추가*<br>
<form action="beansDB2_ins.jsp" method="post" id="frm">
품명: <input type="text" name="sang" id="sang"><br> <!-- name을 DTO 변수와 일치시켜야 jsp액션 태그 자동화 사용가능 -->
수량: <input type="text" name="su" id="su"><br>
단가: <input type="text" name="dan" id="dan"><br>
<br>
<input type="button" value="자료 추가" id="btnIns">
<input type="reset" value="입력 취소">
<input type="button" value="목록 보기" id="btnList">
</form>
</body>
</html>
[beansDB2_ins.jsp]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%--business logic 임. client가 볼수 없음 --%>
<%
request.setCharacterEncoding("utf-8");
%>
<jsp:useBean id="bean" class="pack3.SangpumBean"/>
<jsp:setProperty property="*" name="bean"/> <%--알아서 들어감--%>
<%--두줄에 의해서 DB 입력 됨--%>
<jsp:useBean id="cdp" class="pack3.ConnDbPooling"/>
<%
boolean b = cdp.insertData(bean);
if(b)
response.sendRedirect("beansDB2.jsp");
else
response.sendRedirect("beansDB2_fail.html");
%>

[beansDB2_up.jsp]
<%@page import="pack3.SangpumDTO"%>
<%@ 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>
<%
request.setCharacterEncoding("utf-8");
String code = request.getParameter("code");
%>
<jsp:useBean id="cdp" class="pack3.ConnDbPooling"/>
<%
SangpumDTO dto = cdp.updateDataRead(code);
if(dto == null){
%>
<script>
alert("등록된 상품 코드가 아닙니다.\n수정불가");
location.href="beansDB2.jsp";
</script>
<%
return;
}
%>
<%--여기 부터 자바 <body> tag --%>
** 상품 수정 **<br>
<form action="beansDB2_upok.jsp" method="post">
코드: <%=dto.getCode() %><input type="hidden" name="code" value="<%=dto.getCode() %>"><br>
상품명: <input type="text" name="sang" value="<%=dto.getSang() %>"><br> <%-- 이름 맞춰줘야 jsp액션 태그 자동화 사용 가능 --%>
상품명: <input type="text" name="su" value="<%=dto.getSu() %>"><br>
상품명: <input type="text" name="dan" value="<%=dto.getDan() %>"><br>
<br>
<input type="submit" value="자료 수정">
<input type="button" value="목록 보기" onclick="javascript:location.href='beansDB2.jsp'">
</form>
</body>
</html>
[beansDB2_upok.jsp]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("utf-8"); //한글 넘어온다
%>
<jsp:useBean id="bean" class="pack3.SangpumBean"/>
<jsp:setProperty property="*" name="bean"/> <%--다 넘어와라--%>
<jsp:useBean id="cdp" class="pack3.ConnDbPooling"/>
<%
if(cdp.updateData(bean)){ //boolean type은 그냥 if 조건으로 쓸 수 있음
response.sendRedirect("beansDB2.jsp"); //수정 후 목록 보기
}else{
response.sendRedirect("beansDB2_fail.html");
}
%>


[beansDB2_del.jsp]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("utf-8");
String code = request.getParameter("code");
%>
<jsp:useBean id="cdp" class="pack3.ConnDbPooling"/>
<%
if(cdp.deleteData(code)){ //boolean type은 그냥 if 조건으로 쓸 수 있음
response.sendRedirect("beansDB2.jsp"); //삭제 후 목록 보기
}else{
response.sendRedirect("beansDB2_fail.html");
}
%>

[beansDB2_fail.html]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<b style="font-size: 30px; color: red;">작업실패!!!</b>
<br>
<a href="beansDB2.jsp">목록 으로 돌아가기</a>
</body>
</html>
'Programming Language > Servlet & JSP' 카테고리의 다른 글
[JSP] (최종 - Model Ⅰ방식) 간단한 쇼핑몰 게시판 만들어 보기 *갱신 필* (0) | 2020.09.02 |
---|---|
[JSP] 로그아웃, 로그인 화면 다르게 하기 (feat. session, include지시어) (0) | 2020.09.02 |
[JSP] (problem) (0) | 2020.08.26 |
[JSP] Bean으로 DB 연결 (feat. 향상된 for문) (0) | 2020.08.26 |
[JSP] (problem) Form Bean (0) | 2020.08.26 |