기존적으로 애플리케이션 서버가 db를 사용하려면
특정 db에 접근할 수 있는 것을 드라이버라 하는데, 어떤 db든 접근할 수 있는 java 표준 드라이버를 JDBC driver라고 한다.
이때 자바 진영에서는 JPA를 사용하면 각각 데이터베이스마다 다르게 sql을 정의해야 했던, 문제를 대부분 해결할 수 있다.
ORM 기술중 하나인 JPA가 개발자 대신에 SQL을 동적으로 만들어
실행해준다. 추가로 각각의 데이터베이스마다 다른 SQL을 사용하는 문제도 중간에서 해결해준다.
다음은 데이터베이스 커넥션의 획득 과정이다.
매번 커넥션을 새로 생성해 연결하는 문제를 한번에 해결하기위해 커넥션을 미리 생성해두고, 사용하는 것을 커넥션 풀이라 한다.
커넥션 풀에 있는 커넥션은 tcp/ip통신으로 db와 커넥션이 연결되어 있는 상태이기 때문에 sql을 db로 전달할때, 새로 커넥션을 맺을 필요없이 연결되어 있는 커넥션을 사용하여 sql을 전달한다.
이제 애플리케이션 로직은 db 드라이버를 통해 새로운 커넥션을 획득하는것이 아닌, 커넥션 풀을 통해 이미 생성되어 있는 커넥션을 객체 참조로 그냥 가져다 쓰면 된다.
커넥션을 모두 사용하고 나면 jdb driverManager에서 커넥션을 종료한것과 달리 해당 커넥션을 그대로 커넥션 풀에 반환하면 된다.
참고) 대표적인 커넥션풀로는 HikariCP와 tomcat-jdbc-pool등이 있는데,
spring boot 2.0부터는 기본 커넥션 풀로 HikariCP를 사용한다.
이제 커넥션 풀을 획득하는 방법으로는 JDBC driver manager을 사용하거나,
커넥션 풀을 이용하는 등 다양한 방법이 존재한다는 것을 알았다.
그런데 만약 driver manager를 사용하다가, HikariCP같은 커넥션 풀을 사용하면 어떻게 될까?
그렇게 되면, 커넥션을 획득하는 애플리케이션 코드를 변경해야 한다.
이런 문제를 해결하기 위해 자바는 커넥션을 획득하는 방법을 추상화한 datasource라는 인터페이스를 제공한다.
참고) DataSoucrce는 DriverManager 인터페이스를 사용하지 않기에
datasource를 사용하여 drivermanager를 사용하고 싶다면,
driverManagerDataSource라는 datasource를 구현한 클래스를 사용해야 한다.
물론, DriverManagerDataSource는 커넥션 풀을 사용하지 않기에 항상 새로운 커넥션이 생성된다.
Java는 커넥션을 획득하고 싶다면, Datasource 인터페이스에만 의존하면 된다. 커넥션 풀 구현 기술을 변경하고 싶다면, 해당 구현체로 갈아끼우기만 하면 된다.
커넥션 풀에서 커넥션을 생성하는 작업은 애플리케이션 실행 속도에 영향을 주지 않기 위해 별도의 쓰레드에서 작동한다.
커넥션 풀에 커넥션을 채우는 작업은 시간이 오래걸리기 때문에, 커넥션 풀을 채우는것과 별개로 쓰레드를 사용하여 어플리케이션이 실행시킨다.
DriverManager 는 커넥션을 획득할 때 마다 URL , USERNAME , PASSWORD 같은 파라미터를 계속 전달해야 한다.
Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
반면에 DataSource 를 사용하는 방식은 처음 객체를 생성할 때만 필요한 파리미터를 넘겨두고, 커넥션을 획득할 때는 단순히 dataSource.getConnection() 만 호출하면 된다.
DriverManagerDataSource dataSource = new DriverManagerDataSource(URL,
USERNAME, PASSWORD);
Connection connection = datasource.getConnection();
DataSource는 생성자를 통해 생성할 때, 매개변수에 URL, USERNAME, PASSWORD를 설정해 설정을 한 곳에 모아 놓았다.
설정은 신경쓰지 않고, DataSource 의 getConnection() 만 호출해서 Connection을 사용할 수 있다.
필요한 데이터를 DataSource 가 만들어지는 시점에 미리 다 넣어두게 되면, DataSource 를 사용하는 곳에서는 dataSource.getConnection() 만 호출하면 되므로, URL , USERNAME , PASSWORD 같은 속성들에 의존하지 않아도 된다. 그냥 DataSource 만 주입받아서 getConnection() 만 호출하면 된다. 이를 통해 설정을 한 곳에서만 관리하여, 유지 보수가 훨씬 편리해졌다.
<참고자료> : 스프링 DB 1편 - 데이터 접근 핵심 원리
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-db-1