본문 바로가기
학원/servlet jsp

11.13일 (ajax / model-1 / 커넥션 풀)

by 쿠룽지 2023. 11. 15.
728x90
반응형
728x90

 

공결로 설명 미흡..

 

 

xml - json ajax로 연동해서 todoList 만드는 연습 하나 하고 model1 방식으로 db연동한 것 같음

 

 

ch05-ServletMain

webapp

ch16-ajax

dbInfo.jspf  (ch15거 복사해서 붙여넣기)

<%@ page language="java" contentType="text/plain; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
String driverName = "oracle.jdbc.OracleDriver";
String jdbcUrl = "jdbc:oracle:thin:@localhost:1521:xe";
String dbId = "c##user001";
String dbPass = "1234";
%>

contentType="text/plain" << json 타입

 

 

 

 

ch16-ajax

table.sql

create table todo(
 id number primary key, -- 할 일 번호
 todo varchar2(150) not null, -- 할 일
 created date not null, -- 등록일
 completed number(1) not null -- 할 일 수행 여부 0 미완료 1 완료
);
create sequence todo_seq;

 

저장 후 오라클에서 실행 -> todo table + todo_seq sequence 만들기

 

 

 

 

 

 

todoList.html (목록처리)

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>할 일 목록</title>
<link rel="stylesheet" href="https://unpkg.com/bootstrap@5.2.3/dist/css/bootstrap.min.css">
<style>
body{
	margin:0;
	padding:0;
	font-family:sans-serif;
}
.title{
	text-align:center;
	font-weight:bold;
	font-size:20pt;
}
.todo-done{
	text-decoration:line-through;
}
.container{
	padding:10px;
}
.pointer{
	cursor:pointer;
}
</style>
</head>
<body>
<div class="container">
	<div class="card card-body">
		<div class="title">할 일 목록</div>
	</div>
	<div class="card card-default">
		<div class="card-body">
        
			<!-- 입력창 시작 -->
			<div class="row mb-3">
				<div class="input-group">
					<input type="text" class="form-control" name="msg" placeholder="할 일을 여기에 입력!" id="todo">
					<span class="btn btn-primary input-group-addon" id="add_btn">추가</span> 
				</div>
			</div>
			<!-- 입력창 끝 -->
            
			<!-- 목록 시작 -->
			<div class="row">
				<div class="col">
					<ul class="list-group" id="list"></ul>
				</div>
			</div>
			<!-- 목록 끝 -->
            
		</div>
	</div>
