springboot实现读写分离

配置:

application.yml

spring:
  datasource:
    ####写数据源
    update:
      jdbc-url: jdbc:mysql://192.168.100.150:8066/test
      driver-class-name: com.mysql.jdbc.Driver
      username: root
      password: root
    ###读数据源
    select:
      jdbc-url: jdbc:mysql://192.168.100.150:8066/test
      driver-class-name: com.mysql.jdbc.Driver
      username: user
      password: user
    type: com.alibaba.druid.pool.DruidDataSource

 

配置读写数据源:

DataSourceConfig.java

/**
 * 配置读写数据源
 */
@Configuration
public class DataSourceConfig {

	@Bean(name = "selectDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.select")
	public DataSource dataSource1() {
		return DataSourceBuilder.create().build();
	}

	@Bean(name = "updateDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.update")
	public DataSource dataSource2() {
		return DataSourceBuilder.create().build();
	}

}

  

保存本地数据源:

DataSourceContextHolder.java

/**
 * 保存本地多数据源
 */
@Component
@Lazy(false)
public class DataSourceContextHolder {
	private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

	// 设置数据源类型
	public static void setDbType(String dbType) {
		contextHolder.set(dbType);
	}

	public static String getDbType() {
		return contextHolder.get();
	}

	public static void clearDbType() {
		contextHolder.remove();
	}

}

 

配置动态切换数据源类:

DynamicDataSource.java

/**
 * 该类继承自 AbstractRoutingDataSource 类,在访问数据库时会调用该类的 determineCurrentLookupKey() 方法获取数据库实例的 key
 */
@Component
@Primary
public class DynamicDataSource extends AbstractRoutingDataSource {
	private static final Logger logger = LoggerFactory.getLogger(DynamicDataSource.class);
	@Autowired
	@Qualifier("selectDataSource")
	private DataSource selectDataSource;
	@Autowired
	@Qualifier("updateDataSource")
	private DataSource updateDataSource;

	/**
	 * 返回生效的数据源名称
	 */
	@Override
	protected Object determineCurrentLookupKey() {
		logger.info("DataSourceContextHolder:{}", DataSourceContextHolder.getDbType());
		return DataSourceContextHolder.getDbType();
	}
	/**
	 * 配置使用的数据源信息,如果不存在就使用默认的数据源
	 */
	@Override
	public void afterPropertiesSet() {
		Map<Object, Object> map = new HashMap<>();
		map.put("selectDataSource", selectDataSource);
		map.put("updateDataSource", updateDataSource);
		//注册数据源
		setTargetDataSources(map);
		setDefaultTargetDataSource(updateDataSource);
		super.afterPropertiesSet();
	}
}

  

AOP配置:

DataSourceAOP.java

@Aspect
@Component
@Lazy(false)
// Order设定AOP执行顺序 使之在数据库事务上先执行
@Order(0)
public class DataSourceAOP {
    private static final Logger logger = LoggerFactory.getLogger(DataSourceAOP.class);
    //横切点
    @Before("execution(* com.yk.service.*.*(..))")
    public void process(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        if (methodName.startsWith("get") || methodName.startsWith("count") || methodName.startsWith("find")
                || methodName.startsWith("list") || methodName.startsWith("select") || methodName.startsWith("check")) {
            DataSourceContextHolder.setDbType("selectDataSource");
            logger.info("使用的是读数据源:selectDataSource");
        } else {
            DataSourceContextHolder.setDbType("updateDataSource");
            logger.info("使用的是写数据源:updateDataSource");
        }
    }
}

  

 

application.ymlspring: datasource:####写数据源 update: jdbc-url:jdbc:mysql://192.168.100.150:8066/test driver-class-name:com.mysql.jdbc.Driver username:root password:root###读数据源 select: jdbc-url:jdbc:mysql://192.168.100.150:8066/test driver-class-name:com.mysql.jdbc.Driver username:user password:user type:com.alibaba.druid.pool.DruidDataSource

原文地址:https://www.cnblogs.com/JAYIT/p/13519234.html