前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot配置多数据源

Spring Boot配置多数据源

作者头像
十毛
发布2021-07-13 11:46:37
6410
发布2021-07-13 11:46:37
举报

业务发展后,一些查询类型的请求需要切换到备用数据源,这个时候需要使用多数据源配置,公司的项目使用的不是主备,而是需要去查询postgresql库(业务库是mysql,所以不是简单的主从,而且语句也可能变化,因为mysql是做了分库的)

整体文件结构

代码文件结构

多数据源配置

  • primary数据源配置 扫描com.tenmao.multidatasource.mapper.primary下的mapper接口,注意需要配置sqlSessionFactoryRef = "primarySqlSessionFactory"
代码语言:javascript
复制
@Configuration
@MapperScan(basePackages = {"com.tenmao.multidatasource.mapper.primary"}, sqlSessionFactoryRef = "primarySqlSessionFactory")
public class PrimaryDataSourceConfiguration {

    @Bean("primary")
    //从配置文件中读取前缀为spring.datasource.primary的配置作为primary数据源
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean("primarySqlSessionFactory")
    public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primary") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //配置xml文件
//        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        return bean.getObject();
    }
}
  • second数据源配置 扫描com.tenmao.multidatasource.mapper.second下的mapper接口,注意需要配置sqlSessionFactoryRef = "secondSqlSessionFactory"
代码语言:javascript
复制
@Configuration
@MapperScan(basePackages = {"com.tenmao.multidatasource.mapper.second"}, sqlSessionFactoryRef = "secondSqlSessionFactory")
public class SecondDataSourceConfiguration {

    @Bean("second")
   //从配置文件中读取前缀为spring.datasource.second的配置作为second数据源 
  @ConfigurationProperties(prefix = "spring.datasource.second")
   public DataSource primaryDataSource() {
       return DataSourceBuilder.create().build();
   }

   @Bean("secondSqlSessionFactory")
   public SqlSessionFactory secondSqlSessionFactory(@Qualifier("second") DataSource dataSource) throws Exception {
       SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
       bean.setDataSource(dataSource);
       //配置xml文件
//        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
       return bean.getObject();
   }
}

领域类和Mapper类

  • 领域类: User是primary库的表信息
代码语言:javascript
复制
@Data
public class User {
   private Integer uid;
   private String name;
}
  • 领域类: Phone是second库的表信息
代码语言:javascript
复制
@Data
public class Phone {
   private String model;
   private Integer price;
}
  • MyBatis的映射类: UserMapper
代码语言:javascript
复制
@Mapper
public interface UserMapper {
   @Select("SELECT * FROM user WHERE id=#{id}")
   User selectOne(int id);
}
  • MyBatis的映射类: PhoneMapper
代码语言:javascript
复制
@Mapper
public interface PhoneMapper {
   @Select("SELECT * FROM phone WHERE id=#{id}")
   Phone selectOne(int id);
}

启动类和配置文件

  • 启动类
代码语言:javascript
复制
@RestController
@SpringBootApplication
public class MultidatasourceApplication {
   @Resource
   private UserMapper userMapper;

   @Resource
   private PhoneMapper phoneMapper;

   public static void main(String[] args) {
       SpringApplication.run(MultidatasourceApplication.class, args);
   }

   @GetMapping("getOneUser")
   public User getOneUser(@RequestParam Integer id) {
       return userMapper.selectOne(id);
   }

   @GetMapping("getOnePhone")
   public Phone getOnePhone(@RequestParam Integer id) {
       return phoneMapper.selectOne(id);
   }
}
  • 配置文件:application.yml 需要注意的是: 这里的配置实际上都是Hikari数据源的配置项
代码语言:javascript
复制
spring:
 datasource:
   primary:
     jdbc-url: jdbc:mysql://localhost:3306/test?useAffectedRows=true&autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&tinyInt1isBit=false&serverTimezone=GMT%2B8
     username: root
     password: root
   second:
     jdb-url: jdbc:mysql://192.168.1.101:3306/tenmao?useAffectedRows=true&autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&tinyInt1isBit=false&serverTimezone=GMT%2B8
     username: tenmao
     password: tenmao

其他特性

  • 数据源只读: 如果其中一个数据源是只读的话, 可以在配置中设置readonly
代码语言:javascript
复制
   second:
     jdb-url: jdbc:mysql://192.168.1.101:3306/tenmao?useAffectedRows=true&autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&tinyInt1isBit=false&serverTimezone=GMT%2B8
     username: tenmao
     password: tenmao
     # 设置second数据源为只读
     read-only: true

如果尝试修改只读数据源则会抛出异常:java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed

  • 使用MyBatis-Plus 需要在数据源配置的时候把SqlSessionFactoryBean替换为MybatisSqlSessionFactoryBean
代码语言:javascript
复制
@Bean("primarySqlSessionFactory")
public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primary") DataSource dataSource) throws Exception {
    //如果使用MyBatis-Plus,则需要把SqlSessionFactoryBean替换为MybatisSqlSessionFactoryBean
    MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    //配置xml文件
//        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
    return bean.getObject();
}

常见问题

  • org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.tenmao.multidatasource.mapper.second.PhoneMapper.selectById: 这是使用MyBatis-Plus的内置函数,但是使用的是标准版的SqlSessionFactory。解决办法是用SqlSessionFactoryBean替换为MybatisSqlSessionFactoryBean
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 整体文件结构
  • 多数据源配置
  • 领域类和Mapper类
  • 启动类和配置文件
  • 其他特性
  • 常见问题
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档