</div>
<script type="text/javascript" src="../js/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
	//목록 처리
	function selectList(){
		$.ajax({
			url:'getTodoList.jsp',
			dataType:'json',
			success:function(param){
				//ul 태그 초기화
				$('#list').empty();
				
				$(param).each(function(index,item){
					let output = '';
					if(item.completed){//1이면 true
						output += '<li class="list-group-item list-group-item-success">';
						output += '<span class="pointer todo-done check-btn" data-id="'+item.id+'" data-check="'+item.completed+'">'+item.todo+' (완료)</span>';
					}else{//0이면 false
						output += '<li class="list-group-item">';
						output += '<span class="pointer check-btn" data-id="'+item.id+'" data-check="'+item.completed+'">'+item.todo+'(작성일:'+item.created+')</span>';
					}
					output += '<span class="float-end badge bg-secondary pointer delete-btn" id="'+item.id+'">삭제</span>';
					output += '</li>';
					$('#list').append(output);
				});
				
			},
			error:function(){
				alert('네트워크 오류 발생');
			}
		});
	}
	//초기 데이터 설정
	selectList();
	
	//삭제 이벤트 연결
	$(document).on('click','.delete-btn',function(){
		$.ajax({
			url:'deleteTodo.jsp',
			type:'post',
			data:{id:$(this).attr('id')},
			dataType:'json',
			success:function(param){
				if(param.result == 'success'){
					//목록 호출
					selectList();
				}else{
					//할 일 삭제 실패
					alert('할 일 삭제 오류 발생!');
				}
			}
		});
	});
	//할 일 체크 이벤트 연결
	$(document).on('click','.check-btn',function(){
		$.ajax({
			url:'updateTodo.jsp',
			type:'post',
			data:{id:$(this).attr('data-id'),completed:$(this).attr('data-check')},
			dataType:'json',
			success:function(param){
				if(param.result == 'success'){
					//목록 호출
					selectList();
				}else{
					//할일 체크/해제 실패
					alert('할 일 체크 오류 발생!');
				}
			},
			error:function(){
				alert('네트워크 오류 발생!');
			}
		});
	});
	//엔터키 이벤트 연결
	$('#todo').keydown(function(event){
		if(event.keyCode == 13){
			addTodo();
		}
	});
	//추가 버튼 이벤트 연결
	$('#add_btn').click(function(){
		addTodo();
	});
	
	//등록 처리 함수
	function addTodo(){
		if($('#todo').val().trim()==''){
			alert('할 일을 입력하세요');
			$('#todo').val('').focus();
			return;
		}
		$.ajax({
			url:'insertTodo.jsp',
			type:'post',
			data:{todo:$('#todo').val()},
			dataType:'json',
			success:function(param){
				if(param.result == 'success'){
					//할 일 등록 성공
					alert('할 일 등록 성공');
					//입력 창 초기화
					$('#todo').val('');
					//목록 호출 
					selectList();
				}
			},
			error:function(){
				alert('네트워크 오류 발생!');
			}
		});
	}
	
</script>
</body>
</html>

1) selectList (목록처리)

    :여러 번 목록이 호출되기 때문에 selectList를 함수 형태로 만들었음

     호출될 때마다 초기화 작업을 해서 새로운 목록을 추가하여 호출할 때에 중복되어 나타나는 값이 없도록 함

         $('#list').empty();

 

2) 할 일 체크 이벤트 연결 > updateform에 가면 토글 형태로 0 1 값을 가지게 만들어져있음

 

 

 

 

 

getTodoList.jsp (레코드 읽어오기)

<%@ page language="java" contentType="text/plain; charset=UTF-8"
    pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>
<%@ page import="java.sql.Date" %>
<%@ include file="dbInfo.jspf" %>  
[<% 
 	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	String sql = null;
	
	try{
		//JDBC 수행 1단계 : 드라이버 로드
		Class.forName(driverName);
		//JDBC 수행 2단계 : Connection 객체 생성
		conn = DriverManager.getConnection(jdbcUrl,dbId,dbPass);
		
		//SQL문 작성
		sql = "SELECT * FROM todo ORDER BY id DESC";
		
		//JDBC 수행 3단계 : PreparedStatement 객체 생성
		pstmt = conn.prepareStatement(sql);
		//JDBC 수행 4단계 : SQL문 실행
		rs = pstmt.executeQuery();
		while(rs.next()){
			int id = rs.getInt("id");
			String todo = rs.getString("todo");
			Date created = rs.getDate("created");
			int completed = rs.getInt("completed");
			
			if(rs.getRow()>1){
				out.print(",");
			}
%>
			{
				"id":<%= id %>,
				"todo":"<%= todo %>",
				"created":"<%= created %>",
				"completed":<%= completed %>
			}
<%			
		}
	}catch(Exception e){
		e.printStackTrace();
	}finally{
		//자원정리
		if(rs!=null)try{rs.close();}catch(SQLException e){}
		if(pstmt!=null)try{pstmt.close();}catch(SQLException e){}
		if(conn!=null)try{conn.close();}catch(SQLException e){}	
	}
	
 %>]

html 구문에 id~completed 값을 출력하는 구문이 들어가있는데

id = 숫자 todo/ created = 문자 completed = 숫자임

