본문 바로가기

플밍 is 뭔들/SPRING

[Spring Batch] 스프링 배치 Mybatis + ( Oracle + MsSql ) 다중 DB 연동

기존 사용하던 배치는  Oracle이었다.
그리고 거기에 MsSql을 추가해야 할 일이 생겼다.
 
물론 될것같긴 했지만 확실하게 확인해보는게 좋을 것 같아 새 프로젝트에서 Oracle + MsSql 세팅을 간단히 해보고 정상적으로 작동하는지 확인해 보기로 했다.
 
프로젝트의 구조는 기존의 프로젝트 구조와 동일한 형태로 만들어 테스트했다.
 
 
1.프로젝트 생성
   Eclipse -> New -> Other -> Spring Starter Project (스프링 부트  프로젝트 생성)
 
 
2,프로젝트 구조 잡기
   패키지 및 설정파일을 기존 프로젝트와 최대한 동일하게 생성
 
 
 
 
3.DatabaseConfig 파일 생성 (Oracle -> 메인 데이터베이스, MsSql -> 서브 데이터베이스)
   Oracle Config  파일(OracleConfig.java)
@Configuration
@EnableTransactionManagement
public class OracleConfig {
       @Bean(name ="dataSource")
       @Primary
       @ConfigurationProperties(prefix = "spring.datasource")
       public DataSource db1DataSource() {
             return DataSourceBuilder.create().build();
       }
       
