동적 다중 데이터소스, sqlSession 작업중

main
semin.baek 11 months ago
parent 7babf9653e
commit 92ff4df5fe

@ -24,8 +24,11 @@ import java.util.Map;
@MapperScan("com.bsmlab.dfx.agent") @MapperScan("com.bsmlab.dfx.agent")
}) })
public class DfxAgentConfiguration { public class DfxAgentConfiguration {
// gradle bootRun 실행 설정
// bootRun --args="--embedded.db.file.directory=D:\projects\bsm-lab\dfx\dfxagent\src\docs\settings-examples --setting.file=D:\projects\bsm-lab\dfx\dfxagent\src\docs\settings-examples\dfxagent.json"
// command line java 실행 설정
// java -jar dfxagent.jar --embedded.db.file.directory=D:\projects\bsm-lab\dfx\dfxagent\src\docs\settings-examples --setting.file=D:\projects\bsm-lab\dfx\dfxagent\src\docs\settings-examples\dfxagent.json
// java -jar dfxagent.jar --embedded.db.file.directory=D:\projects\bsm-lab\dfx\dfxagent\src\docs\settings-examples --setting.file=D:\projects\bsm-lab\dfx\dfxagent\src\docs\settings-examples\dfxagent.json
// embedded.db.file.directory=D:\projects\bsm-lab\dfx\dfxagent\src\docs\settings-examples // embedded.db.file.directory=D:\projects\bsm-lab\dfx\dfxagent\src\docs\settings-examples
@Value("${embedded.db.file.directory}") @Value("${embedded.db.file.directory}")
private String embeddedDbFileDirectory; private String embeddedDbFileDirectory;
@ -58,42 +61,9 @@ public class DfxAgentConfiguration {
return sqlSessionFactoryBean; return sqlSessionFactoryBean;
} }
@Bean @Bean(name = "dynamicRoutingDataSource")
public DynamicRoutingDataSource dynamicRoutingDataSource(Settings settings) { public DynamicRoutingDataSource dynamicRoutingDataSource(Settings settings) {
DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource(); DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
Map<String, DataSourceDto> dataSourceDtoMap = settings.getDataSourceDtoMap();
for(String dataSourceId : dataSourceDtoMap.keySet()) {
DataSourceDto dataSourceDto = dataSourceDtoMap.get(dataSourceId);
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(dataSourceDto.getDriverClassName());
dataSource.setUrl(dataSourceDto.getUrl());
dataSource.setUsername(dataSourceDto.getUsername());
dataSource.setPassword(dataSourceDto.getPassword());
if(oracle.jdbc.driver.OracleDriver.class.getCanonicalName().equals(dataSourceDto.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1 FROM DUAL");
}
else if(org.postgresql.Driver.class.getCanonicalName().equals(dataSourceDto.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1");
}
else if(com.mysql.jdbc.Driver.class.getCanonicalName().equals(dataSourceDto.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1");
}
else if(org.mariadb.jdbc.Driver.class.getCanonicalName().equals(dataSourceDto.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1");
}
else if(com.ibm.db2.jcc.DB2Driver.class.getCanonicalName().equals(dataSourceDto.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1 FROM SYSIBM.SYSDUMMY1");
}
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);
dataSource.setTestOnCreate(true);
dataSource.setTestWhileIdle(true);
dataSource.setInitialSize(3);
dataSource.setMinIdle(3);
dataSource.setMaxIdle(30);
dataSource.setMaxTotal(30);
dynamicRoutingDataSource.addDataSource(dataSourceId, dataSource);
}
return dynamicRoutingDataSource; return dynamicRoutingDataSource;
} }
} }

@ -1,13 +1,19 @@
package com.bsmlab.dfx.agent.config.datasource; package com.bsmlab.dfx.agent.config.datasource;
import com.bsmlab.dfx.agent.config.Settings;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.ibatis.datasource.pooled.PooledDataSource; import org.apache.ibatis.datasource.pooled.PooledDataSource;
import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionManager;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -15,18 +21,60 @@ import java.util.Map;
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
@Service @Service
@DependsOn({"settings", "dynamicRoutingDataSource"})
public class DynamicDataSourceService { public class DynamicDataSourceService {
private final Settings settings;
private final DynamicRoutingDataSource dynamicRoutingDataSource; private final DynamicRoutingDataSource dynamicRoutingDataSource;
private final RefreshableSqlSessionFactoryBean refreshableSqlSessionFactoryBean; private final RefreshableSqlSessionFactoryBean refreshableSqlSessionFactoryBean;
private final Map<String, SqlSessionFactory> sqlSessionFactoryMap = new HashMap<>(); private final Map<String, SqlSessionFactory> sqlSessionFactoryMap = new HashMap<>();
private final Map<String, DataSourceTransactionManager> transactionManagerMap = new HashMap<>(); private final Map<String, DataSourceTransactionManager> transactionManagerMap = new HashMap<>();
public SqlSessionFactory getSqlSessionFactory(String dataSourceId) { public SqlSessionFactory getSqlSessionFactory(String dataSourceId) {
if(!this.sqlSessionFactoryMap.containsKey(dataSourceId)) { return this.sqlSessionFactoryMap.get(dataSourceId);
DataSource dataSource = this.dynamicRoutingDataSource.getDataSourceMap().get(dataSourceId); }
public TransactionManager getTransactionManager(String dataSourceId) {
return this.transactionManagerMap.get(dataSourceId);
}
@PostConstruct
public void init() {
Map<String, DataSourceDto> dataSourceDtoMap = settings.getDataSourceDtoMap();
for(String dataSourceId : dataSourceDtoMap.keySet()) {
DataSourceDto dataSourceDto = dataSourceDtoMap.get(dataSourceId);
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(dataSourceDto.getDriverClassName());
dataSource.setUrl(dataSourceDto.getUrl());
dataSource.setUsername(dataSourceDto.getUsername());
dataSource.setPassword(dataSourceDto.getPassword());
if(oracle.jdbc.driver.OracleDriver.class.getCanonicalName().equals(dataSourceDto.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1 FROM DUAL");
}
else if(org.postgresql.Driver.class.getCanonicalName().equals(dataSourceDto.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1");
}
else if(com.mysql.jdbc.Driver.class.getCanonicalName().equals(dataSourceDto.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1");
}
else if(org.mariadb.jdbc.Driver.class.getCanonicalName().equals(dataSourceDto.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1");
}
else if(com.ibm.db2.jcc.DB2Driver.class.getCanonicalName().equals(dataSourceDto.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1 FROM SYSIBM.SYSDUMMY1");
}
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);
dataSource.setTestOnCreate(true);
dataSource.setTestWhileIdle(true);
dataSource.setInitialSize(3);
dataSource.setMinIdle(3);
dataSource.setMaxIdle(30);
dataSource.setMaxTotal(30);
dynamicRoutingDataSource.addDataSource(dataSourceId, dataSource);
refreshableSqlSessionFactoryBean.setDataSource(dataSource); refreshableSqlSessionFactoryBean.setDataSource(dataSource);
this.sqlSessionFactoryMap.put(dataSourceId, refreshableSqlSessionFactoryBean.getObject()); sqlSessionFactoryMap.put(dataSourceId, refreshableSqlSessionFactoryBean.getObject());
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
transactionManagerMap.put(dataSourceId, transactionManager);
} }
return this.sqlSessionFactoryMap.get(dataSourceId);
} }
} }

@ -9,7 +9,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class DynamicRoutingDataSource extends AbstractRoutingDataSource { public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
private final Map<String, DataSource> dataSourceMap = new ConcurrentHashMap<>(); private final Map<Object, Object> dataSourceMap = new ConcurrentHashMap<>();
@Override @Override
protected Object determineCurrentLookupKey() { protected Object determineCurrentLookupKey() {
@ -24,17 +24,13 @@ public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
contextHolder.remove(); contextHolder.remove();
} }
public Map<String, DataSource> getDataSourceMap() { public Map<Object, Object> getDataSourceMap() {
return this.dataSourceMap; return this.dataSourceMap;
} }
public void addDataSource(String dataSourceId, DataSource dataSource) { public void addDataSource(String dataSourceId, DataSource dataSource) {
this.dataSourceMap.put(dataSourceId, dataSource); this.dataSourceMap.put(dataSourceId, dataSource);
Map<Object, Object> castingMap = new ConcurrentHashMap<>(); super.setTargetDataSources(this.dataSourceMap);
for(Object key : this.dataSourceMap.keySet()) {
castingMap.put(key, this.dataSourceMap.get(key));
}
super.setTargetDataSources(castingMap);
super.afterPropertiesSet(); super.afterPropertiesSet();
} }
} }

Loading…
Cancel
Save