completed가 숫자로 인식되어야 boolean 타입 (토글 형태로 update)으로 사용할 수 있기 때문에 숫자 처리

 

 

 

 

 

insertTodo.jsp (레코드 추가)

<%@ page language="java" contentType="text/plain; charset=UTF-8"
    pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.SQLException" %>
<%@ include file="dbInfo.jspf" %>   
<%
	//전송된 데이터 인코딩 처리
	request.setCharacterEncoding("utf-8");
	//전송된 데이터 반환
	String todo = request.getParameter("todo");
	
	Connection conn = null;
	PreparedStatement pstmt = null;
	String sql = null;
	
	try{
		//JDBC 수행 1단계 : 드라이버 로드
		Class.forName(driverName);
		//JDBC 수행 2단계 : Connection 객체 생성
		conn = DriverManager.getConnection(jdbcUrl,dbId,dbPass);
		//SQL문 작성
		sql = "INSERT INTO todo (id,todo,created,completed) VALUES (todo_seq.nextval,?,SYSDATE,0)";
					//completed 수행x=0 수행o=1
		//JDBC 수행 3단계 : PreparedStatement 객체 생성
		pstmt = conn.prepareStatement(sql);
		//?에 데이터 바인딩
		pstmt.setString(1, todo);
		//JDBC 수행 4단계 : SQL문 실행
		pstmt.executeUpdate();
%>
		{"result":"success"}
<%		
	}catch(Exception e){
%>
		{"result":"failure"}
<%		
		e.printStackTrace();
	}finally{
		//자원정리
		if(pstmt!=null)try{pstmt.close();}catch(SQLException e){}
		if(conn!=null)try{conn.close();}catch(SQLException e){}
	}
%>

todo 값만 읽어오면 그외 나머지 id(sequence), created(sysdate), completed(0/1) 설정 가능하기 때문에

String todo = request.getParameter("todo"); 로 request에서 todo값만 읽어옴

 

 

 

 

 

updateTodo.jsp (todo 완료, 미완료 업데이트)

<%@ page language="java" contentType="text/plain; charset=UTF-8"
    pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %> 
<%@ page import="java.sql.SQLException" %>
<%@ include file="dbInfo.jspf" %>   
<%
	//전송된 데이터 인코딩 처리
	request.setCharacterEncoding("utf-8");
	//전송된 데이터 반환
	int id = Integer.parseInt(request.getParameter("id"));
	int completed = Integer.parseInt(request.getParameter("completed"));
	if(completed == 0) completed = 1;
	else completed = 0;
	
	Connection conn = null;
	PreparedStatement pstmt = null;
	String sql = null;
	
	try{
		//JDBC 수행 1단계 : 드라이버 로드
		Class.forName(driverName);
		//JDBC 수행 2단계 : Connection 객체 생성
		conn = DriverManager.getConnection(jdbcUrl,dbId,dbPass);
		//SQL문 작성
		sql = "UPDATE todo SET completed=? WHERE id=?";
		//JDBC 수행 3단계 : PreparedStatement 객체 생성
		pstmt = conn.prepareStatement(sql);
		//?에 데이터 바인딩
		pstmt.setInt(1, completed);
		pstmt.setInt(2, id);
		//JDBC 수행 4단계 : SQL문 실행
		pstmt.executeUpdate();
%>
		{"result":"success"}
<%		
	}catch(Exception e){
%>
		{"result":"failure"}
<%		
		e.printStackTrace();
	}finally{
		//자원정리
		if(pstmt!=null)try{pstmt.close();}catch(SQLException e){}
		if(conn!=null)try{conn.close();}catch(SQLException e){}			
	}
	
%>

완료 / 미완료 boolean 토글 형태

if(completed == 0) completed = 1;

else completed = 0;

 

 

 

 

 

deleteTodo.jsp (삭제)

<%@ page language="java" contentType="text/plain; charset=UTF-8"
    pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.SQLException" %>
