java_Springboot_Mybatis-Plus_自定义多数据源MybatisSqlSessionFactoryBean配置

这篇具有很好参考价值的文章主要介绍了java_Springboot_Mybatis-Plus_自定义多数据源MybatisSqlSessionFactoryBean配置。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

java_Springboot_Mybatis-Plus_自定义多数据源MybatisSqlSessionFactoryBean配置方法

一、引言

需要在服务中集成表结构维护的功能,维护表结构就需要使用具有执行DDL脚本权限的账号。
为了保证系统的安全性,考虑在工程中配置多个数据源引入不同权限账号,高权限账号只在特定逻辑中使用,其它默认业务使用低权限账号。
加入新的数据源不能影响已有的功能,保证已有功能继续使用只具有CRUD权限的账号。
看了几个多数据源接入方案,都不太满足需求。

  • Springboot默认支持的多数据源
  • Mybatis-Plus的多数据源既动态数据源dynamic-datasource插件
  • Alibaba Druid动态数据源

二、环境

  • JDK 1.0
  • SpringBoot 1.5.6
  • Mybaits 3.5.3
  • Mybatis-plus 3.3.1

三、集成过程中遇到的问题

3.1 Invalid bound statement (not found) 错误

由于系统中调用了Mybatis-plus的BaseMapper中的扩展方法selectBatchIds(),
调用selectBatchIds()方法的位置都报:Invalid bound statement (not found) 错误。
一般遇到这种问题基本都是接口中定义的方法名在对应的XML文件中没有定义。
但是现在使用的是com.baomidou.mybatisplus.core.mapper.BaseMapper中的扩展方法,不需要在XML中定义的!
问题产生原因是没有使用Mybatis-Plust自定义的MybatisSqlSessionFactoryBean构建 SqlSessionFactory实例导致,
改用后解决了Invalid bound statement (not found)的问题。

    @Bean(name = "defSqlSessionFactory")
    @Primary
    public SqlSessionFactory defSqlSessionFactory(@Qualifier("defDataSource") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        //SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //设置mybatis的xml所在位置
        Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:com/.../mapper/**/*Mapper.xml");
        bean.setMapperLocations(resources);
        SqlSessionFactory factory = bean.getObject();
        return factory;
    }

3.2 默认数据源问题

配置多个数据源时,必须明确声明DataSource、SqlSessionFactory、PlatformTransactionManager、SqlSessionTemplate关键对象!
在默认的Bean上加@Primary注解,标记为默认配置。以下为同一数据源的Bean配置,多个数据源需要加入多套配置。

@Configuration
public class DbDefaultConfig {

    @Bean(name = "defDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource defDataSource() {
        DataSource datasource =  DataSourceBuilder.create().build();
        return datasource;
    }

    @Bean(name = "defSqlSessionFactory")
    @Primary
    public SqlSessionFactory defSqlSessionFactory(@Qualifier("defDataSource") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        //SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //设置mybatis的xml所在位置
        Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:com/.../mapper/**/*Mapper.xml");
        bean.setMapperLocations(resources);
        SqlSessionFactory factory = bean.getObject();
        return factory;
    }

    /**
     * JDBC事务管理器
     * @param dataSource
     * @return
     */
    @Bean("defTransactionManager")
    @Primary
    public PlatformTransactionManager txManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "defSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate defSqlSessionTemplate(@Qualifier("defSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
        return sqlSessionTemplate;
    }
}

3.3 Mybatis-Puls分页组件失效问题

使用com.baomidou.mybatisplus.extension.plugins.pagination.Page插件做分页查询时,发现返回的total、pages两个关键的分页属性值都是0,明显分页插件没有生效。

{
    "records": [
        ...
    ],
    "total": 0, --!!!
    "size": 10,
    "current": 1,
    "orders": [],
    "hitCount": false,
    "searchCount": true,
    "pages": 0  --!!!
}

分页组件是基于拦截器com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor实现的,该拦截器对StatementHandler的实例方法prepare进行拦截,对total、pages属性赋值,实现的分页查询功能。问题产生原因是由于手动实现了多个SqlSessionFactory实例,但是实例中没有手动注入拦截器导致的问题。解决方法是:

1.声明一个分页拦截器;

@Configuration
public class MybatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDbType(DbType.POSTGRE_SQL); //这里指明数据库类型
        return page;
    }
}

2.将拦截器添加到SqlSessionFactory实例中;


@Configuration
public class MybatisConfig {
    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;
    @Autowired
    private PaginationInterceptor paginationInterceptor;

    @PostConstruct
    public void addSqlInterceptor() {
        SchemaParamsterInterceptor interceptor = new SchemaParamsterInterceptor();
        for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
            //mybaits分页拦截器
            sqlSessionFactory.getConfiguration().addInterceptor(paginationInterceptor);
            ...
        }
    }
}

四、测试数据源是否正确

