zoukankan      html  css  js  c++  java
  • springboot2.0整合多数据源配置

    在我们的实际项目中,有可能是使用多个数据库(也就是多数据源)的场景,那么在多数据源的场景下,需要怎么配置以及解决事务问题呢?

    话不多说,直接上代码:

    pom.xml文件配置

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     3          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     4     <modelVersion>4.0.0</modelVersion>
     5     <parent>
     6         <groupId>org.springframework.boot</groupId>
     7         <artifactId>spring-boot-starter-parent</artifactId>
     8         <version>2.2.10.RELEASE</version>
     9         <relativePath/>
    10     </parent>
    11     <groupId>com.wuwu</groupId>
    12     <artifactId>cboot</artifactId>
    13     <version>0.0.1-SNAPSHOT</version>
    14     <name>cboot</name>
    15     <description>this project for Spring Boot</description>
    16 
    17     <properties>
    18         <java.version>1.8</java.version>
    19     </properties>
    20 
    21     <dependencies>
    22         <dependency>
    23             <groupId>org.springframework.boot</groupId>
    24             <artifactId>spring-boot-starter-data-jdbc</artifactId>
    25         </dependency>
    26         <dependency>
    27             <groupId>org.springframework.boot</groupId>
    28             <artifactId>spring-boot-starter-web</artifactId>
    29         </dependency>
    30         <!-- mybatis -->
    31         <dependency>
    32             <groupId>org.mybatis.spring.boot</groupId>
    33             <artifactId>mybatis-spring-boot-starter</artifactId>
    34             <version>2.0.0</version>
    35         </dependency>
    36         <dependency>
    37             <groupId>org.projectlombok</groupId>
    38             <artifactId>lombok</artifactId>
    39             <version>1.18.12</version>
    40             <scope>provided</scope>
    41         </dependency>
    42 
    43         <dependency>
    44             <groupId>mysql</groupId>
    45             <artifactId>mysql-connector-java</artifactId>
    46             <scope>runtime</scope>
    47         </dependency>
    48 
    49         <dependency>
    50             <groupId>ch.qos.logback</groupId>
    51             <artifactId>logback-core</artifactId>
    52             <version>1.1.3</version>
    53         </dependency>
    54         <dependency>
    55             <groupId>ch.qos.logback</groupId>
    56             <artifactId>logback-access</artifactId>
    57             <version>1.1.3</version>
    58         </dependency>
    59         <dependency>
    60             <groupId>ch.qos.logback</groupId>
    61             <artifactId>logback-classic</artifactId>
    62             <version>1.1.3</version>
    63         </dependency>
    64 
    65         <dependency>
    66             <groupId>org.springframework.boot</groupId>
    67             <artifactId>spring-boot-starter-test</artifactId>
    68             <scope>test</scope>
    69             <exclusions>
    70                 <exclusion>
    71                     <groupId>org.junit.vintage</groupId>
    72                     <artifactId>junit-vintage-engine</artifactId>
    73                 </exclusion>
    74             </exclusions>
    75         </dependency>
    76     </dependencies>
    77 
    78     <build>
    79         <plugins>
    80             <plugin>
    81                 <groupId>org.springframework.boot</groupId>
    82                 <artifactId>spring-boot-maven-plugin</artifactId>
    83             </plugin>
    84         </plugins>
    85     </build>
    86 
    87 </project>
    View Code

     application.properties文件配置

     1 server.port=8090
     2 server.servlet.context-path=/
     3 
     4 #单数据源
     5 #spring.datasource.driverClassName=com.mysql.jdbc.Driver
     6 #spring.datasource.url=jdbc:mysql://localhost:3306/cboot?useUnicode=true&amp;amp;characterEncoding=UTF-8
     7 #spring.datasource.username=root
     8 #spring.datasource.password=root
     9 
    10 #多数据源-订单
    11 spring.datasource.order.driverClassName=com.mysql.jdbc.Driver
    12 spring.datasource.order.jdbc-url=jdbc:mysql://localhost:3306/cboot?useUnicode=true&amp;amp;characterEncoding=UTF-8
    13 spring.datasource.order.username=root
    14 spring.datasource.order.password=root
    15 
    16 #多数据源-会员
    17 spring.datasource.member.driverClassName=com.mysql.jdbc.Driver
    18 spring.datasource.member.jdbc-url=jdbc:mysql://localhost:3306/cboot1?useUnicode=true&amp;amp;characterEncoding=UTF-8
    19 spring.datasource.member.username=root
    20 spring.datasource.member.password=root
    View Code

     注意:多数据源的情况下在连接数据源地址的时,将常用的spring.datasource.url换成spring.datasource.jdbc-url,否则会报jdbcUrl is required with driverClassName的错误,如下图:

    会员数据源配置

     1 package com.wuwu.cboot.config;
     2 
     3 import lombok.SneakyThrows;
     4 import org.apache.ibatis.session.SqlSessionFactory;
     5 import org.mybatis.spring.SqlSessionFactoryBean;
     6 import org.mybatis.spring.SqlSessionTemplate;
     7 import org.mybatis.spring.annotation.MapperScan;
     8 import org.springframework.beans.factory.annotation.Qualifier;
     9 import org.springframework.boot.context.properties.ConfigurationProperties;
    10 import org.springframework.boot.jdbc.DataSourceBuilder;
    11 import org.springframework.context.annotation.Bean;
    12 import org.springframework.context.annotation.Configuration;
    13 import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    14 
    15 import javax.sql.DataSource;
    16 
    17 /**
    18  * @Description:会员数据源配置
    19  * @author: wph
    20  * @Version: 1.0
    21  * @date: 2021/1/12
    22  */
    23 
    24 @Configuration
    25 @MapperScan(basePackages = "com.wuwu.cboot.member.mapper",sqlSessionTemplateRef = "memberSqlSessionTemplate")
    26 public class MemberDataSourceConfig {
    27 
    28     /**
    29      * @Description: 配置会员数据源
    30      * @author: wph
    31      * @date: 2021/1/15
    32      * @return javax.sql.DataSource
    33      */
    34     @Bean("memberDataSource")
    35     @ConfigurationProperties("spring.datasource.member")
    36     public DataSource memberDataSource(){
    37         return DataSourceBuilder.create().build();
    38     }
    39 
    40     /**
    41      * @Description: 创建会员事务管理器
    42      * @author: wph
    43      * @date: 2021/1/21
    44      * @param dataSource
    45      * @return org.springframework.jdbc.datasource.DataSourceTransactionManager
    46      */
    47     @Bean("memberTransactionManager")
    48     public DataSourceTransactionManager memberTransactionManager(@Qualifier("memberDataSource") DataSource dataSource){
    49         return new DataSourceTransactionManager(dataSource);
    50     }
    51 
    52     /**
    53      * @Description: 将会员sqlSessionFactory注入到容器中
    54      * @author: wph
    55      * @date: 2021/1/13
    56      * @param dataSource 
    57      * @return org.apache.ibatis.session.SqlSessionFactory
    58      */
    59     @SneakyThrows(Exception.class)
    60     @Bean("memberSqlSessionFactory")
    61     public SqlSessionFactory memberSqlSessionFactory(@Qualifier("memberDataSource")DataSource dataSource){
    62         SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
    63         sqlSessionFactoryBean.setDataSource(dataSource);
    64         return sqlSessionFactoryBean.getObject();
    65     }
    66 
    67     /**
    68      * @Description: 创建SqlSessionTemplate模板
    69      * @author: wph
    70      * @date: 2021/1/18
    71      * @param sqlSessionFactory
    72      * @return org.mybatis.spring.SqlSessionTemplate
    73      */
    74     @Bean("memberSqlSessionTemplate")
    75     public SqlSessionTemplate memberSqlSessionTemplate(@Qualifier("memberSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
    76         return new SqlSessionTemplate(sqlSessionFactory);
    77     }
    78 
    79 }
    View Code

    订单数据源配置

     1 package com.wuwu.cboot.config;
     2 
     3 import lombok.SneakyThrows;
     4 import org.apache.ibatis.session.SqlSessionFactory;
     5 import org.mybatis.spring.SqlSessionFactoryBean;
     6 import org.mybatis.spring.SqlSessionTemplate;
     7 import org.mybatis.spring.annotation.MapperScan;
     8 import org.springframework.beans.factory.annotation.Qualifier;
     9 import org.springframework.boot.context.properties.ConfigurationProperties;
    10 import org.springframework.boot.jdbc.DataSourceBuilder;
    11 import org.springframework.context.annotation.Bean;
    12 import org.springframework.context.annotation.Configuration;
    13 import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    14 
    15 import javax.sql.DataSource;
    16 
    17 /**
    18  * @Description:订单数据源配置
    19  * @author: wph
    20  * @Version: 1.0
    21  * @date: 2021/1/15
    22  */
    23 @Configuration
    24 @MapperScan(basePackages = "com.wuwu.cboot.order.mapper",sqlSessionFactoryRef = "orderSqlSessionFactory")
    25 public class OrderDataSourceConfig {
    26 
    27     /**
    28      * @Description: 配置订单数据源
    29      * @author: wph
    30      * @date: 2021/1/15
    31      * @param orderConfig
    32      * @return javax.sql.DataSource
    33      */
    34     @Bean("orderDataSource")
    35     @ConfigurationProperties(prefix = "spring.datasource.order")
    36     public DataSource orderDataSource(){
    37         return DataSourceBuilder.create().build();
    38     }
    39 
    40     /**
    41      * @Description: 创建会员事务管理器
    42      * @author: wph
    43      * @date: 2021/1/21
    44      * @param dataSource
    45      * @return org.springframework.jdbc.datasource.DataSourceTransactionManager
    46      */
    47     @Bean("orderTransactionManager")
    48     public DataSourceTransactionManager orderTransactionManager(@Qualifier("orderDataSource") DataSource dataSource){
    49         return new DataSourceTransactionManager(dataSource);
    50     }
    51 
    52     /**
    53      * @Description: 配置session工厂
    54      * @author: wph
    55      * @date: 2021/1/18
    56      * @param dataSource
    57      * @return org.apache.ibatis.session.SqlSessionFactory
    58      */
    59     @SneakyThrows
    60     @Bean("orderSqlSessionFactory")
    61     public SqlSessionFactory orderSqlSessionFactory(@Qualifier("orderDataSource") DataSource dataSource){
    62         SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
    63         sqlSessionFactoryBean.setDataSource(dataSource);
    64         return sqlSessionFactoryBean.getObject();
    65     }
    66 
    67     /**
    68      * @Description: 创建SqlSessionTemplate模板
    69      * @author: wph
    70      * @date: 2021/1/18
    71      * @param sqlSessionFactory
    72      * @return org.mybatis.spring.SqlSessionTemplate
    73      */
    74     @Bean("orderSqlSessionTemplate")
    75     public SqlSessionTemplate orderSqlSessionTemplate(@Qualifier("orderSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
    76         return new SqlSessionTemplate(sqlSessionFactory);
    77     }
    78 
    79 }
    View Code

    Controller层

     1 package com.wuwu.cboot.controller;
     2 
     3 import com.wuwu.cboot.service.MemberService;
     4 import org.springframework.beans.factory.annotation.Autowired;
     5 import org.springframework.web.bind.annotation.RequestMapping;
     6 import org.springframework.web.bind.annotation.RestController;
     7 
     8 /**
     9  * @Description:会员控制层
    10  * @author: wph
    11  * @Version: 1.0
    12  * @date: 2020/10/26
    13  */
    14 @RestController
    15 public class MemberController {
    16 
    17     @Autowired
    18     private MemberService memberService;
    19 
    20     /**
    21      * @Description: 新增会员用户
    22      * @author: wph
    23      * @date: 2021/1/20
    24      * @param age
    25      * @param name
    26      * @return java.lang.Object
    27      */
    28     @RequestMapping("/saveMember")
    29     public Object saveMember(int age,String name){
    30         return memberService.saveMember(age,name);
    31     }
    32 }
    View Code

    service层实现

     1 package com.wuwu.cboot.service.impl;
     2 
     3 import com.wuwu.cboot.member.mapper.MemberMapper;
     4 import com.wuwu.cboot.order.mapper.OrderMemberMapper;
     5 import com.wuwu.cboot.service.MemberService;
     6 import org.springframework.stereotype.Service;
     7 import org.springframework.transaction.annotation.Transactional;
     8 
     9 import javax.annotation.Resource;
    10 
    11 /**
    12  * @Description:
    13  * @author: wph
    14  * @Version: 1.0
    15  * @date: 2021/1/12
    16  */
    17 @Service
    18 public class MemberServiceImpl implements MemberService {
    19 
    20     @Resource
    21     private OrderMemberMapper orderMemberMapper;
    22     @Resource
    23     private MemberMapper memberMapper;
    24 
    25     @Transactional("memberTransactionManager")
    26     public String saveMember(int age,String name){
    27         //调用会员接口
    28         int i = memberMapper.saveMember(age, name);
    29         return i == 1 ? "true" : "false";
    30     }
    31 }
    View Code

    如果需要事务的控制,只需要在方法上方加上@Transactional("对应的事务管理器")注解即可(如代码所示),看到这里你可能会有疑问:如果我一个service方法内调用了不同的数据源,事务怎么解决呢?

    别急,请继续往下看

    mapper层

     1 package com.wuwu.cboot.member.mapper;
     2 
     3 import org.apache.ibatis.annotations.Insert;
     4 import org.apache.ibatis.annotations.Mapper;
     5 
     6 @Mapper
     7 public interface MemberMapper {
     8 
     9     @Insert("insert into member (age,name) values(#{age},#{name})")
    10     int saveMember(int age, String name);
    11 }
    View Code

    mapper接口采用了分包结构的形式,分别对应会员数据源MemberDataSourceConfig以及订单数据源OrderDataSourceConfig中的注解MapperScan地址

    最后再附上项目结构以及启动类的代码截图

     关于多数据源的配置,文章到此就已结束了。

    但是文章提到一个疑问:如果一个service方法内调用了不同的数据源,事务怎么解决呢?我们修改一下MemberServiceImpl类里面的代码

    这种情况下呢,就会出现:多数据源分布式事务问题

    A服务中调用了B服务的接口,如果A服务执行时报错,那么A服务对应的事务会回滚,B服务不会回滚,那这样子是肯定不行的。

    那如何解决“多数据源分布式事务问题”呢?请移步下一篇文章:springboot2.0 解决多数据源分布式事务问题 

  • 相关阅读:
    简单实现MySQL数据库的日志审计
    利用Impdp+Network将Oracle 11g数据迁移到Oracle 19c
    Oracle Orion tool check IO(Oracle Orion工具查看及校验IO)
    Oracle exp(expdp)数据迁移(生产环境,进行数据对以及统计信息的收集)
    OEM 12C(12.1.0.5)安装插件Plug-in监控MySQL(Linux)
    马斯洛需求层次理论
    完成一条指令的三个阶段
    Render
    JXP
    DOM
  • 原文地址:https://www.cnblogs.com/w-wu/p/14333950.html
Copyright © 2011-2022 走看看