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

作者:鄙人薛某 时间:2021-06-01 14:28:00 

错误

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

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

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

错误的信息显示的是 “无效的绑定语句“,报错的地方正是操作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

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

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

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

改动

也就是说,注入数据源的地方还需要配置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语句了。

来源:https://www.cnblogs.com/yeya/p/12978657.html

标签:Mybatis,plus,Invalid,bound,statement
0
投稿

猜你喜欢

  • JAVA通过Filter实现允许服务跨域请求的方法

    2022-08-02 02:17:46
  • Java线程让步_动力节点Java学院整理

    2021-07-21 14:44:52
  • 基于jQuery获取table数据发送到后端

    2023-07-22 22:07:43
  • java开发RocketMQ之NameServer路由管理源码分析

    2023-10-27 20:56:12
  • java9新特性Collection集合类的增强与优化方法示例

    2023-01-29 05:16:57
  • Java 获取当前系统时间的三种方法

    2023-11-21 12:51:51
  • Java语言多线程终止中的守护线程实例

    2023-11-25 07:48:52
  • 利用Lambda表达式创建新线程案例

    2023-08-26 23:16:00
  • Spring Boot整合Mybatis并完成CRUD操作的实现示例

    2023-11-09 04:36:46
  • Java实现常用缓存淘汰算法:FIFO、LRU、LFU

    2022-08-26 21:45:19
  • Java Synchronized锁失败案例及解决方案

    2023-10-25 12:33:47
  • spring cloud gateway如何获取请求的真实地址

    2023-11-28 20:20:12
  • Java关键字instanceof用法及实现策略

    2023-09-23 06:05:38
  • Java开发环境jdk 1.8安装配置方法(Win7 64位系统/windows server 2008)

    2022-05-11 20:00:58
  • Java 反射类型Type的用法说明

    2023-01-23 04:15:44
  • Java自定义实现链队列详解

    2023-06-22 12:47:31
  • Java8 Lambda表达式详解及实例

    2023-02-06 20:59:15
  • Android客户端与服务端数据加密传输方案详解

    2023-07-14 13:55:37
  • Java基于深度优先遍历的随机迷宫生成算法

    2022-06-01 22:18:50
  • Java特性队列和栈的堵塞原理解析

    2023-10-13 14:15:55
  • asp之家 软件编程 m.aspxhome.com