본문 바로가기

강의 정리/JSP & Servlet (Seoul Wiz)

20. 커넥션 풀

1. DAO와 DTO

 

(1) DAO

- Data Access Object

- 데이터 베이스에 접속에서 CRUD 작업을 수행하는 클래스

- 보통 유지보수 및 코드의 모듈화를 위해 별도의 DAO 클래스를 만들어 사용

 

MemberDAO.java (servlet파일)

package dao_dto;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class MemberDAO
 */
@WebServlet("/MemberDAO")
public class MemberDAO extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	// DB 접속정보 변수에 저장
	private String url = "jdbc:oracle:thin:@localhost:1521:xe";
	private String uid = "scott";
	private String upw = "tiger";
    /**
     * Default constructor. 
     */
    
	// DAO 메소드 정의
	public MemberDAO() {
        // TODO Auto-generated constructor stub
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
    }
    
	// DTO객체에 DB정보를 저장하는 메소드 정의
	public ArrayList<MemberDTO> memberSelect() {
		// TODO Auto-generated method stub
		
		ArrayList<MemberDTO> dtos = new ArrayList<MemberDTO>();
		
		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		
		try {
			con = DriverManager.getConnection(url, uid, upw);
			stmt = con.createStatement();
			rs = stmt.executeQuery("select * from member");
			
			while (rs.next()) {
				String name = rs.getString("name");
				String id = rs.getString("id");
				String pw = rs.getString("pw");
				String phone1 = rs.getString("phone1");
				String phone2 = rs.getString("phone2");
				String phone3 = rs.getString("phone3");
				String gender = rs.getString("gender");
				
				MemberDTO dto = new MemberDTO(name, id, pw, phone1, phone2, phone3, gender);
				dtos.add(dto);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			try {
				if (rs != null) rs.close();
				if (stmt != null) stmt.close();
				if (con != null) con.close();
			} catch (Exception e2) {
				// TODO: handle exception
				e2.printStackTrace();
			}
		}

		return dtos;
	}
    

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

(2) DTO

- Data Transfer Object

- DAO클래스를 이용해 데이터 베이스에서 데이터를 관리할 때 DTO클래스를 사용

 

 

MemberDTO.java (JAVA클래스 파일)

package dao_dto;

public class MemberDTO {

	// 변수 정의
	private String name;
	private String id;
	private String pw;
	private String phone1;
	private String phone2;
	private String phone3;
	private String gender;
	
	// DAO에서 데이터 받아옴
	public MemberDTO(String name, String id, String pw, String phone1, String phone2, String phone3, String gender) {
		this.name = name;
		this.id = id;
		this.pw = pw;
		this.phone1 = phone1;
		this.phone2 = phone2;
		this.phone3 = phone3;
		this.gender = gender;		
	}

	// getter와 setter 정의		
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPw() {
		return pw;
	}

	public void setPw(String pw) {
		this.pw = pw;
	}

	public String getPhone1() {
		return phone1;
	}

	public void setPhone1(String phone1) {
		this.phone1 = phone1;
	}

	public String getPhone2() {
		return phone2;
	}

	public void setPhone2(String phone2) {
		this.phone2 = phone2;
	}

	public String getPhone3() {
		return phone3;
	}

	public void setPhone3(String phone3) {
		this.phone3 = phone3;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}
	
	
	
	
}

 

 

 

 

(3) DAO와 DTO를 이용한 DB 작업

 

memberSelect.jsp (결과 출력 페이지)

<%@page import="dao_dto.MemberDTO"%>
<%@page import="java.util.ArrayList"%>
<%@page import="dao_dto.MemberDAO"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	
	
	<%
		// DAO로 불러온 DB 정보를 DTO 객체에 저장
		MemberDAO memberDAO = new MemberDAO();
		ArrayList<MemberDTO> dtos = memberDAO.memberSelect();
		
		// for문으로 회원정보를 변수에 풀어서 저장
		for (int i=0; i<dtos.size(); i++) {
			MemberDTO dto = dtos.get(i);
			String name = dto.getName();
			String id = dto.getId();
			String pw = dto.getPw();
			String phone = dto.getPhone1() + " - " + dto.getPhone2() + " - " + dto.getPhone3();
			String gender = dto.getGender();
			
			// 회원정보 출력
			out.println("이름 : " + name + ", 아이디 : " + id + ", 비밀번호 : " + pw + ", 연락처 : " + phone + ", 성별: " + gender + "<br />");						
		}
		
	%>

</body>
</html>

 

 

회원정보 조회 결과

 

DAO와 DTO의 적용

 

 

 

 

 

 

2. PreparedStatement 객체

- SQL문 실행을 위해 사용하는 Statement 객체는 중복코드가 많아지는 단점이 있음

- 이러한 단점을 보완하기 위해 PreparedStatement 객체 사용

 

 

① memberDataInsert.jsp : PreparedStatement객체를 이용해 DB에 데이터 저장

<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
    
    <!-- 변수 선언 및 정의 -->
    <%!
    	Connection con;
    	PreparedStatement pstmt;
    	ResultSet rs;
    	
    	String driver = "oracle.jdbc.driver.OracleDriver";
    	String url = "jdbc:oracle:thin:@localhost:1521:xe";
    	String uid = "scott";
    	String upw = "tiger";
    %>
    
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>

	<%
		try{ // 반복 작업을 PreparedStatement로 간편화화여 데이터 삽입
			Class.forName(driver);
			con = DriverManager.getConnection(url, uid, upw);
			int n;
			String query = "insert into memberforpre (id, pw, name, phone) values (?, ?, ?, ?)";
			pstmt = con.prepareStatement(query);
			
			pstmt.setString(1, "tyk");
			pstmt.setString(2, "123");
			pstmt.setString(3, "김태연");
			pstmt.setString(4, "010-5939-1937");
			n = pstmt.executeUpdate();
			
			pstmt.setString(1, "ejj");
			pstmt.setString(2, "642");
			pstmt.setString(3, "정은지");
			pstmt.setString(4, "010-3817-1084");
			n = pstmt.executeUpdate();
			
			pstmt.setString(1, "dongone");
			pstmt.setString(2, "593");
			pstmt.setString(3, "강동원");
			pstmt.setString(4, "010-2039-5382");
			n = pstmt.executeUpdate();
			
			if(n == 1) {
				out.println("insert success");
			} else {
				out.println("insert fail");
			}
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			try { // 접속 종료
				if(rs != null) rs.close();
				if(pstmt != null) pstmt.close();
				if(con != null) con.close();
			} catch(Exception e) {}
		}
	%>
	
	<br />
	<a href="memberDataView.jsp">회원정보 보기</a>
</body>
</html>

 

memberDataInsert.jsp 실행 화면

 

 

 

② memberDataView.jsp : DB에 저장된 데이터 출력 페이지

<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
    
    <!-- 변수 선언 및 정의 -->
    <%!
    	Connection con;
    	Statement stmt;
    	ResultSet rs;
    	
    	String driver = "oracle.jdbc.driver.OracleDriver";
    	String url = "jdbc:oracle:thin:@localhost:1521:xe";
    	String uid = "scott";
    	String upw = "tiger";
    	String query = "select * from memberforpre";
    %>
    
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<%
		try{ // DB 접속
			Class.forName(driver);
			con = DriverManager.getConnection(url, uid, upw);
			stmt = con.createStatement();
			rs = stmt.executeQuery(query);
			
			// 레코드의 값을 받아와서 변수에 저장하고 출력 
			while(rs.next()) {
				String id = rs.getString("id");
				String pw = rs.getString("pw");
				String name = rs.getString("name");
				String phone = rs.getString("phone");
				
				out.println("아이디 : " + id + ", 비밀번호 : " + pw + ", 이름 : " + name + ", 전화번호 : " + phone + "<br />");
			}
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			try { // 접속 종료
				if(rs != null) rs.close();
				if(stmt != null) stmt.close();
				if(con != null) con.close();
			} catch(Exception e) {}
		}
	%>

</body>
</html>

 

memberDataView.jsp 실행 화면

 

 

 

 

 

 

 

 

3. 커넥션 풀 

- DBCP (DataBase Connection Pool)

- 클라이언트에 다수의 요청이 발생할 경우 데이터 베이스에 부하가 발생하는 문제를 해결하기 위해 사용한다

- 미리 커넥션 풀을 만들어두고 요청시 바로바로 가져다 쓸 수 있게 해준다

 

다수의 요청 발생시 DB에 부하가 발생

 

 

① Servers/Tomcat v8.5 Server at localhost-config/context.xml 파일에 DB 접속 정보를 입력하여 톰켓 서버가 바로 커넥션을 담당하도록 해준다

    <Resource
    	auth="Container"
    	driverClassName="oracle.jdbc.driver.OracleDriver"
    	url="jdbc:oracle:thin:@localhost:1521:xe"
    	username="scott"
    	password="tiger"
    	name="jdbc/Oracle11g"
    	type="javax.sql.DataSource"
    	maxActive="50"
    	maxWait="1000"
    	/>

 

② MemberDAO.java 파일 비교

- 커넥션을 미리 처리하였기 때문에 바로바로 get으로 불러오기만 하면 된다

package com.javalec.cpool;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;

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

public class MemberDAO {

//	private String url = "jdbc:oracle:thin:@localhost:1521:xe";
//	private String uid = "scott";
//	private String upw = "tiger";
	
	private DataSource dataSource;
	
	public MemberDAO() {
		
//		try {
//			Class.forName("oracle.jdbc.driver.OracleDriver");
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
		
		try {
			Context context = new InitialContext();
			dataSource = (DataSource)context.lookup("java:comp/env/jdbc/Oracle11g");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public ArrayList<MemberDTO> memberSelect() {
		
		ArrayList<MemberDTO> dtos = new ArrayList<MemberDTO>();
		
		Connection con =null;
		Statement stmt = null;
		ResultSet rs = null;
		
		try {
//			con = DriverManager.getConnection(url, uid, upw);
			con = dataSource.getConnection();
			stmt = con.createStatement();
			rs = stmt.executeQuery("select * from member");
			
			while (rs.next()) {
				String name = rs.getString("name");
				String id = rs.getString("id");
				String pw = rs.getString("pw");
				String phone1 = rs.getString("phone1");
				String phone2 = rs.getString("phone2");
				String phone3 = rs.getString("phone3");
				String gender = rs.getString("gender");
				
				MemberDTO dto = new MemberDTO(name, id, pw, phone1, phone2, phone3, gender);
				dtos.add(dto);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(rs != null) rs.close();
				if(stmt != null) stmt.close();
				if(con != null) con.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return dtos;
	}
	
}

 

 

커넥션 풀을 이용해 DB정보 불러오기에 성공한 모습

 

 

'강의 정리 > JSP & Servlet (Seoul Wiz)' 카테고리의 다른 글

21. 회원 인증 프로그래밍  (0) 2019.08.20
19. Oracle 데이버 베이스 (3)  (0) 2019.08.14
18. Oracle 데이터 베이스 2  (0) 2019.08.14
17. Oracle 데이터 베이스 1  (0) 2019.08.14
16. JAVA Bean  (0) 2019.08.14