基於mycat實現項目讀寫分離
主要的原理步驟是,springboot項目整合mycat後,通過aop攔截後切換數據源,然後在通過mycat路由到相應的數據庫中實現讀寫分離,如下是一些核心文件及配置。
項目地址:springboot-mysqlcopy
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.23</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
application.yml
server:
port: 8282
spring:
datasource:
###可讀數據源
select:
jdbc-url: jdbc:mysql://192.168.78.231:8066/TESTDB
driver-class-name: com.mysql.jdbc.Driver
username: user
password: user
####可寫數據源
update:
jdbc-url: jdbc:mysql://192.168.78.231:8066/TESTDB
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
DataSourceContextHolder
@Component
@Lazy(false)
public class DataSourceContextHolder {
// 採用ThreadLocal 保存本地多數據源
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();
}
}
DataSourceConfig
@Configuration
public class DataSourceConfig {
// 創建可讀數據源
@Bean(name = "selectDataSource")
@ConfigurationProperties(prefix = "spring.datasource.select") // application.properteis中對應屬性的前綴
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
}
// 創建可寫數據源
@Bean(name = "updateDataSource")
@ConfigurationProperties(prefix = "spring.datasource.update") // application.properteis中對應屬性的前綴
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
}
DynamicDataSource
//在Spring 2.0.1中引入了AbstractRoutingDataSource, 該類充當了DataSource的路由中介, 能有在運行時, 根據某種key值來動態切換到真正的DataSource上。
@Component
@Primary
public class DynamicDataSource extends AbstractRoutingDataSource {
@Autowired
@Qualifier("selectDataSource")
private DataSource selectDataSource;
@Autowired
@Qualifier("updateDataSource")
private DataSource updateDataSource;
/**
* 這個是主要的方法,返回的是生效的數據源名稱
*/
@Override
protected Object determineCurrentLookupKey() {
System.out.println("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();
}
}
SwitchDataSourceAOP
@Aspect
@Component
@Lazy(false)
@Order(0) // Order設定AOP執行順序 使之在數據庫事務上先執行
public class SwitchDataSourceAOP {
// 這裏切到你的方法目錄
@Before("execution(* com.mayikt.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");
} else {
// 切換dataSource
DataSourceContextHolder.setDbType("updateDataSource");
}
}
}
以上就是項目整合mycat後實現對數據庫的讀寫分離,自我總結學習並分享給大家!
項目地址:springboot-mysqlcopy
學習參考:螞蟻課堂