위 문제를 해결하는 방법
-> 커넥션
을 미리 생성해두고 재사용하는 커넥션 풀
이 있다
커넥션 풀
: DB와 커넥션이 연결되어 있는 상태로 즉시 SQL을 DB에 전달 가능
커넥션 풀은 서버당 최대 커넥션 수를 제한할 수 있어서 DB를 보호해줌
실무에서 항상 기본으로 사용됨
대표적인 커넥션 풀 오픈소스 -> HikariCP
문제점 발생
-> DriveManager
을 통해 커넥션을 얻다가 커넥션 풀
로 변경하면 애플리케이션 코드를 변경해야함
-> DriveManager
은 DataSource
인터페이스를 사용하지 않는다
-> 스프링이 DriveManager
도 DataSource
를 통해서 사용할 수 있도록
DriveManagerDataSource
라는 DataSource
를 구현한 클래스를 제공
자바에서는 이런 문제를 해결하기 위해서 javax.sql.DataSource
인터페이스를 제공
DataSource
는 커넥션을 얻기 방법을 추상화하는 인터페이스
이 인터페이스의 핵심 기능은 커넥션 조회임 -> getConnection()
public interface DataSource {
Connection getConnection() throws SQLException;
}
자바는 DataSource
를 통해 커넥션을 얻는 방법을 추상화했다
애플리케이션 로직은 DataSource
인터페이스에만 의존하면 된다
효과로 DriveManagerDataSource
를 통해서 DriveManager
를 사용하다가 커넥션 풀
을 사용해도
애플리케이션 로직은 변경하지 않아도 됨
public class ConnectionTest {
void driverManager() throws SQLException {
Connection con1 = DriverManager.getConnection(URL, USERNAME, PASSWORD);
Connection con2 = DriverManager.getConnection(URL, USERNAME, PASSWORD);
}
}
public class ConnectionTest {
void dataSourceDriverManager() throws SQLException {
//DriverManagerDataSource - 항상 새로운 커넥션 획득
DriverManagerDataSource dataSource = new DriverManagerDataSource(URL, USERNAME, PASSWORD);
useDataSource(dataSource);
}
private void useDataSource(DataSource dataSource) throws SQLException {
Connection con1 = dataSource.getConnection();
Connection con2 = dataSource.getConnection();
}
}
위 두 코드의 차이점
DriverManager
은 커넥션을 얻을 때 마다 URL, USERNAME, PASSWORD와 같은 파라미터를 계속 전달
하지만 DataSource
를 사용하는 방식은 처음 객체를 생성할 때만 필요한 파라미터를 넘겨두고
커넥션을 얻을 때마다 단순히 getConnection()
만 호출하면 된다
즉 쉽게 말해서 설정
과 사용
을 분리한 것이다
DataSource
를 만들어서 필요한 속성들은 입력하는 것으로 관련된 속성들은 한 곳으로 분리DataSource
의 getConnection()
만 호출해서 사용 void dataSourceConnectionPool() throws SQLException, InterruptedException {
//커넥션 풀링: HikariProxyConnection(Proxy) -> JdbcConnection(Target)
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(URL);
dataSource.setUsername(USERNAME);
dataSource.setPassword(PASSWORD);
dataSource.setMaximumPoolSize(10); // 커넥션 풀 최대사이즈 지정
dataSource.setPoolName("MyPool"); // 풀 이름 지정
}
useDataSource(dataSource);
Thread.sleep(1000); //커넥션 풀에서 커넥션 생성 시간 대기
}