一、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-tw/n/334644.html