Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 스프링 핵심 원리
- JPQL
- http
- Exception
- 인프런
- SpringBoot
- jpa
- kotlin
- 자바
- java
- 그리디
- Proxy
- db
- Greedy
- Thymeleaf
- QueryDSL
- JDBC
- Android
- 스프링
- springdatajpa
- pointcut
- Servlet
- 알고리즘
- 스프링 핵심 기능
- 백준
- Spring Boot
- 김영한
- AOP
- transaction
- spring
Archives
- Today
- Total
개발자되기 프로젝트
DataSource 적용 본문
package hello.jdbc.repository;
import hello.jdbc.domain.Member;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.support.JdbcUtils;
import javax.sql.DataSource;
import java.sql.*;
import java.util.NoSuchElementException;
/**
* JDBC - DataSource 사용, JDBCUtils 사용
*/
@Slf4j
public class MemberRepositoryV1 {
private final DataSource dataSource;
public MemberRepositoryV1(DataSource dataSource) {
this.dataSource = dataSource;
}
//save
//find
//update
//delete
private void close(Connection conn, Statement stmt, ResultSet rs){
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(stmt);
JdbcUtils.closeConnection(conn);
}
private Connection getConnection() throws SQLException {
Connection con = dataSource.getConnection();
log.info("get Connection={}, class={}", con, con.getClass());
return con;
}
}
- DataSource 의존관계 주입
외부에서 DataSource 를 주입 받아서 사용한다.
이제 직접 만든 DBConnectionUtil 을 사용하지않아도 된다. - DataSource 는 표준 인터페이스 이기 때문에
DriverManagerDataSource 에서 HikariDataSource 로 변경되어도 해당 코드를 변경하지 않아도 된다. - JdbcUtils 편의 메서드
스프링은 JDBC를 편리하게 다룰 수 있는 JdbcUtils 라는 편의 메서드를 제공한다.
JdbcUtils 을 사용하면 커넥션을 좀 더 편리하게 닫을 수 있다.
Test
package hello.jdbc.repository;
import com.zaxxer.hikari.HikariDataSource;
import hello.jdbc.domain.Member;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import java.sql.SQLException;
import java.util.NoSuchElementException;
import static hello.jdbc.connection.ConnectionConst.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@Slf4j
class MemberRepositoryV1Test {
MemberRepositoryV1 repository;
@BeforeEach
void beforeEach(){
//기본 DriverManager - 항상 새로운 커넥션 획득
// DriverManagerDataSource dataSource = new DriverManagerDataSource(URL, USERNAME, PASSWORD);
//커넥션 풀링
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(URL);
dataSource.setUsername(USERNAME);
dataSource.setPassword(PASSWORD);
repository = new MemberRepositoryV1(dataSource);
}
@Test
void crud() throws SQLException {
//save
Member member = new Member("memberV5", 10000);
repository.save(member);
//findById
Member findMember = repository.findById(member.getMemberId());
log.info("findMember={}", findMember);
assertThat(findMember).isEqualTo(member);
//update: money 10000 -> 20000
repository.update(member.getMemberId(), 20000);
Member updatedMember = repository.findById(member.getMemberId());
assertThat(updatedMember.getMoney()).isEqualTo(20000);
//delete
repository.delete(member.getMemberId());
assertThatThrownBy(() -> repository.findById(member.getMemberId()))
.isInstanceOf(NoSuchElementException.class);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
DriverManagerDataSource 사용(DriverManager)
get connection=conn0: url=jdbc:h2:.. user=SA class=class org.h2.jdbc.JdbcConnection
get connection=conn1: url=jdbc:h2:.. user=SA class=class org.h2.jdbc.JdbcConnection
get connection=conn2: url=jdbc:h2:.. user=SA class=class org.h2.jdbc.JdbcConnection
get connection=conn3: url=jdbc:h2:.. user=SA class=class org.h2.jdbc.JdbcConnection
get connection=conn4: url=jdbc:h2:.. user=SA class=class org.h2.jdbc.JdbcConnection
get connection=conn5: url=jdbc:h2:.. user=SA class=class org.h2.jdbc.JdbcConnection
DriverManagerDataSource 를 사용하면 conn0~5 번호를 통해서 항상 새로운 커넥션이 생성되는걸 확인 가능.
HikariDataSource 사용
get connection=HikariProxyConnection@xxxxxxxx1 wrapping conn0: url=jdbc:h2:...user=SA
get connection=HikariProxyConnection@xxxxxxxx2 wrapping conn0: url=jdbc:h2:...user=SA
get connection=HikariProxyConnection@xxxxxxxx3 wrapping conn0: url=jdbc:h2:...user=SA
get connection=HikariProxyConnection@xxxxxxxx4 wrapping conn0: url=jdbc:h2:...user=SA
get connection=HikariProxyConnection@xxxxxxxx5 wrapping conn0: url=jdbc:h2:...user=SA
get connection=HikariProxyConnection@xxxxxxxx6 wrapping conn0: url=jdbc:h2:...user=SA
- 커넥션 풀 사용시 conn0 커넥션이 재사용 된 것을 확인할 수 있다.
- 테스트는 순서대로 실행되기 때문에 커넥션을 사용하고 다시 돌려주는 것을 반복한다.
- 따라서 conn0 만 사용된다.
- 웹 애플리케이션에 동시에 여러 요청이 들어오면 여러 쓰레드에서 커넥션 풀의 커넥션을 다양하게 가져가는
상황을 확인할 수 있다.
DI
- DriverManagerDataSource --> HikariDataSource 로 변경해도
MemberRepositoryV1 의 코드는 전혀 변경하지 않아도 된다. - MemberRepositoryV1 는 DataSource 인터페이스에만 의존하기 때문이다.
- 이것이 DataSource 를 사용하는 장점이다.(DI + OCP)
'인프런 > [인프런] 스프링 DB 1편 - 데이터 접근 핵심 원리' 카테고리의 다른 글
데이터베이스 연결 구조와 DB 세션 (0) | 2022.06.01 |
---|---|
트랜잭션 - 개념이해 (0) | 2022.06.01 |
DataSource 예제2-커넥션 풀 (0) | 2022.05.29 |
DriverSource 예제1-Driver Manager (0) | 2022.05.29 |
Data Source 이해 (0) | 2022.05.29 |
Comments