기존의 데이터베이스에서 마이그레이션하고 최신의 데이터베이스에 값을 밀어넣기위해 두개이상의 디비 커넥션 하는방법을 찾아봤다. 여러가지 방법이있긴했지만, 생각보다 이론은 헷갈리는것 같긴한데.. 자꾸보다보면 이해할 수 있을것
같다.
1. application.properties
spring.datasource.main.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.main.jdbc-url=jdbc:log4jdbc:postgresql://ip:port/db
spring.datasource.main.username=
spring.datasource.main.password=
spring.datasource.sub.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.sub.jdbc-url=jdbc:log4jdbc:postgresql://ip:port/db
spring.datasource.sub.username=
spring.datasource.sub.password=
main 과 sub 로 두개로 나눠서 설정해준다.
2. config
@Configuration
@EnableTransactionManagement
@MapperScan(value="com.snk.lab.main", sqlSessionFactoryRef = "mainSqlSessionFactory")
public class MainDataSourceConfig {
@Primary
@Bean(name="mainDataSource")
@ConfigurationProperties(prefix = "spring.datasource.main")
public DataSource dataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Primary
@Bean(name="mainSqlSessionFactory")
public SqlSessionFactory mainSqlSessionFactory(@Qualifier("mainDataSource") DataSource mainDataSource
, ApplicationContext applicationContext) throws Exception{
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(mainDataSource);
sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath:mybatis/com/snk/lab/main/**/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Primary
@Bean(name="mainSqlSessionTemplate")
public SqlSessionTemplate mainSqlSessionTemplate(SqlSessionFactory mainSqlSessionFactory) throws Exception{
return new SqlSessionTemplate(mainSqlSessionFactory);
}
}
@Configuration
@EnableTransactionManagement
@MapperScan(value="com.snk.lab.sub", sqlSessionFactoryRef = "subSqlSessionFactory")
public class SubDataSourceConfig {
@Bean(name="subDataSource")
@ConfigurationProperties(prefix = "spring.datasource.sub")
public DataSource dataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Bean(name="subSqlSessionFactory")
public SqlSessionFactory subSqlSessionFactory(@Qualifier("subDataSource") DataSource subDataSource
, ApplicationContext applicationContext) throws Exception{
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(subDataSource);
sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath:mybatis/com/snk/lab/sub/**/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean(name="subSqlSessionTemplate")
public SqlSessionTemplate subSqlSessionTemplate(SqlSessionFactory subSqlSessionFactory) throws Exception{
return new SqlSessionTemplate(subSqlSessionFactory);
}
}
3. controller
@RestController
@RequestMapping("/migration")
public class MigrationController {
@Autowired
private MigrationService migrationService;
@PostMapping(value="/module")
public ResponseEntity<String> moduleMigration() {
try {
migrationService.moduleMigration();
return ResponseEntity.ok("Data migration completed successfully");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Data migration failed: " + e.getMessage());
}
}
}
4. service
@Service
public class MigrationService {
@Autowired
private MainDataBaseMapper mainMapper;
@Autowired
private SubDataBaseMapper subMapper;
@Transactional
public void moduleMigration() throws Exception {
// 기존 데이터베이스에서 정보를 가져옵니다.
List<Map<String, Object>> subData = subMapper.selectSubModuleInfo();
for(Map<String, Object> data : subData) {
Map<String, Object> transformData = transform(data);
System.out.println(transformData);
}
}
/*사용하던 코드라 그대로 복붙해서 이부분은 참고안해도됨.*/
public Map<String, Object> transform(Map<String, Object> originalData){
Map<String, Object> data = new HashMap<>();
data.put("del_yn", originalData.get("pmi_del_yn").toString()); // int 형태이기 때문에 문자열로 변경해줘야됨.
data.put("frst_reg_dt", originalData.get("last_reg_dt"));
return data;
}
}
5. mapper
@Mapper
public interface MainDataBaseMapper {
void insertMainInfo(Map<String, Object> data) throws Exception;
List<Map<String, Object>> getAllMainInfo() throws Exception;
}
@Mapper
public interface SubDataBaseMapper {
List<Map<String, Object>> getAllSubInfo() throws Exception;
List<Map<String, Object>> selectSubModuleInfo() throws Exception;
}
이때 각각의 경로를 다르게 해줘야하니 참고바람
ex) com.snk.lab.main.management.mapper , com.snk.lab.sub.management.mapper