一个SpringBoot项目在某些情境下需要配置多个数据源(数据库),我是在一个单体应用中,使用领域驱动的思想设计的时候所遇到的问题。由于初代版本仅跑在单个服务器上,无法用微服务框架,故仅能将数据库分成三个并与同一个springboot项目连接。踩了不少雷总结出的一些经验。
请注意:我默认读者会使用IDEA创建SpringBoot项目,并拥有MyBatis的使用经验。
首先声明我所有用到的maven的版本(貌似并不是很重要)
idea 2020.1MySQL 8.0mybatis-spring-boot-starter 2.2.1java SE 1.8SpringBoot 2.6.2Druid 1.1.10 正文开始下面画圈部分是本次配置所需配置的文件
config包内是本次的核心配置类,一个数据源对应一个类(重点)repository包存放着MyBatis所提供的mapper接口类mapper包存放着MyBatis提供的接口类所对应的XML文件yml就是SpringBoot的配置文件提前梳理一下数据源与这几个包文件的对应关系(敲黑板)
一个数据源对应config包的一个类,对应repository包下面的其中一个包,对应mapper包下面的一个包,对应yml文件中配置的一个数据源
有了上面的总述,下面就来一步步的去具体实现
1.首先是yml文件,其中请务必关注三个注释下面的三个不同的数据源的名字,因为下一步是手动获取yml文件的配置,并非自动配置。
spring:
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#homework数据源
homework:
druid:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/spoc_homework?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username: root
password: 123456
initial-size: 5
min-idle: 5
max-active: 50
#course数据源
course:
druid:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/spoc_course?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username: root
password: 123456
initial-size: 5
min-idle: 5
max-active: 50
#user数据源
user:
druid:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/spoc_user?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username: root
password: 123456
initial-size: 5
min-idle: 5
max-active: 50
server:
port: 80
2.再创建config包,这个只要让SpringBoot扫描到就行,并不需要在启动类上特别加注释
以其中两个类DataSourceCourse、DataSourceUser 为例。
/**
* @Author: STY
*@Date:2022/1/27
*@Describe:user数据源配置类
* */
@Configuration
@MapperScan(basePackages = "com.example.spoc.repository.user.mapper", sqlSessionTemplateRef = "userSqlSessionTemplate")
public class DataSourceUser {
@Value("${spring.datasource.user.druid.url}")
private String url;
@Value("${spring.datasource.user.druid.username}")
private String username;
@Value("${spring.datasource.user.druid.password}")
private String password;
@Value("${spring.datasource.user.druid.driverClassName}")
private String driverClassName;
@Bean("userDataSource")
@Primary
public DruidDataSource dataSource()
{
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(this.url);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
System.out.println("user");
return datasource;
}
@Bean("userSqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("userDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/userMapper/*Mapper.xml"));
return sessionFactory.getObject();
}
@Bean("userTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager(@Qualifier("userDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean("userSqlSessionTemplate")
@Primary
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("userSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
/**
1. @Author: STY
*@Date:2022/1/27
*@Describe:Course数据源配置类
2. */
@Configuration
@MapperScan(basePackages = "com.example.spoc.repository.course.mapper", sqlSessionTemplateRef = "courseSqlSessionTemplate")
public class DataSourceCourse {
@Value("${spring.datasource.course.druid.url}")
private String url;
@Value("${spring.datasource.course.druid.username}")
private String username;
@Value("${spring.datasource.course.druid.password}")
private String password;
@Value("${spring.datasource.course.druid.driverClassName}")
private String driverClassName;
@Bean("courseDataSource")
@Qualifier("courseDataSource")
public DruidDataSource dataSource()
{
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(this.url);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
System.out.println("course");
return datasource;
}
@Bean("courseSqlSessionFactory")
@Qualifier("courseDataSource")
public SqlSessionFactory sqlSessionFactory(@Qualifier("courseDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/courseMapper/*Mapper.xml"));
return sessionFactory.getObject();
}
@Bean("courseTransactionManager")
@Qualifier("courseDataSource")
public DataSourceTransactionManager transactionManager(@Qualifier("courseDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean("courseSqlSessionTemplate")
@Qualifier("courseDataSource")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("courseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
这一部分为重中之重,所有的注解名称都需要更改(代码所有绿色部分)
@MapperScan内的basePackages 是扫描MyBatis提供的mapper接口所在位置,sqlSessionTemplateRef 里面随意起名,对下面的注解没有影响,但是注意,要和其余几个配置类所起的名字要不同。@Value 这个是手动获取yml的配置信息,自动获取老出问题,我每次都获取不到。细心的读者可能会发现DataSourceUser (第一个)类每个方法前面都有@Primary注解,而DataSourceCourse (第二个)类方法就变成了@Qualifier(这里面的名字也是随意,只要这几个类不同就行),这个是防止SpringBoot自动装配的时候,发现存在多个数据源,不知道该使用哪个而在启动时报错。 如有两个以上的数据源,就在其余的配置类的方法上和DataSourceCourse (第二个)一样使用@Qualifier注解。剩下的Bean与作为参数的@Qualifier注解对应由读者自行观察就不再赘述。getResources方法参数是XML所在位置3、而repository包与mapper包就不再赘述,但一定要注意与config包下类的对应关系
在这里感谢这位博主所写文章提供的思路
https://blog.csdn.net/weixin_36586564/article/details/105200968
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)