스프링/5. 스프링 DB-1

12. 커넥션 풀 적용

sdafdq 2023. 9. 28. 17:23
@Slf4j
public class MemberRepositoryV1 {
    private final DataSource dataSource;

    public MemberRepositoryV1(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    private void close(Connection con, Statement stmt, ResultSet rs){
        JdbcUtils.closeResultSet(rs);
        JdbcUtils.closeStatement(stmt);
        JdbcUtils.closeConnection(con);
    }

    private Connection getConnection() throws SQLException {
        Connection con = dataSource.getConnection();
        return con;
    }
}

바뀐 부분만 첨부했다.

먼저 외부로부터 DataSource를 주입받게 했다. (DataSource는 커넥션 풀이다.)

 

커넥션을 닫을 때, JdbcUtils에서 저렇게 간단하게 제공을 해 준다.

그냥 순서대로 닫으면 된다.

 

이제 커넥션을 얻어오는 것은 데이터 풀인 dataSource에서 얻어오게끔 했다.

 

참고로, close를 하게 되면 이제 커넥션을 완전히 닫아버리는 게 아니라, 아마 감싸고 있는 히카리커넥션풀이 풀에 반환하는 로직을 수행할거다.

뭐 아마도

public HikariDataSource{
	private ArrayList<HikariConnection> cPool;
    
    int awaitCount = 0;
    int blockCount = 0;
    int activeCount = 0;
    
    String url;
    String username;
    String password;
    
    HikariDataSource(){
    	
    }
    
    ~~~~~~
}


Enum State{
	Await = 1,
    Block = 2,
    Active = 3
}
public HikariConnection implement Connection {
bool canUse = false;
    State isState = State.Await;
    
    ~~~~~~~
    
    @override
    public void close(){
    	canUse = true;
    }
}

뭐 대충 이런 식으로 되어 있지 않을까 한다.

대충 커넥션 close를 하면 요런 식으로 히카리커넥션의 canUse를 true로 바꾸고 등

 

 

 

 

@Slf4j
public class MemberRepositoryV1Test {
    MemberRepositoryV1 repository;

    @BeforeEach
    public void initRepository(){
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl(URL);
        dataSource.setPassword(PASSWORD);
        dataSource.setUsername(USERNAME);
        dataSource.setMaximumPoolSize(10);
        dataSource.setPoolName("MyPool");

        repository = new MemberRepositoryV1(dataSource);
    }
    @Test
    public void crud() throws SQLException {

        String memberId= "member";
        Member member = new Member(memberId,14000);
        repository.save(member);

        Member resultMember = repository.findById(member.getMemberId());
        assertThat(member).isEqualTo(resultMember);

        repository.update(memberId,16000);
        Member updateMember = repository.findById(memberId);
        assertThat(updateMember.getMoney()).isEqualTo(16000);

        repository.delete(memberId);
        assertThatThrownBy(()->repository.findById(memberId))
                .isInstanceOf(NoSuchElementException.class);
    }
}

테스트 코드이다.

바뀐 점은 crud에서는 없고, 리포지토리를 바꾼 만큼 그것에 대한 초기화 작업이 필요하다.

 

@BeforeEach는 각 테스트가 시작하기 전에 실행되는 문장을 아래에 적용할 수 있는 애노테이션이다.

먼저 히카리DataSource를 생성하고,

기본 설정을 해준다. URL, USERNAME(id), PASSWORD

 

그리고 최고 풀 사이즈와 풀 이름은 설정 안해도 기본값으로 10이 들어가고,  이름은 뭐 defaultPool 이러지 않을까 싶다.

 

그리고 이제 리포지토리에 그 DataSource를 주입해준다.

 

리포지토리에서도 바뀐점은 이제 커넥션을 풀에서 주는 것 뿐이다.

DataSource 자체가 커넥션을 얻는 것에 집중한 인터페이스 이니까..

 

 

참고로, 커넥션 풀 설정할 때,

생성 자체를 DataSource해서 인터페이스에 의존하게끔 한 게 아니라 HikariDataSource 해서 아예 히카리껄로 생성을 했다.

이래야 히카리가 제공하는 setJdbcUrl, setUsername 등 쓸 수 있다.

그냥 DataSource는 저렇게 못 쓴다.

'스프링 > 5. 스프링 DB-1' 카테고리의 다른 글

14. DB 연결 구조와 DB 세션  (0) 2023.09.28
13. 트랜잭션  (0) 2023.09.28
11. 히카리 커넥션 풀  (0) 2023.09.28
10. DataSourceDriverManager  (0) 2023.09.28
9. DataSource  (0) 2023.09.28