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 다중 데이터 원본을 대상으로 데이터 원본을 자동으로 전환할 수 있는 플러그인을 개발하려고 합니다. 저는 이 분야의 실제 응용에 익숙하지 않기 때문에 여러분의 해결 방안을 공유하는 메시지를 남겨 주십시오. 이런 것에 대해 많이 알면 알수록 일반적인 데이터 원본 전환 플러그인을 개발할 수 있습니다.
이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
MySQL/마이바티스 | 동적 쿼리 사용A라는 서비스에 해당하는 테이블을 조인하고 조회하는 데 사용됩니다. 나중에 공통화를 위해 B 및 C 서비스도 추가됩니다. A, B, C 서비스는 모두 단일 쿼리에서 작동할 수 있도록 공통화되어야 합니다. 테이블에 각...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.