引入mybatis-plus报 Invalid bound statement错误问题的解决方法

 更新时间:2020年05月29日 15:28:19   作者:鄙人薛某  
这篇文章主要介绍了引入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语句了。

总结

到此这篇关于引入mybatis-plus报 Invalid bound statement错误问题的解决方法的文章就介绍到这了,更多相关Mybatis plus Invalid bound statement内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java实现简单银行家算法

    java实现简单银行家算法

    这篇文章主要为大家详细介绍了java实现简单银行家算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • Java字符串替换的三种方法实际应用

    Java字符串替换的三种方法实际应用

    这篇文章主要给大家介绍了关于Java字符串替换的三种方法,replace和replaceAll是JAVA中常用的替换字符的方法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • Java中Buffer缓冲区的ByteBuffer类详解

    Java中Buffer缓冲区的ByteBuffer类详解

    这篇文章主要介绍了Java中Buffer缓冲区的ByteBuffer类详解,ByteBuffer类是Java NIO库中的一个重要类,用于处理字节数据,它提供了一种灵活的方式来读取、写入和操作字节数据,ByteBuffer类是一个抽象类,可以通过静态方法创建不同类型的ByteBuffer对象,需要的朋友可以参考下
    2023-10-10
  • Spring Cloud学习教程之DiscoveryClient的深入探究

    Spring Cloud学习教程之DiscoveryClient的深入探究

    这篇文章主要给大家介绍了关于Spring Cloud学习教程之DiscoveryClient的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-04-04
  • Java实现单链表SingleLinkedList增删改查及反转 逆序等

    Java实现单链表SingleLinkedList增删改查及反转 逆序等

    单链表是链表的其中一种基本结构。一个最简单的结点结构如图所示,它是构成单链表的基本结点结构。在结点中数据域用来存储数据元素,指针域用于指向下一个具有相同结构的结点。 因为只有一个指针结点,称为单链表
    2021-10-10
  • 浅析Spring配置中的classpath:与classpath*:的区别

    浅析Spring配置中的classpath:与classpath*:的区别

    这篇文章主要介绍了Spring配置中的"classpath:"与"classpath*:"的区别,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • Java定时器例子_动力节点Java学院整理

    Java定时器例子_动力节点Java学院整理

    本文给大家分享了java定时器例子,非常不错,具有参考借鉴价值,需要的的朋友参考下吧
    2017-05-05
  • JAVA一个快速排序实现代码

    JAVA一个快速排序实现代码

    排序有哪几种方法?请列举。并用JAVA实现一个快速排序.,需要的朋友可以参考下
    2017-02-02
  • 关于SpringBoot中controller参数校验的使用

    关于SpringBoot中controller参数校验的使用

    本文主要介绍了关于SpringBoot中controller参数校验的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • Sentinel核心类之Entry类解读

    Sentinel核心类之Entry类解读

    这篇文章主要介绍了Sentinel核心类之Entry类解读,Sentinel中Entry可以理解为每次进入资源的一个凭证,如果调用SphO.entry()或者SphU.entry()能获取Entry对象,代表获取了凭证,没有被限流,否则抛出一个BlockException,需要的朋友可以参考下
    2023-12-12

最新评论