【微信1039576978,获取珠峰前端架构师全套课程】
同一个项目有时会涉及到多个数据库,这时我们就要配置多个数据源。配置多数据源的常见情况有以下两种:
1)同一个项目中涉及两个或多个业务数据库,它们之间相互独立,这种情况也可以作为两个或多个项目来开发
2)两个或多个数据库之间是主从关系,主库负责写,从库负责读
下面我们通过一个示例来说明多数据源的配置
1、pom.xml 配置
如果您在前面文章中引入了下面的依赖,请忽略这个小点,如果没有,请在 pom.xml 中引入以下依赖:
<!-- 连接mysql的必要依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!-- 整合MyBatis的核心依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
2、配置文件配置
在配置文件 application-dev.yml 中配置我们需要链接的数据库:blog 和 user
spring:
datasource:
blog:
jdbc-url: jdbc:mysql://localhost:3306/blog
username: root
password: test
driver-class-name: com.mysql.cj.jdbc.Driver
user:
jdbc-url: jdbc:mysql://localhost:3306/user
username: root
password: test
driver-class-name: com.mysql.cj.jdbc.Driver
注意:
1)我们在 spring.datasource 之后多设置了一个数据源名称 blog 和 user 来区分不同的数据源配置
2)如果报下面错误,则把 url 改为 jdbc-url 即可
nested exception is java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.
3)com.mysql.jdbc.Driver 与 com.mysql.cj.jdbc.Driver 的区别
com.mysql.jdbc.Driver 是 mysql-connector-java 5 中的
com.mysql.cj.jdbc.Driver 是 mysql-connector-java 6 中的
3、数据源配置
配置文件配置好之后,我们创建两个配置类来加载配置信息,初始化数据源
blog 的配置类:
@Configuration
@MapperScan(basePackages = "com.tn666.demo.dao.blog", sqlSessionTemplateRef = "blogSqlSessionTemplate")
public class DataSourceBlogConfig {
@Primary
@Bean(name = "blogDataSource")
@ConfigurationProperties(prefix = "spring.datasource.blog")
public DataSource blogDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "blogSqlSessionFactory")
public SqlSessionFactory blogSqlSessionFactory(@Qualifier("blogDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "blogSqlSessionTemplate")
public SqlSessionTemplate blogSqlSessionTemplate(@Qualifier("blogSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
User 的配置类:
@Configuration
@MapperScan(basePackages = "com.tn666.demo.dao.user", sqlSessionTemplateRef = "userSqlSessionTemplate")
public class DataSourceUserConfig {
@Bean(name = "userDataSource")
@ConfigurationProperties(prefix = "spring.datasource.user")
public DataSource userDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "userSqlSessionFactory")
public SqlSessionFactory userSqlSessionFactory(@Qualifier("userDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "userSqlSessionTemplate")
public SqlSessionTemplate userSqlSessionTemplate(@Qualifier("userSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
注意:
1)类注解 @MapperScan 的属性 basePackages 配置的为对应 DA 层 dao 的位置
2)@Primary 注解指定了主数据源
4、实体类和 dao 层配置
在 blog 数据库中,创建一个 article 表,在 user 数据库中创建一个 user_info 表,然后创建它们的实体类和 dao 层
创建 article 和 user_info 的实体类:
public class ArticlePo {
private Integer id;
private String articleId;
private String title;
// get、set...
}
public class UserInfoPo {
private Integer id;
private String userId;
private String name;
// get、set...
}
创建 article 和 user_info 的 dao 层:
@Repository
public interface ArticleDao {
@Select("select * from article where article_id = #{articleId}")
@Results({@Result(column = "article_id", property = "articleId")})
ArticlePo get(@Param("articleId") String articleId);
// 给article赋值自增主键id
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
@Insert("insert into article(article_id, title) values(#{article.articleId}, #{article.title})")
int insert(@Param("article") ArticlePo articlePo);
}
@Repository
public interface UserInfoDao {
@Select("select * from user_info where user_id=#{userId}")
@Results({@Result(column = "user_id", property = "userId")})
UserInfoPo get(@Param("userId") String userId);
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
@Insert("insert into user_info(user_id, name) values(#{userInfo.userId}, #{userInfo.name})")
int insert(@Param("userInfo") UserInfoPo userInfoPo);
}
5、测试验证
编写 ArticleController 和 UserInfoController:
@RestController
@RequestMapping("/article")
public class ArticleController {
@Resource
private ArticleDao articleDao;
@GetMapping(value = "/get")
public ArticlePo get(@RequestParam("articleId") String articleId) {
ArticlePo articlePo = articleDao.get(articleId);
return articlePo;
}
@PostMapping(value = "/insert")
public Boolean insert(@RequestBody ArticlePo articlePo) {
articleDao.insert(articlePo);
Boolean res = false;
if (articlePo.getId() > 0) {
res = true;
}
return res;
}
}
@RestController
@RequestMapping("/user")
public class UserInfoController {
@Resource
private UserInfoDao userInfoDao;
@GetMapping(value = "/get")
public UserInfoPo get(@RequestParam("userId") String userId) {
UserInfoPo res = userInfoDao.get(userId);
return res;
}
@PostMapping(value = "/insert")
public Boolean insert(@RequestBody UserInfoPo userInfoPo) {
userInfoDao.insert(userInfoPo);
Boolean res = false;
if (userInfoPo.getId() > 0) {
res = true;
}
return res;
}
}
业务逻辑复杂时,Controller 和 Mapper 中间会有 Service 层来处理业务逻辑,现在我们就简单的测试一下多数据源,所以直接使用 Controller 调用 Mapper 了
【微信642620018,获取珠峰前端架构师全套课程】
同一个项目有时会涉及到多个数据库,这时我们就要配置多个数据源。配置多数据源的常见情况有以下两种:
1)同一个项目中涉及两个或多个业务数据库,它们之间相互独立,这种情况也可以作为两个或多个项目来开发
2)两个或多个数据库之间是主从关系,主库负责写,从库负责读
下面我们通过一个示例来说明多数据源的配置
1、pom.xml 配置
如果您在前面文章中引入了下面的依赖,请忽略这个小点,如果没有,请在 pom.xml 中引入以下依赖:
<!-- 连接mysql的必要依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!-- 整合MyBatis的核心依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
2、配置文件配置
在配置文件 application-dev.yml 中配置我们需要链接的数据库:blog 和 user
spring:
datasource:
blog:
jdbc-url: jdbc:mysql://localhost:3306/blog
username: root
password: test
driver-class-name: com.mysql.cj.jdbc.Driver
user:
jdbc-url: jdbc:mysql://localhost:3306/user
username: root
password: test
driver-class-name: com.mysql.cj.jdbc.Driver
注意:
1)我们在 spring.datasource 之后多设置了一个数据源名称 blog 和 user 来区分不同的数据源配置
2)如果报下面错误,则把 url 改为 jdbc-url 即可
nested exception is java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.
3)com.mysql.jdbc.Driver 与 com.mysql.cj.jdbc.Driver 的区别
com.mysql.jdbc.Driver 是 mysql-connector-java 5 中的
com.mysql.cj.jdbc.Driver 是 mysql-connector-java 6 中的
3、数据源配置
配置文件配置好之后,我们创建两个配置类来加载配置信息,初始化数据源
blog 的配置类:
@Configuration
@MapperScan(basePackages = "com.tn666.demo.dao.blog", sqlSessionTemplateRef = "blogSqlSessionTemplate")
public class DataSourceBlogConfig {
@Primary
@Bean(name = "blogDataSource")
@ConfigurationProperties(prefix = "spring.datasource.blog")
public DataSource blogDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "blogSqlSessionFactory")
public SqlSessionFactory blogSqlSessionFactory(@Qualifier("blogDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "blogSqlSessionTemplate")
public SqlSessionTemplate blogSqlSessionTemplate(@Qualifier("blogSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
User 的配置类:
@Configuration
@MapperScan(basePackages = "com.tn666.demo.dao.user", sqlSessionTemplateRef = "userSqlSessionTemplate")
public class DataSourceUserConfig {
@Bean(name = "userDataSource")
@ConfigurationProperties(prefix = "spring.datasource.user")
public DataSource userDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "userSqlSessionFactory")
public SqlSessionFactory userSqlSessionFactory(@Qualifier("userDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "userSqlSessionTemplate")
public SqlSessionTemplate userSqlSessionTemplate(@Qualifier("userSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
注意:
1)类注解 @MapperScan 的属性 basePackages 配置的为对应 DA 层 dao 的位置
2)@Primary 注解指定了主数据源
4、实体类和 dao 层配置
在 blog 数据库中,创建一个 article 表,在 user 数据库中创建一个 user_info 表,然后创建它们的实体类和 dao 层
创建 article 和 user_info 的实体类:
public class ArticlePo {
private Integer id;
private String articleId;
private String title;
// get、set...
}
public class UserInfoPo {
private Integer id;
private String userId;
private String name;
// get、set...
}
创建 article 和 user_info 的 dao 层:
@Repository
public interface ArticleDao {
@Select("select * from article where article_id = #{articleId}")
@Results({@Result(column = "article_id", property = "articleId")})
ArticlePo get(@Param("articleId") String articleId);
// 给article赋值自增主键id
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
@Insert("insert into article(article_id, title) values(#{article.articleId}, #{article.title})")
int insert(@Param("article") ArticlePo articlePo);
}
@Repository
public interface UserInfoDao {
@Select("select * from user_info where user_id=#{userId}")
@Results({@Result(column = "user_id", property = "userId")})
UserInfoPo get(@Param("userId") String userId);
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
@Insert("insert into user_info(user_id, name) values(#{userInfo.userId}, #{userInfo.name})")
int insert(@Param("userInfo") UserInfoPo userInfoPo);
}
5、测试验证
编写 ArticleController 和 UserInfoController:
@RestController
@RequestMapping("/article")
public class ArticleController {
@Resource
private ArticleDao articleDao;
@GetMapping(value = "/get")
public ArticlePo get(@RequestParam("articleId") String articleId) {
ArticlePo articlePo = articleDao.get(articleId);
return articlePo;
}
@PostMapping(value = "/insert")
public Boolean insert(@RequestBody ArticlePo articlePo) {
articleDao.insert(articlePo);
Boolean res = false;
if (articlePo.getId() > 0) {
res = true;
}
return res;
}
}
@RestController
@RequestMapping("/user")
public class UserInfoController {
@Resource
private UserInfoDao userInfoDao;
@GetMapping(value = "/get")
public UserInfoPo get(@RequestParam("userId") String userId) {
UserInfoPo res = userInfoDao.get(userId);
return res;
}
@PostMapping(value = "/insert")
public Boolean insert(@RequestBody UserInfoPo userInfoPo) {
userInfoDao.insert(userInfoPo);
Boolean res = false;
if (userInfoPo.getId() > 0) {
res = true;
}
return res;
}
}
业务逻辑复杂时,Controller 和 Mapper 中间会有 Service 层来处理业务逻辑,现在我们就简单的测试一下多数据源,所以直接使用 Controller 调用 Mapper 了
参考:http://www.cr7mufc520.cn/archives/zhufeng001
http://www.vx642620018.top/articles/2021/11/23/1637660090885.html