<%@ include file="dbInfo.jspf" %>
<%
	//전송된 데이터 인코딩
	request.setCharacterEncoding("utf-8");
	//전달된 데이터 반환
	int id = Integer.parseInt(request.getParameter("id"));
	
	Connection conn = null;
	PreparedStatement pstmt = null;
	String sql = null;
	
	try{
		//JDBC 수행 1단계 : 드라이버 로드
		Class.forName(driverName);
		//JDBC 수행 2단계 : Connection 객체 생성
		conn = DriverManager.getConnection(jdbcUrl,dbId,dbPass);
		//SQL문 작성
		sql = "DELETE FROM todo WHERE id=?";
		//JDBC 수행 3단계 : PreparedStatement 객체 생성
		pstmt = conn.prepareStatement(sql);
		//?에 데이터 바인딩
		pstmt.setInt(1, id);
		//JDBC 수행 4단계
		pstmt.executeUpdate();
%>
		{"result":"success"}
<%		
	}catch(Exception e){
%>
		{"result":"failure"}
<%		
		e.printStackTrace();
	}finally{
		//자원정리
		if(pstmt!=null)try{pstmt.close();}catch(SQLException e){}
		if(conn!=null)try{conn.close();}catch(SQLException e){}		
	}
	
%>

todoList에서 id(pk) 전달 -> 정보 읽어와서 그 행 삭제

 

 

 

정보처리 시 ajax방식이 없는 경우가 상당히 드물고 특히 모바일은 필수적으로 들어가기 때문에

잘 익혀두는 게 좋음

 

일단 ajax 잠시 중단


 

model-1 방식 시작

 

 

 

 

 

 

UI를 만들어서 작업

ch17-member

main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원관리 메인</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<%
	String user_id = (String)session.getAttribute("user_id");
%>
<div class="page-main">
	<h1>회원관리 메인</h1>
	<div class="align-right">
		<%
			if(user_id==null){//로그인이 되지 않은 경우
		%>
		<a href="registerUserForm.jsp">회원가입</a>
		<a href="loginForm.jsp">로그인</a>		
		<%		
			}else{//로그인 된 경우
		%>
		<a href="myPage.jsp">MyPage</a>
		[<b><%= user_id %></b>님 로그인 중]
		<a href="logout.jsp">로그아웃</a>
		<%		
			}
		%>
	</div>
</div>
</body>
</html>
  • session에 user_id가 저장되는걸 사용해서 로그인/ 로그아웃 처리 (식별자)
  • String user_id = (String)session.getAttribute("user_id") - getAttribute는 Object로 반환되니까 String으로 강제 형변환
  • if user_id == null > 만약 user_id가 session에 없을 경우 (로그인이 안된 경우),
    •    a태그를 사용해 회원가입/ 로그인 목록을 보여주기 /html
  • else 로그인이 된 경우
    •    a태그에 MyPage(상세정보보기)/ user_id 정보/ 로그아웃 목록을 보여주기 /html

 

 


 

 

자바빈(JavaBeans)

: 웹 프로그래밍에서 데이터의 표현을 목적으로 사용

자바와 데이터베이스가 연동할 때 데이터를 보관하고 관리하는 class

더보기

public class Member{

/*값을 저장하는 필드*/

private String name;

 

/*필드의 값을 읽어오는 값*/

public String getName() {

   return name;

}

/*필드의 값을 변경하는 값*/

public void setName(String name){

   this.name = name;

}

}

  • 데이터를 모아서 메서드에 전달하는 게 효율적인데 그 역할이 자바빈
  • MemberVO 멤버변수 =  table.sql 컬럼
  • jsp에서 db연동 시에는 1:1로 연동하면 돼서 딱히 필요가 없는데 MemberDAO class를 만들어서 메서드 안에서 db연동하게 만들고 싶다면 자바빈을 만들어야 함
  • 자바에서 db연동 시 DAO class를 꼭 만드는데 DAO랑 VO는 꼭 만들어야함(강제적) -> mvc패턴의 필수요소라서

 

 

 

 

 

