一、Springboot配置雙數據源
在Spring Boot應用程序中配置多個數據源是很常見的需求。由於Spring Boot的自動配置機制,使得我們可以輕鬆優雅的實現多數據源配置和切換。 若要配置雙數據源,則需要使用Spring Boot的自動裝配機制執行以下操作:
1. 確保我們的應用程序中依賴了Spring Boot的MyBatis Starter,這將為MyBatis集成提供必要的依賴關係和自動配置。在pom.xml文件中添加以下依賴:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency>
2. 在application.properties中配置雙數據源的各項信息:
# primary datasource spring.datasource.primary.url=jdbc:mysql://localhost:3306/primary_db spring.datasource.primary.username=dbuser spring.datasource.primary.password=dbpassword spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver # secondary datasource spring.datasource.secondary.url=jdbc:mysql://localhost:3306/secondary_db spring.datasource.secondary.username=dbuser spring.datasource.secondary.password=dbpassword spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
3. 創建主數據源和次數據源的數據源類:
@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.primary", sqlSessionTemplateRef = "primarySqlSessionTemplate")
public class PrimaryDataSourceConfig {
@Autowired
private DataSourceProperties dataSourceProperties;
@Bean(name = "primaryDataSource")
@Primary
public DataSource primaryDataSource() {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
@Bean(name = "primarySqlSessionFactory")
@Primary
public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource primaryDataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(primaryDataSource);
return sessionFactory.getObject();
}
@Bean(name = "primaryTransactionManager")
@Primary
public DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource primaryDataSource) {
return new DataSourceTransactionManager(primaryDataSource);
}
@Bean(name = "primarySqlSessionTemplate")
@Primary
public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("primarySqlSessionFactory") SqlSessionFactory primarySqlSessionFactory) {
return new SqlSessionTemplate(primarySqlSessionFactory);
}
}
@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.secondary", sqlSessionTemplateRef = "secondarySqlSessionTemplate")
public class SecondaryDataSourceConfig {
@Autowired
private DataSourceProperties dataSourceProperties;
@Bean(name = "secondaryDataSource")
public DataSource secondaryDataSource() {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
@Bean(name = "secondarySqlSessionFactory")
public SqlSessionFactory secondarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(secondaryDataSource);
return sessionFactory.getObject();
}
@Bean(name = "secondaryTransactionManager")
public DataSourceTransactionManager secondaryTransactionManager(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
return new DataSourceTransactionManager(secondaryDataSource);
}
@Bean(name = "secondarySqlSessionTemplate")
public SqlSessionTemplate secondarySqlSessionTemplate(@Qualifier("secondarySqlSessionFactory") SqlSessionFactory secondarySqlSessionFactory) {
return new SqlSessionTemplate(secondarySqlSessionFactory);
}
}
4. 創建controller並在其中注入主數據源的mapper和次數據源的mapper
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private PrimaryUserMapper primaryUserMapper;
@Autowired
private SecondaryUserMapper secondaryUserMapper;
@GetMapping("/primary/list")
public List getPrimaryUsers() {
return primaryUserMapper.getAll();
}
@GetMapping("/secondary/list")
public List getSecondaryUsers() {
return secondaryUserMapper.getAll();
}
}
5. 啟動應用並測試多數據源的配置是否正確。
二、Mybatis多數據源配置SpringBoot
當使用Mybatis作為數據持久層框架時,需要按以下步驟在SpringBoot中配置多數據源:
1. 在pom.xml文件中添加以下依賴關係:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency>
2. 在application.properties或application.yml文件中配置數據源信息:
# primary datasource spring.datasource.primary.url=jdbc:mysql://localhost:3306/primary_db spring.datasource.primary.username=dbuser spring.datasource.primary.password=dbpassword spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver # secondary datasource spring.datasource.secondary.url=jdbc:mysql://localhost:3306/secondary_db spring.datasource.secondary.username=dbuser spring.datasource.secondary.password=dbpassword spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
3. 創建數據源類、SqlSessionFactory、SqlSessionTemplate和TransactionManager:
@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.primary", sqlSessionTemplateRef = "primarySqlSessionTemplate")
public class PrimaryDataSourceConfig {
@Autowired
private DataSource primaryDataSource;
@Bean(name = "primarySqlSessionFactory")
@Primary
public SqlSessionFactory primarySqlSessionFactory() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(primaryDataSource);
return sessionFactory.getObject();
}
@Bean(name = "primaryTransactionManager")
@Primary
public DataSourceTransactionManager primaryTransactionManager() {
return new DataSourceTransactionManager(primaryDataSource);
}
@Bean(name = "primarySqlSessionTemplate")
@Primary
public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("primarySqlSessionFactory") SqlSessionFactory primarySqlSessionFactory) {
return new SqlSessionTemplate(primarySqlSessionFactory);
}
}
@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.secondary", sqlSessionTemplateRef = "secondarySqlSessionTemplate")
public class SecondaryDataSourceConfig {
@Autowired
private DataSource secondaryDataSource;
@Bean(name = "secondarySqlSessionFactory")
public SqlSessionFactory secondarySqlSessionFactory() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(secondaryDataSource);
return sessionFactory.getObject();
}
@Bean(name = "secondaryTransactionManager")
public DataSourceTransactionManager secondaryTransactionManager() {
return new DataSourceTransactionManager(secondaryDataSource);
}
@Bean(name = "secondarySqlSessionTemplate")
public SqlSessionTemplate secondarySqlSessionTemplate(@Qualifier("secondarySqlSessionFactory") SqlSessionFactory secondarySqlSessionFactory) {
return new SqlSessionTemplate(secondarySqlSessionFactory);
}
}
4. 創建主數據源mapper和次數據源mapper,並在其中分別使用@Qualifier註解注入對應的數據源的SqlSessionTemplate。
5. 對於需要使用次數據源的Service或Dao類中,使用@Qualifier註解指定對應的SqlSessionTemplate。
6. 啟動應用並測試多數據源的配置是否正確。
三、Springboot動態配置數據源
無論是配置雙數據源還是多數據源,都需要在application.properties或application.yml文件中預先配置好數據源信息。然而,在生產環境中,可能需要根據用戶的訪問請求,動態選擇不同的數據源。因此,需要在運行時動態配置數據源,具體步驟如下:
1. 在pom.xml文件中添加以下依賴關係:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
2. 配置與數據源相關的bean:
@Configuration
public class DynamicDataSourceConfig {
@Autowired
private DataSourceProperties dataSourceProperties;
private final Map dataSources = new ConcurrentHashMap();
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
dataSource.setUrl(dataSourceProperties.getUrl());
dataSource.setUsername(dataSourceProperties.getUsername());
dataSource.setPassword(dataSourceProperties.getPassword());
return new DynamicRoutingDataSource(dataSource);
}
@Bean
public DataSourceTransactionManager dataSourceTransactionManager() {
return new DataSourceTransactionManager(dataSource());
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
return sessionFactory.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate() throws Exception {
return new SqlSessionTemplate(sqlSessionFactory());
}
}
3. 創建動態數據源類DynamicRoutingDataSource和動態數據源上下文ThreadLocal:
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
public DynamicRoutingDataSource(DataSource defaultTargetDataSource) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
}
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getDataSourceKey();
}
}
public class DynamicDataSourceContextHolder {
private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal();
public static void setDataSourceKey(String key) {
CONTEXT_HOLDER.set(key);
}
public static String getDataSourceKey() {
return CONTEXT_HOLDER.get();
}
public static void clearDataSourceKey() {
CONTEXT_HOLDER.remove();
}
}
4. 創建DynamicDataSourceAspect類,在函數執行前獲取數據源的key並設置到DynamicDataSourceContextHolder中,函數執行完畢後清除DynamicDataSourceContextHolder。
@Aspect
@Component
public class DynamicDataSourceAspect {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Before("execution(* com.example.demo.service.*.*(..))")
public void before(JoinPoint point) {
String dataSourceKey = point.getSignature().getName().contains("primary") ? "primary" : "secondary";
DynamicDataSourceContextHolder.setDataSourceKey(dataSourceKey);
logger.info(String.format("設置數據源為 %s", dataSourceKey));
}
@After("execution(* com.example.demo.service.*.*(..))")
public void after(JoinPoint point) {
DynamicDataSourceContextHolder.clearDataSourceKey();
logger.info("清除數據源");
}
}
5. 在需要多數據源的Service實現類中,添加以下注解,這將激活DynamicDataSourceAspect,從而動態設置數據源:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private PrimaryUserMapper primaryUserMapper;
@Autowired
private SecondaryUserMapper secondaryUserMapper;
@Primary
@DataSource(key = "primary")
public List getAllPrimaryUsers() {
return primaryUserMapper.getAll();
}
@DataSource(key = "secondary")
public List getAllSecondaryUsers() {
return secondaryUserMapper.getAll();
}
// ...
}
四、Springboot配置多數據源Druid
如果需要使用連接池,可以選擇使用阿里巴巴的Druid。具體步驟如下:
1. 在pom.xml文件中添加以下依賴關係:
<dependency>
<groupId>com.alibaba
<artifactId>druid-spring-boot-starter
<version>1.2.5
</dependency>
2. 在application.properties或application.yml文件中配置DruidDataSource的各項信息:
# primary datasource
spring.datasource.primary.url=jdbc:mysql://localhost:3306/primary_db?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
spring.datasource.primary.username=dbuser
spring.datasource.primary.password=dbpassword
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.primary.type=com.alibaba.druid.pool.DruidDataSource
# druid specific config
spring.datasource.primary.initial-size=0
spring.datasource.primary.min-idle=0
spring.datasource.primary.max-active=20
spring.datasource.primary.max-wait=-1
spring.datasource.primary.time-between-eviction-runs-millis=60000
spring.datasource.primary.min-evictable-idle-time-millis=300000
spring.datasource.primary.validation-query=SELECT 1 FROM DUAL
spring.datasource.primary.test-while-idle=true
spring.datasource.primary.test-on-borrow=false
spring.datasource.primary.test-on-return=false
spring.datasource.primary.pool-prepared-statements=true
spring.datasource.primary.max-pool-prepared-statement-per-connection-size=20
spring.datasource.primary.filters=stat,wall,log4j
spring.datasource.primary.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000# secondary datasource
spring.datasource.secondary.url=jdbc:mysql://localhost:3306/secondary_db?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
spring.datasource.secondary.username=dbuser
spring.datasource.secondary.password=dbpassword
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.secondary.type=com.alibaba.druid.pool.DruidDataSource
# druid specific config
spring.datasource.secondary.initial-size=0
spring.datasource.secondary.min-idle=0
spring.datasource.secondary.max-active=20
spring.datasource.secondary.max-wait=-1
spring.datasource.secondary.time-between-eviction-runs-millis=600原創文章,作者:QYCUH,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/334644.html
微信掃一掃
支付寶掃一掃