오봉이와 함께하는 개발 블로그
Servlet - Servlet DB연동(Connection Pool) 본문
728x90
Connection Pool(커넥션 풀 : DBCP(DataBase Connection Pool))
- 등장 배경
- 기존 데이터베이스 연결 방법의 문제점
- 애플리케이션에서 데이터베이스 연결 과정에서 시간이 많이 소요
- 해결 방안
- 애플리케이션 실행 시 미리 Connection 객체를 생성하고, 미리 데이터베이스 연결을 해 놓음
- 애플리케이션은 데이터베이스 연동 작업 발생 시 미리 생성되어 있는 Connection객체를 이용해 작업
- 기존 데이터베이스 연결 방법의 문제점
커넥션 풀
- 일정량의 DB Connection 객체를 Pool에 저장해 두고 클라이언트 요청이 있을 때 마다 가져다 사용하고 반환
- 클라이언트에서 다수의 요청이 발생될 경우 요청마다 DB Connection 객체를 생성하게 되면 데이터베이스에 부하가 발생하기 때문에 커넥션 풀 기법 이용
- JDBC를 통하여 DB에 연결하게 되면 사용자의 요청이 있을 때마다 매번 드라이버를 로드하고 커넥션 객체를 생성하여 연겨라고 종료하는 작업을 반복하면 비효율적
- 장점
- 풀 속에 미리 커넥션이 생성되어 있기 때문에 커넥션 생성에 시간이 걸리지 않음
- 커넥션을 계속 사용하고 반환하기 때문에 재사용 가능하므로 많은 수의 커넥션을 만들지 않아도 된다.
- 매번 커넥션을 생성하고 해제하는데 시간이 소요되지 않으므로 애플리케이션 실행 속도가 빨라진다.
- 생성되는 커넥션 수를 제어하기 때문에 동시 접속자 수가 증가해도 애플리케이션이 쉽게 Down되지 않는다.
- 접속 시 사용할 커넥션이 없으면 대기 상태로 전환되고, 반환되면 대기 순서대로 커넥션 제공
- 동작 과정
- 톰캣 컨테이너를 실행한 후 응용프로그램 실행
- 톰캣 컨테이너 실행 시 ConnectionPool 객체 생성
- 생성된 커넥션객체는 DBMS와 미리 연결
- 데이터베이스 연동 작업이 필요할 경우 응용 프로그램은 ConnectionPool에서 제공하는 메소드를
- 호출하여 연동
- context.xml, web.xml에 추가
<!-- context.xml -->
<Resource
name="jdbc/mysql"
type="javax.sql.DataSource"
auth="Container"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/servletdb?serverTimezone=UTC"
username="root"
password=""
maxActive="50"
maxWait="1000"
/>
<!-- maxWait : 커넥션이 없을 때 대기 시간 (1000 : 1초) 음수이면 무한 대기
<Resource
name="데이터베이스 이름"
auth="Container"
driverClassName="oracle.jdbc.driver.OracleDriver"
type="javax.sql.DataSource"
url="jdbc:oracle:thin:@ip주소:포트번호:전역 데이터베이스 이름"
username="데이터베이스 아이디"
password="데이터베이스 비밀번호"
maxActive="20"
maxIdle="10"
maxWait="5000" />
-->
<!-- web.xml -->
<resource-ref>
<description>Connection</description>
<res-ref-name>jdbc/mysql</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<!--
<resource-ref>
<description>Connection</description>
<res-ref-name>자신의 데이터베이스 이름</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
-->
커넥션 풀 예제 - MemberDAO.java, MemberVO.java, MemberSelectServlet.java
public class MemberDAO {
private Connection con = null;
DataSource dataSource = null;
// 생성자에서 DB연결 설정
public MemberDAO() {
try {
Context init = new InitialContext();
dataSource = (DataSource)init.lookup("java:comp/env/jdbc/mysql");
System.out.println("연결 성공");
} catch (Exception e) {
System.out.println("연결 실패");
e.printStackTrace();
}
}
package com.example.servlet4.sec06;
import java.util.Date;
public class MemberVO {
private String id;
private String pwd;
private String name;
private String email;
private Date joinDate;
// 디폴트 생성자
public MemberVO() { }
// 현재는 매개변수 있는 생성자 필요 없다.
public MemberVO(String id, String pwd, String name, String email, Date joinDate) {
this.id = id;
this.pwd = pwd;
this.name = name;
this.email = email;
this.joinDate = joinDate;
}
public MemberVO(String id, String pwd, String name, String email) {
this.id = id;
this.pwd = pwd;
this.name = name;
this.email = email;
}
// Getter / Setter
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getJoinDate() {
return joinDate;
}
public void setJoinDate(Date joinDate) {
this.joinDate = joinDate;
}
}
package com.example.servlet4.sec06;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
//@WebServlet(name = "MemberSelectServlet", value = "/MemberSelectServlet")
@WebServlet("/sec06/MemberSelectServlet")
public class MemberSelectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doProcess(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doProcess(request, response);
}
protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 서버에서 클라이언트로 데이터 전송에 자바 IO스트림 이용
PrintWriter out = response.getWriter();
MemberDAO dao = new MemberDAO();
ArrayList<MemberVO> memList = dao.memberSelect();
out.print("<html><head></head><body>");
out.print("<table border=1><tr align='center' bgcolor='gold'>");
out.print("<td>아이디</td><td>비밀번호</td><td>이름</td><td>이메일</td>" +
"<td>가입일</td></tr>");
for(int i = 0; i < memList.size(); i++) {
// 오브젝트 반환 MemberVO 타입으로 형변환
MemberVO vo = (MemberVO)memList.get(i);
String id = vo.getId();
String pwd = vo.getPwd();
String name = vo.getName();
String email = vo.getEmail();
Date joinDate = vo.getJoinDate();
// 한 행씩 출력
out.print("<tr><td>" + id + "</td><td>" +
pwd + "</td><td>" +
name + "</td><td>" +
email + "</td><td>" +
joinDate + "</td></tr>");
}
out.print("</table></body></head>");
}
}
커넥션 풀 연습 - MemberDAO.java, MemberVO.java, MemberSelectServlet2.java, MemberInsertServlet.java, MemberDeleteServlet.java
package com.example.servlet4.sec06;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
public class MemberDAO {
private Connection con = null;
DataSource dataSource = null;
// 생성자에서 DB연결 설정
public MemberDAO() {
try {
Context init = new InitialContext();
dataSource = (DataSource)init.lookup("java:comp/env/jdbc/mysql");
System.out.println("연결 성공");
} catch (Exception e) {
System.out.println("연결 실패");
e.printStackTrace();
}
}
// 회원 정보 조회 메소드(전체 회원 정보 select : MemberVO 반환)
// MemberVO를여러 행 반환 : ArrayList<MemberVO>
public ArrayList<MemberVO> memberSelect() {
Connection con = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
ArrayList<MemberVO> memList = new ArrayList<MemberVO>();
try {
con = dataSource.getConnection();
String query = "select * from member";
preparedStatement = con.prepareStatement(query);
resultSet = preparedStatement.executeQuery(query);
while(resultSet.next()) { // 결과 세트에서 한 행씩 처리
// 한 행(회원 1명당) 처리
String id = resultSet.getString("memId");
String pwd = resultSet.getString("memPwd");
String name = resultSet.getString("memName");
String email = resultSet.getString("memEmail");
Date joinDate = resultSet.getDate("memJoinDate");
// 한 행 정보 가져와 memberVO에 Setter 이용하여 저장
MemberVO vo = new MemberVO();
vo.setId(id);
vo.setPwd(pwd);
vo.setName(name);
vo.setEmail(email);
vo.setJoinDate(joinDate);
// 각 memberVO를 ArrayList에 저장
memList.add(vo);
}
System.out.println("회원 조회 성공");
} catch (Exception e) {
e.printStackTrace();
System.out.println("회원 조회 실패");
} finally {
try {
resultSet.close();
preparedStatement.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return memList;
}
// 회원 정보 등록하는 메소드
public void memberInsert(MemberVO memberVO) {
try {
con = dataSource.getConnection();
String sql = "insert into member values(?, ?, ?, ?, default)";
PreparedStatement preparedStatement = con.prepareStatement(sql);
preparedStatement.setString(1, memberVO.getId());
preparedStatement.setString(2, memberVO.getPwd());
preparedStatement.setString(3, memberVO.getName());
preparedStatement.setString(4, memberVO.getEmail());
int result = preparedStatement.executeUpdate();
if (result > 0) {
System.out.println("회원 정보 입력 성공");
}
preparedStatement.close();
con.close();
} catch (Exception e) {
System.out.println("insert 오류 발생!");
e.printStackTrace();
}
}
// 회원 정보 삭제 메소드
public void memberDelete(String id ) {
try {
con = dataSource.getConnection();
String sql = "delete from member where memId=?";
PreparedStatement preparedStatement = con.prepareStatement(sql);
preparedStatement.setString(1, id);
// 쿼리문 실행 : 영향을 받은 행의 수 반환
//select : executeQuery - 결과 행 resultSet 반환.
//insert / update / delete : executeUpdate() - 영향을 받은 행의 수 반환
int result = preparedStatement.executeUpdate();
if(result > 0) {
System.out.println("회원 정보 삭제 성공!");
}
// 모든 객체 close() : 리소스 반납
preparedStatement.close();
con.close();
} catch (Exception e) {
System.out.println("delete 발생!");
e.printStackTrace();
}
}
}
package com.example.servlet4.sec06;
import java.util.Date;
public class MemberVO {
private String id;
private String pwd;
private String name;
private String email;
private Date joinDate;
// 디폴트 생성자
public MemberVO() { }
// 현재는 매개변수 있는 생성자 필요 없다.
public MemberVO(String id, String pwd, String name, String email, Date joinDate) {
this.id = id;
this.pwd = pwd;
this.name = name;
this.email = email;
this.joinDate = joinDate;
}
public MemberVO(String id, String pwd, String name, String email) {
this.id = id;
this.pwd = pwd;
this.name = name;
this.email = email;
}
// Getter / Setter
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPwd() {return pwd;}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getJoinDate() {
return joinDate;
}
public void setJoinDate(Date joinDate) {
this.joinDate = joinDate;
}
}
package com.example.servlet4.sec06;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
//@WebServlet(name = "MemberSelectServlet", value = "/MemberSelectServlet")
@WebServlet("/sec06/MemberSelectServlet2")
public class MemberSelectServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doProcess(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doProcess(request, response);
}
protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 서버에서 클라이언트로 데이터 전송에 자바 IO스트림 이용
PrintWriter out = response.getWriter();
MemberDAO dao = new MemberDAO();
ArrayList<MemberVO> memList = dao.memberSelect();
out.print("<html><head></head><body>");
out.print("<table border=1><tr align='center' bgcolor='gold'>");
out.print("<td>아이디</td><td>비밀번호</td><td>이름</td><td>이메일</td>" +
"<td>가입일</td><td>삭제</td></tr>");
for(int i = 0; i < memList.size(); i++) {
// 오브젝트 반환 MemberVO 타입으로 형변환
MemberVO vo = (MemberVO)memList.get(i);
String id = vo.getId();
String pwd = vo.getPwd();
String name = vo.getName();
String email = vo.getEmail();
Date joinDate = vo.getJoinDate();
// 한 행씩 출력
out.print("<tr><td>" + id + "</td><td>" +
pwd + "</td><td>" +
name + "</td><td>" +
email + "</td><td>" +
joinDate + "</td><td>" +
"<a href='/MemberDeleteServlet?id=" + id + "'>삭제</a></td></tr>");
}
out.print("</table></body></head>");
}
}
package com.example.servlet4.sec06;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Scanner;
@WebServlet("/sec06/MemberInsertServlet")
public class MemberInsertServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doProcess(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doProcess(request, response);
}
protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String id = request.getParameter("user_id");
String pwd = request.getParameter("user_pw");
String name = request.getParameter("user_name");
String email = request.getParameter("user_email1");
MemberVO memberVO = new MemberVO();
memberVO.setId(id);
memberVO.setPwd(pwd);
memberVO.setName(name);
memberVO.setEmail(email);
// or
// MemberVO memberVO = new MemberVO(id, pwd, name,email);
MemberDAO memberDAO = new MemberDAO();
memberDAO.memberInsert(memberVO);
}
}
package com.example.servlet4.sec06;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
//@WebServlet("/MemberDeleteServlet")
@WebServlet(name = "MemberDeleteServlet", value = "/MemberDeleteServlet")
public class MemberDeleteServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doProcess(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doProcess(request, response);
}
protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String id = request.getParameter("id");
MemberDAO dao = new MemberDAO();
dao.memberDelete(id);
// select 결과 페이지로 포워딩
response.sendRedirect("sec06/MemberSelectServlet2");
}
}
728x90
'BE > Servlet' 카테고리의 다른 글
Servlet - 세션 트래킹(웹 페이지 사이 정보 공유)<hidden> 태그 사용 (0) | 2021.12.29 |
---|---|
Servlet - 포워딩 (0) | 2021.12.29 |
Servlet - Servlet DB 연동(기본 JDBC) (0) | 2021.12.28 |
Servlet - DOM 객체, name 속성, jQuery 사용 (0) | 2021.12.28 |
Servlet - Servlet 요청 API (0) | 2021.12.27 |
Comments