最近在做项目时遇到了一个需求,一个SpringBoot项目中需要连接多个数据库(分表分库)当把数据库分出来后至少有五个数据库,但是以前做的项目很少有用到多个数据库的情况,经过一些资料的查找终于找到了一些方法。
方法一:基于Mybatis或MybatisPlus实现
首先要用Mybatis或MybatisPlus实现最重要的是Dynamic-DataSource,它简化了在 Spring Boot 应用中配置和使用多数据源的流程。它基于 Spring 的 AbstractRoutingDataSource
实现了多数据源的动态切换,能够根据特定的标识选择不同的数据源进行连接。
所以方法如下:
1.在application.yml文件中配置好自己的数据源
datasource:
dynamic:
primary: user # 设置为已存在的数据源名称
strict: false # 设置为 true 后,找不到对应数据源时会抛出异常,为 false 时,找不到对应数据源时会使用默认数据源
datasource:
admin:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/leadnews_admin
username: root
password: 123456
user:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/leadnews_user
username: root
password: 123456
article:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/leadnews_article
username: root
password: 123456
最重要的是要加上
dynamic:
primary: user # 设置为已存在的数据源名称
strict: false
primary: 这个属性用来指定默认的数据源名称。在多个数据源配置中,可以指定其中一个作为默认数据源,当无法确定具体要使用的数据源时,会默认使用这个名称对应的数据源。
strict: 这个属性是一个布尔值,用来指定是否启用严格模式。默认情况下,严格模式是开启的(即 strict: true)。在严格模式下,如果无法找到指定的默认数据源(通过 primary 属性指定的),系统会抛出异常,表示无法找到默认数据源。当设置为 false 时,如果找不到默认数据源,系统将会以某种默认的行为来处理,可能是使用一个默认的数据源或者采取其他的处理方式。
2.在SpringBoot项目中导入dynamic-datasource-spring-boot-starter和mybatisplus依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
3.在dynamic-datasource-spring-boot-starter有一个注解叫@DS
用于指定在特定方法或类上使用的数据源标识,从而实现动态切换数据源的功能。这个注解可以使用在不同的地方,列如:
3.1在方法上使用
@DS("user")
public void getUserData() {
// 从名为"user"的数据源中获取数据
}
3.2在Service层使用
@DS("user")
@Service
public class UserService {
public void getUserData() {
// 这里也会使用名为"user"的数据源
}
}
3.3在Mapper层使用
@Mapper
@DS("user")
public interface UserMapper extends BaseMapper<ApUser> {
}
4.使用效果
前提需要在实体类中指定表名 (MyBatisPlus使用方法)
4.1UserMapper使用了在yml配置文件中已user为名的数据库
@Mapper
@DS("user")
public interface UserMapper extends BaseMapper<ApUser> {
}
4.2ArticleMapper使用了在yml配置文件中已article为名数据库(同理也要指定表名)
@DS("article")
@Mapper
public interface ArticleMapper extends BaseMapper<ApArticle> {
}
为了方便直接在controller层测试
结果:
这样就能实现动态切换数据源了
二.基于写XXXDataSourceConfig配置类实现
以Admin数据库为例:
package com.zhb.config.dataSource;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.zhb.methods.admin.mapper", sqlSessionTemplateRef = "adminSqlSessionTemplate")
public class AdminDataSourceConfig {
@Bean(name = "admin")
@ConfigurationProperties(prefix = "datasource.admin")
public DataSource adminDataSource() {
return new DruidDataSource();
}
@Bean(name = "adminSqlSessionFactory")
public SqlSessionFactory adminSqlSessionFactory() throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(adminDataSource());
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/admin/*.xml"));
return bean.getObject();
}
@Bean(name = "adminSqlSessionTemplate")
public SqlSessionTemplate adminSqlSessionTemplate() throws Exception {
return new SqlSessionTemplate(adminSqlSessionFactory());
}
}
如果有多个数据源就写几个配置类
需要注意的是
所以每一个数据库的操作方法就放在一个mapper.xml文件中,这样就能找到他们对应的数据库了。