MyBatis 멀티 데이터 소스 구성 자세히 보기(읽기/쓰기 분리)

MyBatis 멀티 데이터 소스 구성(읽기/쓰기 분리)
먼저 본고의 배치가 사용하는 가장 직접적인 방식은 실제로 사용하면 매우 번거로울 수 있음을 설명한다.
실제 응용에서 여러 가지 결합된 상황이 존재할 수 있으므로 본고의 의미를 이해할 수 있고 융통성이 없는 사용을 하지 마라.
다중 데이터 원본의 가능성
1. 주종
일반적으로 MySQL의 주된 다중 종속 상황입니다. 본고의 예는 주종의 상황입니다. 그러나 두 개의 데이터 원본만 있기 때문에 직접 설정을 사용하는 것은 그리 번거롭지 않지만 후속 확장에 불리합니다. 주로 하나의 예로 설명하기 때문에 실제 조작은 신중하게 고려해 주십시오.
2. 분고
업무의 독립성이 강하고 데이터의 양이 많을 때 병발을 향상시키기 위해 표에 대해 라이브러리를 나눌 수 있다. 라이브러리를 나눌 때 모든 데이터베이스는 하나의 데이터 원본을 설정해야 한다.
이런 상황은 본고를 참고할 수 있으나 모든 데이터베이스에 대응하는 Mapper는 서로 다른 패키지 아래에서 쉽게 구분하고 설정해야 한다는 것을 주의해야 한다.
또한 라이브러리를 나누는 경우에도 주종적인 상황이 존재한다. 만약에 데이터베이스가 라이브러리에서 너무 많으면 위에서 제공한 방법을 참고하거나 다른 방법을 찾아 해결한다.
매퍼 패키지
라이브러리를 나누는 경우, 서로 다른 데이터베이스의 Mapper는 반드시 서로 다른 가방 아래에 놓여 있다.
주종의 경우 같은 Mapper가 읽기와 쓰기가 동시에 존재하기 때문에 두 개를 만드는 것은 적합하지 않습니다. 같은 것을 사용하면 됩니다.그러나 이 경우 스프링이 마퍼에게 자동으로 생성되는 이름은 같고 유형도 같으므로 마퍼 인터페이스에 직접 주입할 수 없다는 점에 주의해야 한다.SqlSession을 통해 해결해야 합니다.
Spring 기본 구성
applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop.xsd">

  <context:component-scan base-package="com.isea533.mybatis.service"/>
  <context:property-placeholder location="classpath:config.properties"/>
  <aop:aspectj-autoproxy/>

  <import resource="spring-datasource-master.xml"/>
  <import resource="spring-datasource-slave.xml"/>
</beans>

