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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM