SpringBoot多数据源读写分离的自定义配置问题及解决方法

 更新时间:2022年06月08日 08:47:19   作者:不瑶碧莲  
这篇文章主要介绍了SpringBoot多数据源读写分离的自定义配置,我们可以通过自定义配置数据库配置类来解决这个问题,方式有很多,不同的业务采用的方式也不同,下面我简单的介绍我们项目的使用的方法

在开发中我们有可能会遇到一个项目需要配置多个数据源,或者需要读写分离的配置,在启动类上贴上@MapperScan注解指定扫描对应的mapper.xml文件肯迪那个是无法满足了。我们可以通过自定义配置数据库配置类来解决这个问题,方式有很多,不同的业务采用的方式也不同,下面我简单的介绍我们项目的使用的方法

比如:项目中我需要连接opretion和device这个两个数据库,且需要进行读写分离,在配置文件中如下:

针对device库我们先创建一个数据库连接配置类

@Configuration
@MapperScan(basePackages = {"com.liuqing.my.repo.device"}, sqlSessionTemplateRef = "deviceSqlSessionTemplate")  
public class DeviceDSConfig {
​
    @Value("${props.sql.show}")  //定义在配置文件中的字段 ture
    private String sqlShow;
}
  • @MapperScan

    • basePackages = {"com.liuqing.my.repo.device"}

      指定包扫描

    • sqlSessionTemplateRef = "deviceSqlSessionTemplate")

      指定sqlSessionTemplateRef

在类中添加配置文件中的读写数据源

@ConfigurationProperties(prefix = "spring.shardingsphere.datasource.device.read")
    public DataSource deviceReadDataSource() {
        return new DruidDataSource();
    }
    @Bean
    @ConfigurationProperties(prefix = "spring.shardingsphere.datasource.device.write")
    public DataSource deviceWriteDataSource() {
        return new DruidDataSource();
    }

@ConfigurationProperties注解的作用和@Value类似,都是获取配置文件中相应的配置值,但是@ConfigurationProperties与@Value不同的是,@Value一次只能获取一个值,但是@ConfigurationProperties可以获取多个值,此处可以将配置文件中的属性,自动封装到DruidDataSource的属性中

配置Sharding数据源的Bean,也就是device.readdevice.write读写分离的数据源

通过@Qualifier注解来指定我们想要使用 deviceReadDataSource 方法返回的 bean ,即获取deviceReadDataSource方法返回DruidDataSource对象,deviceWriteDataSource同理。

通过LoadBalanceStrategyConfiguration是实现我们负载均衡策略

通过MasterSlaveRuleConfiguration构造方法实现自定义的负载均衡算法

@Bean
public DataSource deviceShardingDataSource(@Qualifier("deviceReadDataSource") DataSource readDataSource,   //指定使用deviceReadDataSource的Bean返回的readDataSource对象
                                          @Qualifier("deviceWriteDataSource") DataSource writeDataSource) throws SQLException {
    Map<String, DataSource> dataSourceMap = new HashMap<>();
​
    dataSourceMap.put("device-read", readDataSource);
    dataSourceMap.put("device-write", writeDataSource);
​
    //Spring负载均衡自动配置类   LoadBalanceStrategyConfiguration
    LoadBalanceStrategyConfiguration loadBalanceStrategyConfiguration = new LoadBalanceStrategyConfiguration("round_robin");
    //负载均衡算法
    MasterSlaveRuleConfiguration masterSlaveRuleConfig =
            new MasterSlaveRuleConfiguration(
                    "device_read_write",
                    "device-write",
                    Lists.newArrayList("device-read"),
                    loadBalanceStrategyConfiguration);
​
    Properties properties = new Properties();
    properties.setProperty("sql.show", sqlShow);
​
    return MasterSlaveDataSourceFactory.createDataSource(dataSourceMap, masterSlaveRuleConfig, properties);   //返回一个DataSource
}

创建返回SqlSessionFactory的Bean

1、创建MybatisSqlSessionFactoryBean对象配置SqlSessionFactory;

2、创建MybatisConfiguration对象调用setMapUnderscoreToCamelCase方法,开启mapUnderscoreToCamelCase配置驼峰转换

3、创建GlobalConfig对象出传入MybatisConfiguration对象设置关闭对应banner(可以选择不关,但是利于查看日志和控制台)

4、通过ResourcePatternResolver资源模式解析器,配置mapper.xml的文件路径

