Notice
Recent Posts
Recent Comments
관리 메뉴

Developer Gonie

[9주차] 26. JDBC에서 커넥션풀을 적용하는 방법 본문

K-DigitalTraining 강의/8. JSP

[9주차] 26. JDBC에서 커넥션풀을 적용하는 방법

이대곤 2022. 7. 19. 18:32

1. 커넥션 객체란?

DB와 미리 연결 해놓은 객체를 커넥션 객체라고 한다.

아래의 코드를 참고해 볼때 getConnection() 메소드의 결과로 얻어진 conn 객체를 말하는거 같다.

public class MovieDao {
	
	String driver = "oracle.jdbc.driver.OracleDriver";
	String url = "jdbc:oracle:thin:@localhost:1521:orcl";
	String id = "jspid";
	String pw = "jsppw";

	Connection conn = null;

	// 생성자를 public 으로 해주지 않으면 클래스를 찾을 수 없다는 오류가 자꾸 뜸.
	public MovieDao() {
		// 1. 드라이버로드
		try {
			Class.forName(driver);
			System.out.println("드라이버 로드 성공");
		} catch (ClassNotFoundException e) {
			System.out.println("드라이버 로드 실패");
		}
	}

	void getConnection() {
		// 2. 계정에 접속
		try {
			conn = DriverManager.getConnection(url, id, pw);
			System.out.print("접속성공: ");
			System.out.println(conn);
		} catch (SQLException e) {
			System.out.println("접속에러");
		}
	}
}

2. 커넥션풀(DataBase Connection Pool, DBCP)이란?

웹서비스가 실행되면 DB와 연결해놓은 커넥션 객체들을 pool 이라는 공간에 지정한 갯수만큼 저장해 두었다가

클라이언트 요청이 오면 이 커넥션 객체를 빌려줬다가 다 사용하면 다시 이를 반납받아 pool에 되돌려 놓는 방식을 말한다. 
반납되는 커넥션 객체는 연결이 종료되지 않은 상태이다.

 

기존에 매번 DAO 객체를 생성해서 DB 연산을 수행했던 때를 생각해보자.

매번 사용자가 DB관련 요청을 할 때마다 드라이버를 로드하고 커넥션 객체를 생성하여 작업을 끝내면 연결을 종료하였다.

만약 이미 DB와 연결을 해놓은 커넥션 객체를 빌려써 드라이버 로드, 연결종료 단계를 생략할 수 있다면 좀 더 효율적일 것이다.

이것을 가능하게 하기위해 커넥션풀(DBCP)을 사용하는 것이다.

 

특징(장점)

- pool에 미리 커넥션 객체가 생성되어 있기 때문에, 요청마다 커넥션 객체를 생성하는데 들었던 연결 시간이 절약된다.

- 또한, DB에 가해지는 연결 부하가 줄어든다.

- 커넥션 객체를 재사용하기 때문에 생성되는 커넥션 객체의 수를 특정 개수로 제한해둔다.

- 동시접속자가 많아 사용가능한 커넥션 객체가 없는 경우, 사용자는 커넥션 객체가 다른 사용자로부터 반환될 때 까지
   대기 상태로 전환시킨다.

- 커넥션 풀을 크게 설정하면 메모리의 소모가 큰 대신에 사용자의 대기시간이 줄어들고, 반대로 커넥션 풀을 적게 설정하면
   그만큼 대기시간이 줄어든다. 따라서 웹사이트에 걸리는 부하에 따라 조정해야 한다.

- 무엇보다 속도가 향상되고, 동시접속자 수를 제한하기에 접속자가 증가해도 서버가 쉽게 다운되지 않는다.

출처 : https://linked2ev.github.io/spring/2019/08/14/Spring-3-%EC%BB%A4%EB%84%A5%EC%85%98-%ED%92%80%EC%9D%B4%EB%9E%80/

3. 커넥션 풀의 종류

참고 : https://steady-coding.tistory.com/564

1) commons-dbcp

- 아파치에서 제공하는 대표적인 커넥션 풀 라이브러리이다. 수업중에 사용한 것이 이것이다.

 

2) tomcat-jdbc-pool

- Spring boot 2.0.0 하위 버전에서 사용되던 디폴트 DBCP이다.

 

3) HikariCP

- 스프링 부트 2.0부터 디폴트 DBCP으로 사용되는 중이다.

4. 커넥션풀을 적용하는 방법(commons-dbcp 적용)

0. 기존에 JDBC와 jsp 사용할 때 필요하던 2개의 파일도 lib 폴더 아래에 넣어줌.
- ojdbc8.jar

- servlet-api.jar

 

1. 3개의 zip 파일을 다운받아 압축을 풀어 jar 형식으로 놔두고 이를 프로젝트의 lib 폴더 밑에 위치시킴.

빨간 체크 표시로 들어가

아래 파일에 기재된 버전을 다운로드 받아야 하지만 지금보니 완전 옛날버전인가보다 존재하지 않는다.

2. Context.xml 파일을 META-INF 폴더 아래 위치시켜줌

<?xml version="1.0" encoding="UTF-8"?>
<Context>
   <Resource name="jdbc/OracleDB"
      auth="Container"
      type="javax.sql.DataSource"
      username="jspid"
      password="jsppw"
      driverClassName = "oracle.jdbc.driver.OracleDriver" 	 
      factory="org.apache.commons.dbcp.BasicDataSourceFactory"
      url = "jdbc:oracle:thin:@localhost:1521:orcl"
      maxActive="80"
      maxIdle = "100"/>
</Context>

name : 이런 설정들을 이 이름으로 부르겠다는 의미
username, password, driverClassName, url : 기존에 JDBC 할 때 사용했던 그대로임
maxActive : 동시에 사용할 수 있는 최대 커넥션 개수(기본값: 8)
maxIdle : 커넥션 풀에 반납할 때 최대로 유지될 수 있는 커넥션 개수(기본값: 8) -> 동시접속자가 많아지면 숫자를 키우면 됨

3. jsp 페이지에서 사용자가 DB에 접근하려고 한다면 이 코드를 삽입하여 커넥션 객체 사용 가능하게 하기

   이 코드 아래에서는 똑같이 conn 객체를 이용해서 DB 관련 작업을 수행하면됨

<%@page import="java.sql.ResultSet"%>
<%@page import="javax.sql.DataSource"%>
<%@page import="javax.naming.InitialContext"%> <!-- javax 패키지는 추가해준 3개의 jar화일에 존재 -->
<%@page import="javax.naming.Context"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%
   request.setCharacterEncoding("UTF-8");

   Connection conn = null;
   PreparedStatement ps = null;
   
   /* Context.xml을 한 번 살펴봐라 */
   Context initContext = new InitialContext(); 
   /* 내가 설정한 Context.xml 정보가 comp/env 폴더 안에 들어감 */
   Context envContext = (Context)initContext.lookup("java:comp/env");
   /* 위 폴더가서 jbdc/OracleDb 이름으로 설정한 것을가져와라 */
   DataSource ds = (DataSource)envContext.lookup("jdbc/OracleDB"); 
   
   // 사용자가 사이트에 접속하면 컨넥션 객체를 얻음. 그리고 이 컨넥션 객체를 가지고 로그인을 하고 자시고 하는거임. 등등의 DB작업 
   conn = ds.getConnection();
   System.out.println("conn :"+conn);
%>
Comments