为什么需要多数据源--珠峰前端架构师百度云下载

Published on with 0 views and 0 comments

【微信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


标题:为什么需要多数据源--珠峰前端架构师百度云下载
作者:vx1039576978
地址:https://vx642620018.top/articles/2023/04/16/1681625751313.html