       @Bean(name="sqlSessionFactory")
       @Primary
       public SqlSessionFactory dbSqlSessionFactory(@Qualifier("dataSource")  DataSource dbDataSource, ApplicationContext applicationContext) throws Exception  {
             
               SqlSessionFactoryBean sqlSessionFactoryBean = new  SqlSessionFactoryBean();
               sqlSessionFactoryBean.setDataSource(dbDataSource);
               //Mapper 경로 설정 (src/main/resources/mappers/oracle/*.xml)
               sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath:mappers/oracle/*.xml")); 
               return sqlSessionFactoryBean.getObject();
       }
       
        @Bean(name = "sqlSessionTemplate")
        @Primary
        public SqlSessionTemplate db1SqlSessionTemplate(SqlSessionFactory  dbSqlSessionFactory) throws Exception {
               return new SqlSessionTemplate(dbSqlSessionFactory);
        }
        
}
 
   MsSql Config 파일 (MsSqlConfig.java)
@Configuration
@MapperScan(value ="demo.mssql.dao", sqlSessionFactoryRef =  "msSqlSqlSessionFactory")  //value = "@Mapper 패키지 경로"
@EnableTransactionManagement
public class MsSqlConfig {
    
    @Bean(name="msSqlDataSource")
    @ConfigurationProperties(prefix="spring.ms.datasource")
    public DataSource db2DataSource() {
        return DataSourceBuilder.create().build();
    }
   
    @Bean(name = "msSqlSqlSessionFactory")
    public SqlSessionFactory db2SqlSessionFactory(@Qualifier("msSqlDataSource")  DataSource db2DataSource, ApplicationContext applicationContext) throws  Exception {
 
        SqlSessionFactoryBean sqlSessionFactoryBean = new  SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(db2DataSource);
        //Mapper 경로 설정 (src/main/resources/mappers/mssql/*.xml)
        sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath:mappers/mssql/*.xml"));
        return sqlSessionFactoryBean.getObject();
    }
 
    @Bean(name = "msSqlSqlSessionTemplate")
    public SqlSessionTemplate  db2SqlSessionTemplate(@Qualifier("msSqlSqlSessionFactory") SqlSessionFactory  db2SqlSessionFactory) throws Exception {
         return new SqlSessionTemplate(db2SqlSessionFactory);
    }
}
 
   application.properties 
#datasource
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.jdbc-url=jdbc:oracle:thin:@localhost:1521:xe
spring.datasource.username=username
spring.datasource.password=password
 
#datasource
spring.ms.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.ms.datasource.jdbc-url=jdbc:sqlserver://localhost:1433;databaseName=TEST
spring.ms.datasource.username=username
spring.ms.datasource.password=password
 
4.Job 구현 및 Dao, DaoImpl 구현하기
   Job 구현
     - Mybatis 연동이 아니므로 이 글에서는 다루지 않는다. 간단히 어떤식으로 작동하게 할건지 얘기해 보면 메인 디비(Oracle)에서 데이트를 조회해서 그 데이터를 서브 디비(MsSql)에 Insert를 하였다. 즉 Orcle관련된 내용은 SELECT / MsSql 관련된 내용은 INSERT라고 보면 된다.
 
   Dao
@Mapper
public interface OracleDao{
       public void insertOracleTest (HashMap<String, Object> map);
       public List<HashMap<String, Object>> selectOracleTest(String  unfy_mmb_no);
}
 
@Mapper
public interface MsSqlDao{
       public void insertMsSqlTest(HashMap<String,Object> map);
       public List<HashMap<String, Object>>selectMsSqlTest(String unfy_mmb_no);
}
 
   Impl
@Repository
public class OracleDaoImpl implements OracleDao {
       
       @Autowired
       @Qualifier("sqlSessionTemplate")
       private SqlSession sqlSession;
       
       @Override
       public List<HashMap<String, Object>> selectOracleTest(String unfy_mmb_no)  {
             return sqlSession.selectList("oracleMapper.selectOracleTestQuery",  unfy_mmb_no);
       }
}
 
@Repository
public class MsSqlDaoImpl implements MsSqlDao{
       
       @Autowired
       @Qualifier("msSqlSqlSessionTemplate")
       private SqlSession sqlSession;
       
       @Override
       public void insertMsSqlTest(HashMap<String, Object> map) {
             sqlSession.insert("insertMsSqlTest", map);
       }
}
 
   oracle-mapper.xml
<mapper namespace="oracleMapper">
       <select id="selectOracleTestQuery" parameterType="String"  resultType="java.util.HashMap">
             /* oracle-mapper.xml | selectOracleTestQuery */
             SELECT
                    MMB_NO
                    ,MMB_NM
                    ,MMB_ID
             FROM
                    MMB_INFO
             WHERE
                    MMB_NO = #{mmb_no}
       </select>
</mapper>
 
   msSql-mapper.xml
<mapper namespace="demo.mssql.dao.MsSqlDao">
       <insert id="insertMsSqlTest" parameterType="java.util.HashMap">
             /* mssql-mapper.xml | insertMsSqlTestQuery */
             INSERT INTO TEST_TABLE2
                    (
                           MMB_NO,
                           MMB_NM,
                           MMB_ID
                    )
             VALUES
                    (
                           #{MMB_NO},
                           #{MMB_NM},
                           #{MMB_ID}
                    )
             
       </insert>
</mapper>
 
주의해야 할 점
  • 메인 디비(Oracle)는 mapper.xml 파일의  id와 Impl의 Repository 소스 상에서의 아이디만 같으면 된다. 하지만 서브 디비(MsSql)의 경우에는 mapper.xml 파일의 id, impl의 Repository의 소스 상의 아이디 + 메소드명이 동일해야 한다.
  • msSql-mapper.xml 에서 namespace는 해당 매퍼의 패키지부터 파일명 까지 풀로 적어준다.
 
 
5.추가설정
   MsSql관련해서 방화벽으로 인한 타임아웃 에러가 난다면 몇가지 설정을 해주어야 한다.
  • windows 방화벽에서 사용하려는 포트(기본 1433)의 TCP 인바운드 규칙을 생성해준다.
  • SQL SERVER Configuration Manager (SQL SERVER 구성 관리자)에 들어가 SQL Server 네트워크 구성 -> SQLEXPRESS에 대한 프로토콜 -> TCP/IP  더블클릭을 하면 TCP/IP 속성이 나오는데 아래 이미지와 같이 설정해준다.