@RunWith(SpringRunner.class)
//@Transactional
@SpringBootTest(classes = StartApplication.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
@ActiveProfiles("")
public class MultiDatasourceTest {
    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;

    @Before
    public void before(){
    }
    @Test
    public void datasourceTest(){
        System.out.println("sqlSessionFactoryList Size = " + sqlSessionFactoryList.size());
        boolean success = true;
        for(SqlSessionFactory f:sqlSessionFactoryList ){
            System.out.println("【工厂】:"+f.toString());
            try {
                datasourceTest(f);
                System.out.println("成功!!!");
            }catch (Exception ex){
                System.out.println("异常:"+ex.toString());
                if(success)
                    success = false;
            }
        }
        Assert.assertTrue("存在不支持的查询!",success);
    }

    private boolean datasourceTest(SqlSessionFactory factory){
        MyTestMapper mapper = factory.openSession(true).getMapper(MyTestMapper.class);
        //xml中的方法
        Object objPk = mapper.selectByPrimaryKey("111");
        //mybatis-plus BaseMapper 中的扩展方法(使用前必须在对象上加 @TableName,pk字段上加@TableId注解)
        Object objIds = mapper.selectBatchIds(Arrays.asList("1","2"));

        return true;
    }
}

五、总结

构建SqlSessionFactory必须使用MybatisPlust实现的MybatisSqlSessionFactoryBean对象。
项目引入Mybatis-Puls依赖包后,会自动化注入一个SqlSessionFactory实例(详见:com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration#sqlSessionFactory()方法),这个实例注入是有条件的,即只在没有SqlSessionFactory实例时注入,使用@ConditionalOnMissingBean注解做的约束。
梳理了一下Mapper实例的构建过程,发现调用的扩展方法必须继承BaseMapper类,Mapper实例又是通过SqlSessionFactory实例创建的,
大概率Mapper扩展方法绑定在MybatisSqlSessionFactoryBean的实例方法bean.getObject()中实现的。文章来源地址https://www.toymoban.com/news/detail-794123.html

到了这里,关于java_Springboot_Mybatis-Plus_自定义多数据源MybatisSqlSessionFactoryBean配置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot整合Mybatis-Plus、Druid配置多数据源

    目录 1.初始化项目 1.1.初始化工程 1.2.添加依赖 1.3.配置yml文件 1.4.Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹 1.5.配置使用数据源 1.5.1.注解方式 1.5.2.基于AOP手动实现多数据源原生的方式 2.结果展示 Mybatis-Plus:简介 | MyBatis-Plus (baomidou.com) 在正式开始之前,先初始

    2024年02月11日
    浏览(35)
  • 【SpringBoot 3.x】整合Mybatis-Plus多数据源、Druid

    开发依赖 版本 Spring Boot 3.0.6 Mybatis-Plus 3.5.3.1 dynamic-datasource-spring-boot-starter 3.6.1 JDK 20 SpringBoot启动类修改 由于排除了DruidDataSourceAutoConfigure类的自动装载,就需要手工指定装配以下几个类 查看DruidDataSourceAutoConfigure这个类的源码可以看出,需要把@Import带进来的几个类进行自动装

    2024年02月04日
    浏览(39)
  • Dynamic DataSource 多数据源配置【 Springboot + DataSource + MyBatis Plus + Druid】

    MybatisPlus多数据源配置主要解决的是多数据库连接和切换的问题。在一些大型应用中,由于数据量的增长或者业务模块的增多,可能需要访问多个数据库。这时,就需要配置多个数据源。 2.1.1、引用依赖 2.1.2、application.yml 配置 2.1.3、通用配置类 2.1.4、使用方式 这里便不过多的

    2024年02月03日
    浏览(36)
  • SpringBoot+MyBatis-Plus多数据源@DS注解失效的解决方法

    引入 dynamic-datasource: application.yml 数据源配置: 详细使用请看 MyBatis-Plus官网 这种场景还是比较常见,比如在一个为master数据源的调用slave数据源就会失效 slave数据源Service方法 mater数据源Service方法调用slave数据源Service方法 这里会出现没有走slave_1,依然还是master数据源 需要在

    2024年01月18日
    浏览(43)
  • Springboot+mybatis-plus+dynamic-datasource+Druid 多数据源 分布式事务

    背景 处理多数据源事务一直是一个复杂而棘手的问题,通常我们有两种主流的解决方法。 第一种是通过Atomikos手动创建多数据源事务,这种方法更适合数据源数量较少,参数配置不复杂,对性能要求不高的项目。然而,这种方法的最大困难在于需要手动配置大量设置,这可能

    2024年02月11日
    浏览(29)
  • mybatis(plus)多数据源

         一个项目大部分都是单一数据库多一些,但是有时候会需要用多个库,所以这时候据需要使用多数据源。我这里使用springboot+mybatis(plus)+druid多数据源. 目前我知道有两种方式,一种方式是需要在service实现类上添加@DS,一种方式是通过配置的方式,配置不同的SqlSessionFac

    2024年02月06日
    浏览(33)
  • Mybatis-plus动态数据源

    由于服务没有做微服务部署,需要在后台管理系统访问其他服务的库,所以需要用到动态数据源切换 引入依赖 mybatis-plus动态数据源依赖 更改配置 配置类 添加注解 @DS注解我一般放在dao层,因为觉得这样更合理 启动测试 问题: 动态数据源切换时效 当服务层接口添加事务注解

    2024年04月12日
    浏览(37)
  • Spring Boot MyBatis Plus 配置数据源详解

    🎉欢迎来到架构设计专栏~Spring Boot MyBatis Plus 配置数据源详解 ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:架构设计 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技术和水平有限,如果文

    2024年01月21日
    浏览(47)
  • Mybatis-plus多数据源单元测试@MybatisPlusTest

    mybatis-plus多数据源单元测试报错 错误原因分析 多数据源,但是不能取到数据信息 解决方案 在注解中添加 @ImportAutoConfiguration(value = {RmasDataSourceConfig.class}, exclude = DataSourceAutoConfiguration.class) 注意事项 1.@Test添加以后,没有启动键,后来发现引入的包不对,必须引入 org.junit.jup

    2024年02月11日
    浏览(32)
  • 利用 Mybatis-Plus 的动态数据源实现多数据源配置

    目录 一、导入依赖 二、Application.yaml配置文件 三、切换数据源 四、其他方法 4.1 配置多个数据源 4.2 定义Datasource和EntityManager 4.3 在需要使用数据源的地方注入不同的EntityManager 官网:https://baomidou.com/pages/a61e1b/#dynamic-datasource 默认是使用配置文件中master参数设置的数据库。

    2024年02月13日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包