이 파일은 주로spring-datasource-master를 도입했습니다.xml과spring-datasource-slave.xml.
spring-datasource-master.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop.xsd">

  <bean id="dataSourceMaster" class="com.alibaba.druid.pool.DruidDataSource" 
    init-method="init" destroy-method="close">
    <property name="driverClassName" value="${master.jdbc.driverClass}"/>
    <property name="url" value="${master.jdbc.url}"/>
    <property name="username" value="${master.jdbc.user}"/>
    <property name="password" value="${master.jdbc.password}"/>

    <property name="filters" value="stat"/>

    <property name="maxActive" value="20"/>
    <property name="initialSize" value="1"/>
    <property name="maxWait" value="60000"/>
    <property name="minIdle" value="1"/>

    <property name="timeBetweenEvictionRunsMillis" value="60000"/>
    <property name="minEvictableIdleTimeMillis" value="300000"/>

    <property name="validationQuery" value="SELECT 'x'"/>
    <property name="testWhileIdle" value="true"/>
    <property name="testOnBorrow" value="false"/>
    <property name="testOnReturn" value="false"/>
  </bean>

  <bean id="sqlSessionFactory1" 
    class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSourceMaster"/>
    <property name="mapperLocations">
      <array>
        <value>classpath:mapper/*.xml</value>
      </array>
    </property>
  </bean>

  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.isea533.mybatis.mapper"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1"/>
  </bean>

  <bean id="sqlSessionMaster" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
    <constructor-arg index="0" ref="sqlSessionFactory1"/>
  </bean>

  <aop:config>
    <aop:pointcut id="appService" 
      expression="execution(* com.isea533.mybatis.service..*Service*.*(..))"/>
    <aop:advisor advice-ref="txAdvice1" pointcut-ref="appService"/>
  </aop:config>

  <tx:advice id="txAdvice1" transaction-manager="transactionManager1">
    <tx:attributes>
      <tx:method name="select*" read-only="true"/>
      <tx:method name="find*" read-only="true"/>
      <tx:method name="get*" read-only="true"/>
      <tx:method name="*"/>
    </tx:attributes>
  </tx:advice>

  <bean id="transactionManager1" 
   class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSourceMaster"/>
  </bean>
</beans>

spring-datasource-slave.xml
마스터와 차이가 크지 않습니다. 주로 id 이름과 데이터 원본 설정이 다릅니다.

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">

  <bean id="dataSourceSlave" class="com.alibaba.druid.pool.DruidDataSource" 
    init-method="init" destroy-method="close">
    <property name="driverClassName" value="${slave.jdbc.driverClass}"/>
    <property name="url" value="${slave.jdbc.url}"/>
    <property name="username" value="${slave.jdbc.user}"/>
    <property name="password" value="${slave.jdbc.password}"/>

    <property name="filters" value="stat"/>

    <property name="maxActive" value="20"/>
    <property name="initialSize" value="1"/>
    <property name="maxWait" value="60000"/>
    <property name="minIdle" value="1"/>

    <property name="timeBetweenEvictionRunsMillis" value="60000"/>
    <property name="minEvictableIdleTimeMillis" value="300000"/>

    <property name="validationQuery" value="SELECT 'x'"/>
    <property name="testWhileIdle" value="true"/>
    <property name="testOnBorrow" value="false"/>
    <property name="testOnReturn" value="false"/>
  </bean>

  <bean id="sqlSessionFactory2" 
    class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSourceSlave"/>
    <property name="mapperLocations">
      <array>
        <value>classpath:mapper/*.xml</value>
      </array>
    </property>
  </bean>

  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.isea533.mybatis.mapper"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2"/>
  </bean>

  <bean id="sqlSessionSlave" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
    <constructor-arg index="0" ref="sqlSessionFactory2"/>
  </bean>


  <aop:config>
    <aop:pointcut id="appService" 
      expression="execution(* com.isea533.mybatis.service..*Service*.*(..))"/>
    <aop:advisor advice-ref="txAdvice2" pointcut-ref="appService"/>
  </aop:config>

  <tx:advice id="txAdvice2" transaction-manager="transactionManager2">
    <tx:attributes>
      <tx:method name="*" read-only="true"/>
    </tx:attributes>
  </tx:advice>

  <bean id="transactionManager2" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSourceSlave"/>
  </bean>
</beans>

는 읽기 전용입니다.라이브러리가 아닌 경우 기본 라이브러리별로 구성할 수 있습니다.
다음 코드에서:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage" value="com.isea533.mybatis.mapper"/>
  <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2"/>
</bean>
sqlSessionFactoryBeanName을 통해 다른 sqlSessionFactory를 지정해야 합니다.
config.properties

#   - Master
master.jdbc.driverClass = com.mysql.jdbc.Driver
master.jdbc.url = jdbc:mysql://192.168.1.11:3306/test
master.jdbc.user = root
master.jdbc.password = jj

# - Slave
slave.jdbc.driverClass = com.mysql.jdbc.Driver
slave.jdbc.url = jdbc:mysql://192.168.1.22:3306/test
slave.jdbc.user = root
slave.jdbc.password = jj
매퍼 사용
여기는 주종의 상황에 맞추어 설정된 것입니다. 두 개의 설정이 스캐닝된 Mapper는 똑같기 때문에 직접 주입할 수 없습니다. 아래의 번거로운 방식을 통해 주입해야 합니다.

@Service
public class DemoService {
  private CountryMapper writeMapper;
  private CountryMapper readMapper;

  @Resource(name = "sqlSessionMaster")
  public void setWriteMapper(SqlSession sqlSession) {
    this.writeMapper = sqlSession.getMapper(CountryMapper.class);
  }
  @Resource(name = "sqlSessionSlave")
  public void setReadMapper(SqlSession sqlSession) {
    this.readMapper = sqlSession.getMapper(CountryMapper.class);
  }

  public int save(Country country){
    return writeMapper.insert(country);
  }

  public List<Country> selectPage(int pageNum, int pageSize) {
    PageHelper.startPage(pageNum, pageSize);
    return readMapper.select(null);
  }
}
sqlSession은name를 통해 구분할 수 있기 때문에, 여기에서 sqlSession에서 Mapper를 가져옵니다.
또한 같은 업무에서 쓰기를 고려할 때, 같은 write Mapper를 사용해야 읽을 때 업무의 최신 데이터를 얻을 수 있습니다.
이상은 주종의 경우입니다.
라이브러리의 경우, 서로 다른 마퍼가 서로 다른 가방 아래에 있기 때문에 @Resource 또는 @Autowired를 사용하여 마퍼를 주입할 수 있으며, sqlSession을 통해 얻을 필요가 없습니다.
이 글은 단지 다중 데이터 원본의 참고일 뿐이므로 실제 응용할 때 자신의 상황에 따라 고려해 주십시오.
다음에 저는 여가 시간을 이용하여 본고와 상기 두 개의 관련 링크를 바탕으로 MySql 다중 데이터 원본을 대상으로 데이터 원본을 자동으로 전환할 수 있는 플러그인을 개발하려고 합니다. 저는 이 분야의 실제 응용에 익숙하지 않기 때문에 여러분의 해결 방안을 공유하는 메시지를 남겨 주십시오. 이런 것에 대해 많이 알면 알수록 일반적인 데이터 원본 전환 플러그인을 개발할 수 있습니다.
이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.

좋은 웹페이지 즐겨찾기