kr.member.vo

MemberVO.java

package kr.member.vo;

import java.sql.Date;

//자바빈 : 자바와 데이터베이스가 연동할 때 데이터를 보관하고 관리하는 클래스
//VO : Value Object
//DTO : Data Transfer Object
public class MemberVO {
	//멤버변수(프로퍼티)
	private int num;
	private String id;
	private String name;
	private String passwd;
	private String email;
	private String phone;
	private Date reg_date;
	
	//비밀번호 체크 (db 안 passwd와 사용자가 입력한 passwd 일치여부 체크)
	public boolean isCheckedPassword(String userPasswd) {
		//DB에 저장된 비밀번호	사용자가 입력한 비밀번호
		if(passwd.equals(userPasswd)) {//비밀번호 일치
			return true;
		}
		return false; //비밀번호 불일치
	}
	
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPasswd() {
		return passwd;
	}
	public void setPasswd(String passwd) {
		this.passwd = passwd;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public Date getReg_date() {
		return reg_date;
	}
	public void setReg_date(Date reg_date) {
		this.reg_date = reg_date;
	}
}

 

 

 


 

 

JSP와 DB 연동

1) JDBC

자바에서 DB 프로그래밍을 하기 위해 사용되는 API

JDBC API 사용 어플리케이션의 기본 구성

 

 

2) 커넥션 풀 (Connection Pool)

: 데이터베이스와 연결된 커넥션을 미리 만들어서 풀(pool) 속에 저장해두고 있다가 필요할 때에

커넥션을 풀에서 가져다 스고 다시 풀에 반환하는 기법

장점

풀 속에 미리 커넥션이 생성되어 있기 때문에 커넥션을 생성하는데 시간이 소비되지 않음
커넥션을 재사용하기 때문에 생성되는 커넥션 수가 많지 않음
커넥션을 생성하고 제거하는데 필요한 시간이 소요되지 않기 때문에 어플리케이션의 실행 속도가 빨라지며 한번에 생성될 수 있는 커넥션 수를 제어하기 때문에 동시 접속자 수가 많아도 웹 어플리케이션이 쉽게 다운되지 않음

 

 

 

싱글톤 패턴

  • 객체를 생성하고 호출하는걸 계속 반복하게 되면 객체 多 -> 메모리 부족 -> 속도 저하
  • 그렇기 때문에 속도를 개선하기 위해 (메모리 점유율을 낮추기 위해) MemberDAO를 하나만 만들어서 재활용함
  • 어떤 변수에 값을 담아서 사용하면 재활용할 수가 없는데 DAO는 변수가 없고 메서드 중심으로 사용함
  • 호출을 계속 하더래도 1개의 객체만 만들어지고 계속 반복하는 방식 -- > 싱글톤 패턴
  • 구성요소
    1) 생성자-private
    2) static- 객체 1번 생성, 공유

 

 

kr.member.dao

MemberDAO

package kr.member.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import kr.member.vo.MemberVO;
import kr.util.DBUtil;

public class MemberDAO {
	/*
	 * 싱글턴 패턴은 생성자를 private으로 지정해서 외부에서 호출할 수 없도록
	 * 처리하고 static 메서드를 호출해서 객체가 한 번만 생성되고 생성된 객체를
	 * 공유할 수 있도록 처리하는 방식을 의미 
	 */
	private static MemberDAO instance = new MemberDAO();
	
	public static MemberDAO getInstance() {
		return instance;
	}
	
	private MemberDAO() {}
	
