1.配置文件中的数据源配置
2.为了方便查询,我将读写分离的代码写在一个包中,如下图
3.我们从上向下看,先看annotation包下的
public @interface Master {
}
public @interface Slave {
}
4.bean 包的内容
public class DBContextHolder {
private static final ThreadLocal<DBTypeEnum> contextHolder = new ThreadLocal<>();
public static void set(DBTypeEnum dbType) {
contextHolder.set(dbType);
}
public static DBTypeEnum get() {
return contextHolder.get();
}
public static void master() {
set(DBTypeEnum.MASTER);
}
public static void slave() {
set(DBTypeEnum.SLAVE);
}
}
@Component
@Primary
public class DynamicDataSource extends AbstractRoutingDataSource {
@Autowired
@Qualifier("masterDataSource")
private DataSource masterDataSource;
@Autowired
@Qualifier("slaveDataSource")
private DataSource slaveDataSource;
@Override
protected Object determineCurrentLookupKey() {
return DBContextHolder.get();
}
@Override
public void afterPropertiesSet() {
Map<Object,Object> map = new HashMap<>();
map.put(DBTypeEnum.SLAVE,slaveDataSource);
map.put(DBTypeEnum.MASTER,masterDataSource);
setTargetDataSources(map);
setDefaultTargetDataSource(masterDataSource);
super.afterPropertiesSet();
}
4.config包内容
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.slave")
public DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}
}
@Configuration
@EnableTransactionManagement
public class MyBatisConfig extends MybatisAutoConfiguration {
@Resource(name = "dynamicDataSource")
private DataSource dynamicDataSource;
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception{
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dynamicDataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean
public PlatformTransactionManager platformTransactionManager() {
return new DataSourceTransactionManager(dynamicDataSource);
}
}
5.enums包内容
public enum DBTypeEnum {
MASTER, SLAVE
}
6.value中的值可以根据自己的需要进行配置
@Aspect
@Component
@Order(-1)//控制加载顺序,使其最先加载
public class DataSourceHandler {
@Pointcut(
value = "!@annotation(com.test.datasource.annotation.Master)"
+ "&& (execution(* com.test.service..*.select*(..))"
+ "|| execution(* com.test.service..*.find*(..))"
+ "|| execution(* com.test.service..*.get*(..))"
+ "|| execution(* com.test.service..*.query*(..)))"
)
private void readPointcut() {
}
@Pointcut(
value = "@annotation(com.test.datasource.annotation.Master)"
+ "|| execution(* com.test.service..*.insert*(..))"
+ "|| execution(* ccom.test.service..*.add*(..))"
+ "|| execution(* com.test.service..*.save*(..))"
+ "|| execution(* com.test.service..*.update*(..))"
+ "|| execution(* com.test.service..*.delete*(..))"
+ "|| execution(* com.test.service..*.remove*(..))"
)
private void writePointcut() {
}
@Before("readPointcut()")
private void read() {
//从数据源
DBContextHolder.slave();
}
@Before("writePointcut()")
private void write() {
//主数据源
DBContextHolder.master();
}
}
7.根据第6不的配置,在service包下,如果方法名以select、find、get、query开头并且在方法上没有加@Master注解,在访问数据库的时候会使用从数据源;如果方法名以insert、add、save、update、delete、remove开头或者方法上加了@Master注解,在访问数据库的时候会使用主数据源
8.该方法是通过互联网查询后自己总结的方法,如果有侵权请联系删除