zoukankan      html  css  js  c++  java
  • 引入mybatis-plus报 Invalid bound statement错误怎么办,动动手指改一个地方就行

    错误

    Mybatis-Plus (简称MP) 是mybatis的一个增强工具,在mybatis的基础上只做增强不做改变,简化了开发效率。其实就是帮我们封装了一些简单的curd方法,可以直接调用,不必再重写这些简单的sql语句,类似JPA那样。

    前两天创建了一个新项目,持久层框架用的是mybatis,同时引入mybatis-plus做增强工具,项目启动后,调用接口却发现报错了,报错的提醒如下:

    错误的信息显示的是 “无效的绑定语句“,报错的地方正是操作sql语句的方法,从网上查了一下答案,该错误主要是数据源绑定的配置问题,于是我顺腾摸瓜,从配置数据源的地方下手。

    查找原因

    因为项目是做了多数据源的读写分离,所以我把数据源的动态配置整合到了一个类DataSourceConfig中,这是该类的代码:

    @Configuration
    @MapperScan(basePackages = "com.xjt.proxy.mapper", sqlSessionTemplateRef = "sqlTemplate")
    public class DataSourceConfig {
        /**
         * 主库
         */
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource.master")
        public DataSource masterDb() {
            return DruidDataSourceBuilder.create().build();
        }
    
        /**
         * 从库
         */
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource.slave")
        public DataSource slaveDb() {
            return DruidDataSourceBuilder.create().build();
        }
    
        /**
         * 主从动态配置
         */
        @Bean
        public DynamicDataSource dynamicDb(@Qualifier("masterDb") DataSource masterDataSource,
                                           @Autowired(required = false) @Qualifier("slaveDb") DataSource slaveDataSource) {
            DynamicDataSource dynamicDataSource = new DynamicDataSource();
            Map<Object, Object> targetDataSources = new HashMap<>();
            targetDataSources.put(DynamicDataSourceEnum.MASTER.getDataSourceName(), masterDataSource);
            if (slaveDataSource != null) {
                targetDataSources.put(DynamicDataSourceEnum.SLAVE.getDataSourceName(), slaveDataSource);
            }
            dynamicDataSource.setTargetDataSources(targetDataSources);
            dynamicDataSource.setDefaultTargetDataSource(masterDataSource);
            return dynamicDataSource;
        }
    
        @Bean
        public SqlSessionFactory sessionFactory(@Qualifier("dynamicDb") DataSource dynamicDataSource) throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setMapperLocations(
                    new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*Mapper.xml"));
            bean.setDataSource(dynamicDataSource);
            return bean.getObject();
        }
    
        @Bean
        public SqlSessionTemplate sqlTemplate(@Qualifier("sessionFactory") SqlSessionFactory sqlSessionFactory) {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    
        @Bean(name = "dataSourceTx")
        public DataSourceTransactionManager dataSourceTx(@Qualifier("dynamicDb") DataSource dynamicDataSource) {
            DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
            dataSourceTransactionManager.setDataSource(dynamicDataSource);
            return dataSourceTransactionManager;
        }
    }
    
    

    内容没什么复杂的,主要是对主从库的数据源配置映射,以及把数据源注入SqlSessionFactory对象中,如果对该部分代码或者读写分离比较疑惑的话,可以看我之前的文章《读写分离很难吗?springboot结合aop简单就实现了》

    主从库映射数据源没什么异议,想来想去应该是注入那一步有问题,然后就把目光放到了sessionFactory方法上,该方法主要是返回一个SqlSessionFactory对象,该对象是由通过新建一个SqlSessionFactoryBean对象并注入数据源后返回的,问题应该是出在这个SqlSessionFactoryBean类上,后来,经平哥(我旁边的大佬)提醒后,这里应该要换成mybatis-plus中另一个Bean工厂类,叫做MybatisSqlSessionFactoryBean,点开该类的源码,才发现该类正是拷贝了SqlSessionFactoryBean,并且重写了自己的自定义加载方法buildSqlSessionFactory

    跳转到该方法的源码中,发现其中有一段代码比较重要,配置中少了这一步就会注入失败,

    改动

    也就是说,注入数据源的地方还需要配置mapper的扫描路径,如此一来,改动的地方也比较明确了,就是注入数据源的地方把 SqlSessionFactoryBean 改成 MybatisSqlSessionFactoryBean 后,并配置mapper文件对应的路径,也就是把sessionFactory方法改成如下代码:

    @Bean
        public SqlSessionFactory sessionFactory(@Qualifier("dynamicDb") DataSource dynamicDataSource) throws Exception {
            MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dynamicDataSource);
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();        sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:mapper/*Mapper.xml"));
            return sqlSessionFactoryBean.getObject();
        }
    

    这样一来,再次启动项目就可以正常操作sql语句了。

  • 相关阅读:
    【转】css解决兼容的问题
    【转】.NET完美实现伪静态页面,URLRewriter.dll下载
    【技术贴】网站首页浏览量统计代码,适合.NET||网页浏览量计数器代码
    js过滤空格回车
    男人帮所有手机铃声下载|左永邦手机铃声下载,顾小白手机铃声下载,米琪手机铃声下载,艾米手机铃声下载
    孙红雷男人帮全集迅雷下载
    【技术帖】Mysql The 'InnoDB' feature is disabled; you n
    周杰伦2011所有歌曲完整版无删节全正版打包免费下载 http://115.com/file/bhr
    红警95 3D重置版 下载地址|3D95红警下载地址
    周杰伦2011所有歌曲完整版无删节全正版打包免费下载 http://115.com/file/bhr
  • 原文地址:https://www.cnblogs.com/yeya/p/12978657.html
Copyright © 2011-2022 走看看