	//회원가입
	public void insertMember(MemberVO member)throws Exception{ 
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql = null;
		
		try {
			//커넥션 풀로부터 커넥션 할당받아서 1~2단계는 신경안써도 됨
			//커넥션풀로부터 커넥션을 할당
			conn = DBUtil.getConnection(); //1~2단계 끝
			
			//SQL문 작성
			sql = "INSERT INTO smember (num,id,name,passwd,email,phone) VALUES (smember_seq.nextval,?,?,?,?,?)"; //reg_date는 default값이 있어서 명시 x
			
			//PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			
			//?에 데이터 바인딩
			pstmt.setString(1, member.getId()); //member에 넣었기 때문에 접근해서 빼내야함
			pstmt.setString(2, member.getName());
			pstmt.setString(3, member.getPasswd());
			pstmt.setString(4, member.getEmail());
			pstmt.setString(5, member.getPhone());
			
			//4단계 : sql문장 실행
			pstmt.executeUpdate();
			
		}catch(Exception e) { 
			throw new Exception(e); //원래 발생한 예외 문구 던지기
		}finally {
			DBUtil.executeClose(null, pstmt, conn); 
		}
	}
	/*
	 * 메서드를 통해 동작시킬 때 예외 발생 시 콘솔에는 에러가 뜨는데 화면엔 안뜸(정상작동된 것처럼 보이게 함)
	 * 그래서 에러 페이지가 전송되게 만들어야 하는데 그럼 catch가 없어야함
	 * catch가 없을 시 예외가 발생하게 되면 catch쪽으로 갈 수 없으니까 에러 페이지가 전송됨
	 * 
	 * catch를 아예 안쓰거나 catch를 던지면 됨
	 */
	
	
	//회원상세정보
	public MemberVO getMember(int num)throws Exception{ //num(pk)로 정보를 읽고 MemberVO에 담는 것
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql = null;
		MemberVO member = null;
		
		try {
			//커넥션풀로부터 커넥션을 할당
			conn = DBUtil.getConnection();
			//SQL문 작성
			sql = "SELECT * FROM smember WHERE num=?";
			//PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			//?에 데이터 바인딩
			pstmt.setInt(1, num);
			//SQL문 실행
			rs = pstmt.executeQuery();
			//pk로 1개의 레코드만 빼내기 때문에 if문 (여러개면 while)
			if(rs.next()) {
				member = new MemberVO(); //자바빈 객체 생성
				//아래로 다 명시하고 필요할 때 출력하던가 아님 원하는 것만 넣고 다 출력하던가 상관없는데 그냥 다 명시하고 뽑아내는게 편하다했음
				member.setNum(rs.getInt("num"));
				member.setId(rs.getString("id"));
				member.setPasswd(rs.getString("passwd"));
				member.setName(rs.getString("name"));
				member.setEmail(rs.getString("email"));
				member.setPhone(rs.getString("phone"));
				member.setReg_date(rs.getDate("reg_date"));
			}
		}catch(Exception e) {
			throw new Exception(e);
		}finally {
			DBUtil.executeClose(rs, pstmt, conn);
		}
		return member;
	}
	
