1.概要
读写分离分为master、slave两台MySQL服务器
在appcation.yml配置多数据源
为多数据源配置读写路由
在AOP中根据方法名或者@Master、@Slave来选择连接不同的数据库
2.代码
application.yml
datasource:
matser:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/spring_boot_mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: **********
slave:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/spring_boot_mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: **********
DBTypeEnum.java
package com.ctgu.springstart.db;
public enum DBTypeEnum {
MASTER, SLAVE;
}
DBContextHolder.java
package com.ctgu.springstart.db;
import java.util.concurrent.atomic.AtomicInteger;
public class DBContextHolder {
private static final ThreadLocal contextHolder = new ThreadLocal<>();
private static final AtomicInteger counter = new AtomicInteger(-1);
public static void set(DBTypeEnum dbType){
contextHolder.set(dbType);
}
public static DBTypeEnum get() {
return contextHolder.get();
}
public static void master() {
set(DBTypeEnum.MASTER);
System.out.println("切换到master");
}
public static void slave() {
// 轮询
// int index = counter.getAndIncrement() % 2;
// if (counter.get() > 9999) {
// counter.set(-1);
// }
// if (index == 0) {
// set(DBTypeEnum.SLAVE);
// System.out.println("切换到slave1");
// }else {
// set(DBTypeEnum.SLAVE2);
// System.out.println("切换到slave2");
// }
set(DBTypeEnum.SLAVE);
System.out.println("切换到slave");
}
}
MyRoutingDataSource.java
package com.ctgu.springstart.db;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.lang.Nullable;
public class MyRoutingDataSource extends AbstractRoutingDataSource {
@Nullable
@Override
protected Object determineCurrentLookupKey() {
return DBContextHolder.get();
}
}
MyBatisConfig.java
package com.ctgu.springstart.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.annotation.Resource;
import javax.sql.DataSource;
@EnableTransactionManagement
@Configuration
public class MyBatisConfig {
@Resource(name = "myRoutingDataSource")
private DataSource myRoutingDataSource;
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(myRoutingDataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean
public PlatformTransactionManager platformTransactionManager() {
return new DataSourceTransactionManager(myRoutingDataSource);
}
}
未完,这不是注解方式,有空会改进、改进