zoukankan      html  css  js  c++  java
  • Spring Boot 2.x 多数据源配置之 MyBatis 篇

    场景假设:现有电商业务,商品和库存分别放在不同的库

    配置数据库连接

    app:
      datasource:
    
        first:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://127.0.0.1/product?useSSL=false
          username: root
          password: root
          configuration:
            maximum-pool-size: 10
    
        second:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://127.0.0.1/stock?useSSL=false
          username: root
          password: root
          configuration:
            maximum-pool-size: 10
    

    添加配置类

    FirstConfig

    @Configuration
    @MapperScan(
            basePackages  = {"com.karonda.springboot2datasourcesmybatis.dao.first"},// 1. dao 层所在的包
            sqlSessionTemplateRef = "firstSqlSessionTemplate")
    public class FirstConfig {
    
        @Bean
        @Primary
        public SqlSessionTemplate firstSqlSessionTemplate() throws Exception {
            return new SqlSessionTemplate(firstSqlSessionFactory());
        }
    
        @Bean
        @Primary
        public DataSourceTransactionManager firstTransactionManager(){
            return new DataSourceTransactionManager(firstDataSource());
        }
    
        @Bean
        @Primary
        public SqlSessionFactory firstSqlSessionFactory() throws Exception {
            SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
            factoryBean.setDataSource(firstDataSource());
            factoryBean.setMapperLocations(
                    new PathMatchingResourcePatternResolver()
                            .getResources("classpath:mapper/first/*.xml")); // 2. xml 所在路径
            return factoryBean.getObject();
        }
    
        @Bean
        @Primary
        @ConfigurationProperties("app.datasource.first")
        public DataSourceProperties firstDataSourceProperties() {
            return new DataSourceProperties();
        }
    
        @Bean
        @Primary
        @ConfigurationProperties("app.datasource.first.configuration")
        public DataSource firstDataSource() {
            return firstDataSourceProperties()
                    .initializeDataSourceBuilder()
                    .type(HikariDataSource.class) // 3. 可以显示指定连接池,也可以不显示指定;即此行代码可以注释掉
                    .build();
        }
    
    }
    

    SecondConfig

    @Configuration
    @MapperScan(
            basePackages = {"com.karonda.springboot2datasourcesmybatis.dao.second"},
            sqlSessionTemplateRef = "secondSqlSessionTemplate")
    public class SecondConfig {
    
        @Bean
        public SqlSessionTemplate secondSqlSessionTemplate() throws Exception {
            return new SqlSessionTemplate(secondSqlSessionFactory());
        }
    
        @Bean
        public DataSourceTransactionManager secondTransactionManager(){
            return new DataSourceTransactionManager(secondDataSource());
        }
    
        @Bean
        public SqlSessionFactory secondSqlSessionFactory() throws Exception {
            SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
            factoryBean.setDataSource(secondDataSource());
            factoryBean.setMapperLocations(
                    new PathMatchingResourcePatternResolver()
                            .getResources("classpath:mapper/second/*.xml"));
            return factoryBean.getObject();
        }
    
        @Bean
        @ConfigurationProperties("app.datasource.second")
        public DataSourceProperties secondDataSourceProperties() {
            return new DataSourceProperties();
        }
    
        @Bean
        @ConfigurationProperties("app.datasource.second.configuration")
        public DataSource secondDataSource() {
            return secondDataSourceProperties()
                    .initializeDataSourceBuilder()
                    .type(HikariDataSource.class)
                    .build();
        }
    
    }
    

    dao

    public interface ProductMapper {
    
        Product getOneById(int id);
    }
    
    public interface StockMapper {
    
        Stock getOneByProductId(int productId);
    }
    

    xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.karonda.springboot2datasourcesmybatis.dao.first.ProductMapper">
      <resultMap id="BaseResultMap" type="com.karonda.springboot2datasourcesmybatis.entity.Product">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="name" jdbcType="VARCHAR" property="name" />
      </resultMap>
      <sql id="Base_Column_List">
        id, name
      </sql>
      <select id="getOneById" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        select 
        <include refid="Base_Column_List" />
        from product
        where id = #{id,jdbcType=INTEGER}
      </select>
    </mapper>
    
    <mapper namespace="com.karonda.springboot2datasourcesmybatis.dao.second.StockMapper">
      <resultMap id="BaseResultMap" type="com.karonda.springboot2datasourcesmybatis.entity.Stock">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="product_id" jdbcType="INTEGER" property="productId" />
        <result column="stock_count" jdbcType="INTEGER" property="stockCount" />
      </resultMap>
      <sql id="Base_Column_List">
        id, product_id, stock_count
      </sql>
      <select id="getOneByProductId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        select 
        <include refid="Base_Column_List" />
        from stock
        where product_id = #{productId,jdbcType=INTEGER}
      </select>
    </mapper>
    

    使用示例

    @Component
    public class Task {
    
        @Autowired
        private ProductMapper productMapper;
        @Autowired
        private StockMapper stockMapper;
    
        @Scheduled(cron = "0/5 * * * * ? ")
        public void job(){
    
            final int productId = 1;
            Product product = productMapper.getOneById(productId);
            Stock stock = stockMapper.getOneByProductId(productId);
    
            System.out.println("产品名称: " + product.getName() + ", 库存: " + stock.getStockCount());
        }
    
    }
    

    注意事项

    1. 使用多数据源,其中一个配置类需要添加 @Primary 注解 (有且仅有一个配置类需要添加)
    2. 在配置类中需要同时配置 dao 层所在的包和 xml 所在的路径

    总结

    与 JPA 使用多数据源配置基本相同,具体可对比上一篇文章 Spring Boot 2.x 多数据源配置之 JPA 篇

    参考:

    Spring Boot(七):Mybatis 多数据源最简解决方案

    完整代码:GitHub

    本人 C# 转 Java 的 newbie, 如有错误或不足欢迎指正,谢谢

  • 相关阅读:
    delete与double free
    OpenCV(1)——基础数据结构CvMat
    防止表单自动提交_随笔2012年5月16日
    Flex 学习笔记学习资料
    当析构函数遇到多线程 ── C++ 中线程安全的对象回调
    .NET Core2.0+MVC 用session,cookie实现的sso单点登录
    TreeView中右击直接获取节点的方法
    webservice 远程调试配置
    数组,集合 转成DataTable 方法
    String类中几个简单的常用方法
  • 原文地址:https://www.cnblogs.com/victorbu/p/10983184.html
Copyright © 2011-2022 走看看