@Bean
@Primary  //在同样的DataSource中,首先使用被标注的SqlSessionFactory
public SqlSessionFactory deviceSqlSessionFactory(@Qualifier("deviceShardingDataSource") DataSource shardingDataSource) {
    MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
    bean.setDataSource(shardingDataSource);    //设置 MybatisSqlSessionFactory的数据源
​
    //MyBatis开启mapUnderscoreToCamelCase配置驼峰转换
    MybatisConfiguration configuration = new MybatisConfiguration();
    configuration.setMapUnderscoreToCamelCase(true);
​
    GlobalConfig globalConfig = GlobalConfigUtils.getGlobalConfig(configuration);
    globalConfig.setBanner(false);   //关闭Mybatis 加载的banner
​
    bean.setGlobalConfig(globalConfig);
    bean.setConfiguration(configuration);
​
    // 添加XML目录
    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //资源模式解析器
    try {
        bean.setMapperLocations(resolver.getResources("classpath:mapper/device/**/*Mapper.xml"));  //设施设置mapper映射器位置
        return bean.getObject();  //返回一个SqlSessionFactory'po
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}

题外话:默认情况下,@Autowired 按类型装配 Spring Bean。如果容器中有多个相同类型的 bean,则框架将抛出 NoUniqueBeanDefinitionException, 以提示有多个满足条件的 bean 进行自动装配。程序无法正确做出判断使用哪一个,所以会报错,可以使用@Primary和@Qualifier注解类解决这类问题

  • 通过将 @Qualifier 注解与我们想要使用的特定 Spring bean 的名称一起进行装配,Spring 框架就能从多个相同类型并满足装配要求的 bean 中找到我们想要的
  • @Primary 的解,可以用来发生依赖注入的歧义时决定要注入哪个 bean。当存在多个相同类型的 bean 时,此注解定义了Bean的首选项。

简单来说就是@Qualifier注解那多个Bean指定了我要那个Bean,而@Primary注解表示那个多个Bean,先选贴了@Primary注解的Bean

创建SqlSessionTemplate的Bean

方法名要与类名上@MapperScan注解中的sqlSessionTemplateRef属性值一致;否者无法映射

SqlSessionTemplate是MyBatis-Spring的核心。这个类负责管理MyBatis的SqlSession,调用MyBatis的SQL方法,翻译异常。SqlSessionTemplate是线程安全的,可以被多个DAO所共享使用。

@Bean
@Primary
public SqlSessionTemplate deviceSqlSessionTemplate(@Qualifier("deviceSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
    return new SqlSessionTemplate(sqlSessionFactory);
}

创建DataSourceTransactionManager 事务管理器

@Bean
@Primary
public DataSourceTransactionManager deviceTransactionManager(@Qualifier("deviceShardingDataSource") DataSource shardingDataSource) {
    return new DataSourceTransactionManager(shardingDataSource);
}

到此,我们的配置基本结束,根据我们配置的mapper包扫描下创建对应的mapper接口,

在resource目录下根据我们在配置类中配置的路径存放即可;

最后

注意:这是一个数据源的案例,当是需要配置多个数据源的时候,流程是一样的

1.在配置文件中配置数据库连接数据

2.创建配置类

3.创建mapper接口和mapper.xml文件

到此这篇关于SpringBoot多数据源读写分离的自定义配置问题及解决方法的文章就介绍到这了,更多相关SpringBoot多数据源自定义配置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go Java算法之K个重复字符最长子串详解

    Go Java算法之K个重复字符最长子串详解

    这篇文章主要为大家介绍了Go Java算法之K个重复字符最长子串详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • SpringBoot内置tomcat参数调优的实现

    SpringBoot内置tomcat参数调优的实现

    springboot内置了tomcat, 并给我们设置了默认参数, 我们怎么样修改springboot内置的tomcat参数,本文就详细的来介绍一下,感兴趣的可以了解一下
    2023-09-09
  • 详解java中接口与抽象类的区别

    详解java中接口与抽象类的区别

    这篇文章主要介绍了详解java中接口与抽象类的区别的相关资料,希望通过本文能帮助到大家,让大家轻松理解掌握接口与抽象类的区别,需要的朋友可以参考下
    2017-10-10
  • Java实战之小米交易商城系统的实现

    Java实战之小米交易商城系统的实现

    这篇文章将利用Java实现小米交易商城系统,文中采用的技术有:JSP 、Spring、SpringMVC、MyBatis等,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-04-04
  • Maven打包所有依赖到一个可执行jar中遇到的问题

    Maven打包所有依赖到一个可执行jar中遇到的问题

    这篇文章主要给大家介绍了关于Maven打包所有依赖到一个可执行jar中遇到的问题,将依赖打入jar包,由于maven管理了所有的依赖,所以将项目的代码和依赖打成一个包对它来说是顺理成章的功能,需要的朋友可以参考下
    2023-10-10
  • Mybatis-config.xml中映射Mapper.xml文件遇到的错误及解决

    Mybatis-config.xml中映射Mapper.xml文件遇到的错误及解决

    这篇文章主要介绍了Mybatis-config.xml中映射Mapper.xml文件遇到的错误及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • java读取其他服务接口返回的json数据示例代码

    java读取其他服务接口返回的json数据示例代码

    这篇文章主要给大家介绍了关于java读取其他服务接口返回的json数据的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-03-03
  • SpringBoot Security权限控制自定义failureHandler实例

    SpringBoot Security权限控制自定义failureHandler实例

    这篇文章主要为大家介绍了SpringBoot Security权限控制自定义failureHandler实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • Java实现的迷宫游戏

    Java实现的迷宫游戏

    这篇文章主要介绍了如何用Java实现一个迷宫游戏,本仓库代码是经过eclipse编译运行过的,一般情况下将本仓库代码下载下来之后,使用eclipse编译直接可以运行。
    2021-04-04
  • spring声明式事务@Transactional开发常犯的几个错误及最新解决方案

    spring声明式事务@Transactional开发常犯的几个错误及最新解决方案

    使用声明式事务@Transactional进行事务一致性的管理,在开发过程中,发现很多开发同学都用错了spring声明式事务@Transactional或使用不规范,导致出现各种事务问题,这篇文章主要介绍了spring声明式事务@Transactional开发常犯的几个错误及解决办法,需要的朋友可以参考下
    2024-02-02

最新评论