package kr.wisestone.owl.config;
|
|
import com.zaxxer.hikari.HikariConfig;
|
import com.zaxxer.hikari.HikariDataSource;
|
import kr.wisestone.owl.config.persistence.aop.TransactionDefinitionInterceptor;
|
import kr.wisestone.owl.config.persistence.routing.TransactionDefinitionRoutingDataSource;
|
import org.apache.commons.lang3.StringUtils;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.flywaydb.core.Flyway;
|
import org.mybatis.spring.SqlSessionFactoryBean;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
import org.springframework.orm.jpa.JpaTransactionManager;
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
|
import org.springframework.transaction.interceptor.TransactionAttributeSource;
|
|
import javax.persistence.SharedCacheMode;
|
import javax.persistence.ValidationMode;
|
import javax.sql.DataSource;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* Created by jeong on 2017-08-02.
|
*/
|
@Configuration
|
@EnableTransactionManagement
|
@EnableJpaRepositories(
|
basePackages = {"kr.wisestone.owl.repository"},
|
entityManagerFactoryRef = "entityManagerFactory",
|
transactionManagerRef = "jpaTransactionManager"
|
)
|
@EnableAspectJAutoProxy
|
public class DataBaseConfiguration implements TransactionManagementConfigurer {
|
|
@Value("${db.primary.driverName}")
|
private String dbPrimaryDriverName;
|
@Value("${db.primary.url}")
|
private String dbPrimaryUrl;
|
@Value("${db.primary.userName}")
|
private String dbPrimaryUserName;
|
@Value("${db.primary.password}")
|
private String dbPrimaryPassword;
|
|
@Value("${db.replica1.url}")
|
private String dbReplica1PrimaryUrl;
|
@Value("${db.replica2.url}")
|
private String dbReplica2PrimaryUrl;
|
@Value("${db.replica3.url}")
|
private String dbReplica3PrimaryUrl;
|
@Value("${db.replica4.url}")
|
private String dbReplica4PrimaryUrl;
|
@Value("${db.replica5.url}")
|
private String dbReplica5PrimaryUrl;
|
|
@Bean
|
public TransactionDefinitionInterceptor transactionDefinitionInterceptor(TransactionAttributeSource transactionAttributeSource) {
|
return new TransactionDefinitionInterceptor(transactionAttributeSource);
|
}
|
|
@Bean
|
public DataSource dataSource() {
|
final TransactionDefinitionRoutingDataSource transactionDefinitionRoutingDataSource = new TransactionDefinitionRoutingDataSource();
|
final Map<Object, Object> targetDataSources = new HashMap<>();
|
|
this.setReplica(targetDataSources, this.dbReplica1PrimaryUrl, 1);
|
this.setReplica(targetDataSources, this.dbReplica2PrimaryUrl, 2);
|
this.setReplica(targetDataSources, this.dbReplica3PrimaryUrl, 3);
|
this.setReplica(targetDataSources, this.dbReplica4PrimaryUrl, 4);
|
this.setReplica(targetDataSources, this.dbReplica5PrimaryUrl, 5);
|
|
transactionDefinitionRoutingDataSource.setDefaultTargetDataSource(this.buildDataSource("primaryHikariPool", this.dbPrimaryUrl, this.dbPrimaryUserName, this.dbPrimaryPassword, this.dbPrimaryDriverName)); // master db
|
transactionDefinitionRoutingDataSource.setTargetDataSources(targetDataSources);
|
return transactionDefinitionRoutingDataSource;
|
}
|
|
// 리플리카 설정
|
private void setReplica(Map<Object, Object> targetDataSources, String replicaUrl, int count) {
|
if (!StringUtils.isEmpty(replicaUrl)) {
|
targetDataSources.put("replica" + count, this.buildDataSource("replicaHikariPool" + count, replicaUrl, this.dbPrimaryUserName, this.dbPrimaryPassword, this.dbPrimaryDriverName));
|
}
|
}
|
|
private DataSource buildDataSource(String poolName, String jdbcUrl, String userName, String password, String driverClassName) {
|
HikariConfig hikariConfig = new HikariConfig();
|
hikariConfig.setMinimumIdle(40);
|
hikariConfig.setConnectionTimeout(10000);
|
hikariConfig.setMaxLifetime(58000);
|
hikariConfig.setValidationTimeout(10000);
|
hikariConfig.setMaximumPoolSize(40);
|
hikariConfig.setConnectionTestQuery("SELECT 1");
|
hikariConfig.setPoolName(poolName);
|
hikariConfig.setJdbcUrl(jdbcUrl);
|
hikariConfig.setUsername(userName);
|
hikariConfig.setPassword(password);
|
hikariConfig.setDriverClassName(driverClassName);
|
|
return new HikariDataSource(hikariConfig);
|
}
|
|
@Override
|
public PlatformTransactionManager annotationDrivenTransactionManager() {
|
return this.jpaTransactionManager();
|
}
|
|
@Bean
|
public PlatformTransactionManager jpaTransactionManager() {
|
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
|
jpaTransactionManager.setEntityManagerFactory(this.entityManagerFactory().getObject());
|
return jpaTransactionManager;
|
}
|
|
@Bean
|
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
|
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect");
|
|
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
|
factory.setJpaVendorAdapter(adapter);
|
factory.setDataSource(this.dataSource());
|
factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
|
factory.setValidationMode(ValidationMode.NONE);
|
factory.setPackagesToScan("kr.wisestone.owl.domain");
|
factory.setMappingResources("META-INF/orm.xml");
|
factory.setJpaPropertyMap(this.getJpaProperties());
|
|
return factory;
|
}
|
|
private Map<String, Object> getJpaProperties() {
|
Map<String, Object> jpaProperties = new HashMap<>();
|
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
|
jpaProperties.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
|
jpaProperties.put("hibernate.physical_naming_strategy", "kr.wisestone.owl.domain.strategy.PrefixNamingStrategy");
|
jpaProperties.put("hibernate.show_sql", "false");
|
jpaProperties.put("hibernate.format_sql", "true");
|
jpaProperties.put("hibernate.use_sql_comments", "true");
|
jpaProperties.put("hibernate.session_factory.interceptor", "kr.wisestone.owl.domain.interceptor.AuditLogInterceptor");
|
|
return jpaProperties;
|
}
|
|
@Bean
|
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
|
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
|
|
sqlSessionFactoryBean.setDataSource(dataSource);
|
sqlSessionFactoryBean.setConfigLocation(
|
new PathMatchingResourcePatternResolver().getResource("classpath:/mybatis/config/mybatis-config.xml")
|
);
|
sqlSessionFactoryBean.setMapperLocations(
|
new PathMatchingResourcePatternResolver().getResources("classpath:/mybatis/query-template*//*.xml")
|
);
|
|
return sqlSessionFactoryBean.getObject();
|
}
|
|
@Bean(initMethod = "migrate")
|
public Flyway flyway(DataSource dataSource) {
|
Flyway flyway = new Flyway();
|
flyway.setBaselineOnMigrate(true);
|
flyway.setLocations("classpath:/migration");
|
flyway.setDataSource(dataSource);
|
|
return flyway;
|
}
|
}
|