	//아이디 중복 체크, 로그인 체크 (같이)
	public MemberVO checkMember(String id)throws Exception{
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql = null;
		MemberVO member = null; //여기다 넣고 반환할거라서
		
		try {
			//커넥션 풀로부터 커넥션을 할당
			conn = DBUtil.getConnection();
			//SQL문 작성
			sql = "SELECT * FROM smember WHERE id=?";
			//PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			//?에 데이터 바인딩
			pstmt.setString(1, id);
			//SQL문 실행
			rs = pstmt.executeQuery();
			if(rs.next()) { //행이 있으면 데이터를 넘겨줌 (id 중복 시)
				member = new MemberVO(); //자바빈(VO) 객체 생성
				member.setId(rs.getString("id"));
				member.setNum(rs.getInt("num"));
				member.setPasswd(rs.getString("passwd"));
			}//else는 없음 (MemberVO member = null가 있기 때문에 행이 없으면 null을 반환)
		}catch(Exception e) {
			throw new Exception(e); //예외를 던져야 예외발생 시 에러페이지가 보임
		}finally {
			DBUtil.executeClose(rs, pstmt, conn);
		}
		return member;
	}
	
	
	//회원정보수정
	public void updateMember(MemberVO member)throws Exception{
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql = null;
		
		try {
			//커넥션풀로부터 커넥션을 할당
			conn = DBUtil.getConnection();
			//SQL문 작성
			sql = "UPDATE smember SET name=?,passwd=?,email=?,phone=? WHERE num=?";
			//PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			
			//?에 데이터 바인딩
			pstmt.setString(1, member.getName());
			pstmt.setString(2, member.getPasswd());
			pstmt.setString(3, member.getEmail());
			pstmt.setString(4, member.getPhone());
			pstmt.setInt(5, member.getNum());
			
			//SQL문 실행
			pstmt.executeUpdate();
			
		}catch(Exception e) {
			throw new Exception(e);
		}finally{
			DBUtil.executeClose(null, pstmt, conn);
		}
	}
	
	//회원탈퇴(회원정보삭제)
	public void deleteMember(int num)throws Exception{
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql = null;
		
		try {
			//커넥션풀로부터 커넥션을 할당
			conn = DBUtil.getConnection();
			//SQL문 작성
			sql = "DELETE FROM smember WHERE num=?";
			//PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			//?에 데이터 바인딩
			pstmt.setInt(1, num);
			//SQL문 실행
			pstmt.executeUpdate();
		}catch(Exception e) {
			throw new Exception(e);
		}finally {
			DBUtil.executeClose(null, pstmt, conn);
		}
	}
	
}

>> getInstance를 사용해서 instance가 호출되면 객체 생성됨 static이라 한번만 만들어지고, 또 다른 데서 객체가 호출되면 새로 만들어지는 게 아니라 하나에 덮어씌워지는? 그런 형식으로 사용됨 (메모리 효과적으로 사용)

 

 

 

META-INF

context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>
	<!-- 
	auth : 컨테이너를 자원 관리자로 기술 
	maxTotal : 커넥션 풀에서 생성되는 최대 커넥션 숫자 
	maxIdle : 커넥션 풀 유지를 위해 최대 대기 커넥션 숫자
	-->
    <Resource name="jdbc/xe"
              auth="Container"
              type="javax.sql.DataSource"
              username="c##user001"
              password="1234"
              driverClassName="oracle.jdbc.OracleDriver"
              url="jdbc:oracle:thin:@localhost:1521:xe"
              maxTotal="20"
              maxIdle="10" />
</Context>

 

 


 

 

kr.util

DBUtil.java

package kr.util;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

public class DBUtil {
	//context.xml에서 설정 정보를 읽어들여 커넥션풀로부터 커넥션을 할당 받음
	public static Connection getConnection()throws Exception{
		Context initCtx = new InitialContext();
		//설정 정보를 읽어오기 위해 객체 생성
		DataSource ds = (DataSource)initCtx.lookup("java:comp/env/jdbc/xe");
		
		return ds.getConnection();
	}
	//자원정리
	public static void executeClose(ResultSet rs, 
			                       PreparedStatement pstmt,
			                       Connection conn) {
		if(rs!=null)try {rs.close();}catch(SQLException e) {}
		if(pstmt!=null)try {pstmt.close();}catch(SQLException e) {}
		if(conn!=null)try {conn.close();}catch(SQLException e) {}
	}
}

lookup("java:comp/env/jdbc/xe");
>>java:comp/env/
ex) 대한민국 안에 우리가 살고있는 것처럼 커다란 그룹(대한민국)
>>jdbc/xe 우리가 명시했던 식별자

 

 

 

대문 페이지 회원가입 란에서 데이터 넣고 전송 -> registerUser.jsp로 가서 DAO 호출, 자바빈에 데이터 담김

 

728x90
반응형