目录
引言
要想实现数据库读写分离的功能,最常用的方法就是将数据库设置好主从复制,在程序中对一个数据库只进行读取操作,对另一个数据库只进行增删改等写的操作。
版本
本文基于Spring4.2和mybatis-plus3.5的
准备
首先需要先设置好Spring整合Mybatis Plus单一数据源时的情况。
注意jar包的版本是否匹配。
我的单数据源时mybatis-plus的整合文件(命名为spring-mybatis.xml)设置如下
<?xml version="1.0" encoding="UTF-8"?>
<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"
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">
<!-- spring整合MyBatis :将MyBatis核心配制相关配制放到 Spring的配制文件 -->
<!-- 关闭日志 -->
<bean id="configuration" class="com.baomidou.mybatisplus.core.MybatisConfiguration" >
<property name="logImpl" value="org.apache.ibatis.logging.nologging.NoLoggingImpl" />
</bean>
<!-- 导入db.properties文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 整合数据源 :DBCP连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- SqlSesessionFactory 工厂对象 -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 加载xxMapper.xml -->
<!--
<property name="mapperLocations">
<array>
<value>classpath:mapper/*Mapper.xml</value>
</array>
</property>
-->
<!-- 批量的别名配制 -->
<property name="typeAliasesPackage" value="com.xxx.entity"/>
<property name="configuration" ref="configuration" />
</bean>
<!-- 整合映射文件 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xxx.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
</beans>
其中自定义的包名用“xxx”屏蔽了。
db.db.properties文件中内容如下
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/xxx?serverTimezone=UTC
jdbc.username=root
jdbc.password=xxx
能够使用单数据源操作数据库后,进行多数据源的整合。
开始
1.代码中数据库切换工具类:
DataSourceContextHolder
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setDbType(String dbType) {
contextHolder.set(dbType);
}
public static String getDbType() {
return ((String) contextHolder.get());
}
public static void clearDbType() {
contextHolder.remove();
}
}
2.数据源切换工具类。用于切换数据库
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDbType();
}
}
3.静态常量存储数据源名
public class DataSourceType {
public static final String DATASOURCE_1= "dataSource_1";
public static final String DATASOURCE_2= "dataSource_2";
}
4.修改配置文件
将整合mybatis-plus的文件修改为:
<?xml version="1.0" encoding="UTF-8"?>
<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"
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">
<!-- spring整合MyBatis :将MyBatis核心配制相关配制放到 Spring的配制文件 -->
<!-- 关闭日志 -->
<bean id="configuration" class="com.baomidou.mybatisplus.core.MybatisConfiguration" >
<property name="logImpl" value="org.apache.ibatis.logging.nologging.NoLoggingImpl" />
</bean>
<!-- 导入db.properties文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 整合数据源 :DBCP连接池 -->
<bean id="dataSource_1" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 整合数据源 :DBCP连接池 -->
<bean id="dataSource_2" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName2}" />
<property name="url" value="${jdbc.url2}" />
<property name="username" value="${jdbc.username2}" />
<property name="password" value="${jdbc.password2}" />
</bean>
<!-- 动态配置数据源 -->
<bean id ="dataSource" class= "com.xxx.DynamicDataSource" >
<property name ="targetDataSources">
<map key-type ="java.lang.String">
<entry value-ref ="dataSource_1" key= "dataSource_1"></entry >
<entry value-ref ="dataSource_2" key= "dataSource_2"></entry >
</map >
</property >
<property name ="defaultTargetDataSource" ref= "dataSource_1"></property > <!-- 默认使用ds1的数据源 -->
</bean >
<!-- SqlSesessionFactory 工厂对象 -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 加载xxMapper.xml -->
<!--
<property name="mapperLocations">
<array>
<value>classpath:mapper/*Mapper.xml</value>
</array>
</property>
-->
<!-- 批量的别名配制 -->
<property name="typeAliasesPackage" value="com.xxx.entity"/>
<property name="configuration" ref="configuration" />
</bean>
<!-- 整合映射文件 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xxx.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
</beans>
注意对应关系:数据源的id放入动态数据源的map的value-ref中。
5.切换数据源
在调用数据库的操作之前调用"DataSourceContextHolder.setDbType(DataSourceType.数据源类型)"即可
@Service
public class ServiceImpl implements Service {
@Autowired
Mapper Mapper;
@Override
public List<String> test() {
//切换数据库
DataSourceContextHolder.setDbType(DataSourceType.DATASOURCE_2);
List<String> resList=mapper.selectList(null);
return resList;
}
}
出现异常:
nested exception is java.lang.NoSuchMethodError: org.springframework.util.CollectionUtils.newHashMap(I)Ljava/util/HashMap;
原因:我的spring-jdbc的版本原先使用的是5.0版本的,导致版本异常。将spring-jdbc的jar包换成4.2版本的就行了。
参考: