HikariCP 사용하기

개발한 애플리케이션을 데이터베이스와 연결하여 사용할 때, 효율적으로 사용하기 위해서 보통 커넥션풀을 사용한다. 커넥션풀을 사용하기 위해서 여러가지 커넥션풀 라이브러리가 있는데, 우연히 HikariCP에 대해서 이야기를 들어 간단하게 설정해보았다.

우선 mvnrepository에서 HikariCP로 검색을 하면 Java6용과 Java7이상이 서로 다른 것을 알 수 있다. 사용하는 Java 버젼에 따라 알맞은 것을 선택하여 의존성관리 도구를 통해 해당 jar 파일을 내려 받는다.

image1

그 다음으로 HikariCP Github에 들어가 설정에 필요한 내용들(예를 들면 DataSource Class Name)을 확인하고, 자신에게 맞는 내용으로 설정해준다.

실제로 테스트를 위해 JPA를 하버이네이트 구현체로 사용하고, HikariCP를 사용하는 것까지의 설정을 아래와 같이 해줬다.

package com.eomdev.study.config;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.hibernate.cfg.AvailableSettings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

import javax.servlet.http.Cookie;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration
public class DataConfig {


    @Autowired
    private DatabaseProperties databaseProperties;

    @Bean
    public DataSource dataSource(){

        HikariConfig config = new HikariConfig();
        config.setJdbcUrl(databaseProperties.getUrl());
        config.setUsername(databaseProperties.getUsername());
        config.setPassword(databaseProperties.getPassword());
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");

        HikariDataSource dataSource = new HikariDataSource(config);

        return dataSource;
    }

    @Bean
    public JpaTransactionManager transactionManager(){
        return new JpaTransactionManager();
    }

    // LocalContainerEntityManagerFactoryBean : JPA를 스프링 컨테이너에서 사용할 수 있도록 스프링프레임워크가 제공하는 기능
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(){

        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        factoryBean.setDataSource(dataSource());
        factoryBean.setPackagesToScan("com.eomdev.study"); // @Entity 탐색위치
        factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());   // JPA 구현체로는 하이버네이트를 사용


        // 상세설정
        Properties jpaProperties = new Properties();
        jpaProperties.put(AvailableSettings.SHOW_SQL, true);    // SQL 보기
        jpaProperties.put(AvailableSettings.FORMAT_SQL, true);  // SQL 정렬해서 보기
        jpaProperties.put(AvailableSettings.USE_SQL_COMMENTS, true);    // SQL 코멘트 보기
        jpaProperties.put(AvailableSettings.HBM2DDL_AUTO, "create");    // DDL 자동생성
        jpaProperties.put(AvailableSettings.DIALECT, "org.hibernate.dialect.H2Dialect");    // 방언 설정
        jpaProperties.put(AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, true);   // 새 버젼의 ID생성 옵션
        jpaProperties.put("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");
        factoryBean.setJpaProperties(jpaProperties);

        return factoryBean;

    }

}

기존에 작성해뒀던 단위테스트를 통해 정상적으로 작동되는지 확인했고, 특별한 이상은 없었다.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringSecurityStudyApplication.class)
@WebAppConfiguration
@Slf4j
public class SpringSecurityStudyApplicationTests {

	@Autowired
	private AccountRepository accountRepository;

	@Test
	public void testAccount() {

		// given
		Account account = new Account();
		account.setEmail("testUser01@eomdev.com");
		account.setPassword("testPwd");
		account.setRole(Role.USER);
		LocalDateTime date = LocalDateTime.now();
		account.setCreateDate(date);

		// when
		Account afterAccount = accountRepository.save(account);
		log.info("{}", afterAccount.toString());

		// then
		assertThat(afterAccount.getCreateDate()).isEqualTo(date);

	}

}

실제로 스트레스 테스트를 통해 기존에 사용하던 다른 것들과의 성능면에서 얼만큼 차이가 있는지에 대해서는 실험해보지 않았고, 관련 내용으로 다른분이 블로깅한 내용이 있어 ConnectionPool 성능 측정 글을 참고하면 될 것 같다.

참고자료