Invalid bound statement (not found)

2023-05-16

目录

一、遇到的问题

二、分析思路

1、映射文件

2、测试类

三、解决方案


一、遇到的问题

前几日,有个工作不久的同事找我帮他解决一个 Mybatis 的问题。他写了一个增删改查,但是在启动程序的时候报错:Invalid bound statement (not found) 。他试图解决该异常,花了一个小时还是没有解决,所以向我求助。所谓当局者迷,我帮他梳理了一下开发逻辑,几分钟后他发现了问题,并解决了该异常。刚工作两三年的开发者特别容易碰到该异常,但是只要理清思路,就很容解决问题。我将分析问题的思路记录一下,希望能帮到你。

二、分析思路

Mybatis 开发有两种方式,一种是原始 Dao 开发方式,另一种是 Mapper 动态代理开发方式。在开发项目时,我们会用 Mapper 动态代理开发方式,动态代理会自动帮我们生成 Mapper 的代理类,将细节封装起来。但是,在分析问题的时候,我们用原始 Dao 开发方式,可以让我们了解到 statement 绑定映射文件的细节。

下面使用原始 Dao 的开发方式演示一下 statement 是如何绑定映射文件中的 Sql 语句的。

1、映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.test.mapper.UserMapper">
        <!-- 查询所有的用户名 -->
    <select id="findUserNameList" resultType="java.lang.String">
        select user_name userName from user
    </select>
</mapper>

2、测试类

public class Test {

    //会话工厂
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void createSqlSessionFactory() throws IOException {
        // 配置文件
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);

        // 使用SqlSessionFactoryBuilder从xml配置文件中创建SqlSessionFactory
        sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(inputStream);

    }

    // 查询所有的用户名
    @Test
    public void testFindUserNameById() {
        // 数据库会话实例
        SqlSession sqlSession = null;
        try {
            // 创建数据库会话实例sqlSession
            sqlSession = sqlSessionFactory.openSession();
            // 查询所有的用户名
            List<String> list = sqlSession.selectList("com.test.mapper.UserMapper.findUserNameById");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }

    }
}

在上面的测试中,使用了 sqlSession 的 selectList 方法,中间的参数就是 statement 。该参数用来确定映射文件中的 Sql 语句,换句话说就是用这个 statement 绑定映射文件中的 Sql 语句。

该参数是用映射文件中的 namespace 和 select 标签的 id 组合而成的,在项目是唯一的。示例中映射文件的 namespace 是:com.test.mapper.UserMapper,select 标签的 id 是:indUserNameById ,所以组合起来的 statement 是 com.test.mapper.UserMapper.findUserNameById

如果 statement 写错了,就会导致找不到映射文件中的 Sql 语句,就会报 Invalid bound statement (not found) 。所以造成该异常的原因是 statement 和 Sql 语句不匹配。

在实际项目会使用 Mapper 动态代理的开发方式,自动生成 mapper 接口的实现类,就更容易出现该异常了。

三、解决方案

既然知道了造成该异常的原因,就容易解决了,如果通过 statement 找不到映射文件中的 Sql 就会报错误:Invalid bound statement (not found) 。在项目中一般都是使用 Mapper 动态代理,所以我们要解决的也是动态代理的问题。先说一下 Mapper 动态代理的实现原理,看完之后你就知道应该怎么解决该异常了。

Mapper 动态代理只需要开发定义 Mapper 接口,Mybatis 会根据接口创建动态代理对象。使用该种方式开发,需要遵守一定的开发规范,规范如下 4 点:

  1. Mapper.xml 文件中的 namespace 与 mapper 接口的类路径相同。
  2. Mapper 接口方法名和 Mapper.xml 中定义的每个 statement 的 id 相同
  3. Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 Sql 的 parameterType 的类型相同
  4. Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 Sql 的 resultType 的类型相同 

所以,我们在使用 Mapper 动态代理遇到该异常,就是要检查是否遵守开发规范,因为粗心或单词写错了,容易导致程序报错。

我列了几个检查步骤,你跟着步骤检查一下,肯定能找到问题的所在之处。步骤如下 7 点:

  1. 检查 target 目录中有没有 Mybatis 的映射文件
  2. 检查 mybatis.mapper-locations 配置,该配置是把 mapper 的位置告诉 Mybatis 。默认是mapper-locations: classpath*:/mapper/**/*.xml
  3. 检查映射文件是不是放在 resources/mapper 目录中
  4. 检查映射文件中的 namespace 与 mapper 接口的类路径是不是一样
  5. 检查映射文件中的 statement 是不是和 Mapper 接口的方法名一样
  6. 检查映射文件中的 statement 的 parameterType 和 resultType 是不是和 Mapper 接口的方法中的入参和出参一样
  7. 如果你使用 Idea 开发,检查一下 resources 目录,在该目录下创建下级目录是不能一次性创建的,要创建完成一个目录后再创建另外的下级目录

另外,如果你遇到过该异常,并且遇到的错误不在上述之中。不妨在留言区提出,大家一起讨论一下,给后来者提个醒,避免遇到坑。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Invalid bound statement (not found) 的相关文章

随机推荐

  • python取文本中含有指定关键词的行

    python取文本中含有指定关键词的行 脚本内容 xff1a f 61 open 39 home py 9 txt 39 39 r 39 lines 61 f readlines for lines in lines if 34 EIPId
  • VSCode 快捷键

    VsCode可以通过以下快捷键 格式化代码 xff1a On Windows Shift 43 Alt 43 F 巨好用 xff01 有木有 xff01 QAQ xff09 On Mac Shift 43 Option 43 F 1 向上
  • 查看容器暴露的端口

    docker ps 查看运行中的容器 docker port c5b 查看容器c5b的端口状态 27017是容器端口 xff1b 0 0 0 0 37017是27017映射到宿主机上的端口
  • python元组实例

    脚本 xff1a usr bin python coding utf 8 names 61 34 kevin 34 34 liqunxing 34 34 chenxianan 34 print names 0 names 1 names 2
  • 机房温度告警

    https blog csdn net ot512csdn article details 80175323
  • k8s部署教程

    https mp weixin qq com s biz 61 MzI5MjA5Mjg5OA 61 61 amp mid 61 2247484395 amp idx 61 1 amp sn 61 0767cc24ec99ce818e41f7
  • Win10笔记本用雷电3接口外接显卡加速tensorflow深度学习步骤

    简介 xff1a 最近入手了一块rtx3060 xff0c 但自己的主力设备是笔记本 xff0c 于是萌生了通过外接显卡来加速深度学习的想法 xff0c 配置过程中遇到一些小问题 xff0c 经过调试最后解决了 xff0c 现在简单把整个过
  • 使用GitHub和DockerHub自动构建并发布镜像

    要使用自动构建 xff0c 必须在 Docker Hub 和GitHub上拥有一个帐户 首先登录您的Docker Hub账号 xff0c 创建一个Repository xff0c 创建类似如下页面 点击创建的Repository xff0c
  • 三 机器人仿真软件Gazebo介绍

    ROS教程 这是小弟的学习笔记 xff0c 有错求请拍 xff0c 多指教 xff0c 谢谢 三 机器人仿真软件Gazebo介绍 Gazebo功能 1 构建机器人运动仿真模型 在Gazebo里 xff0c 提供了最基础的三个物体 xff0c
  • Protobuf生成Go代码指南

    这个教程中将会描述protocol buffer编译器通过给定的 proto会编译生成什么Go代码 教程针对的是proto3版本的protobuf 在阅读之前确保你已经阅读过Protobuf语言指南 编译器调用 Protobuf核心的工具集
  • ROS sensor_msgs/LaserScan Message简单说明

    std msgs Header header float32 angle min 开始扫描角度 float32 angle max 结束扫描角度 float32 angle increment 每次扫描增加的角度 xff08 角度分辨率 x
  • 双系统Ubuntu分区

    假设整个空闲空间有200G xff0c 主要分4个区 xff1a 1 给系统分区EFI xff1a 在唯一的一个空闲分区上添加 xff0c 大小200M xff0c 逻辑分区 xff0c 空间起始位置 xff0c 用于efi xff1b 这
  • 2 用D435i运行VINS-fusion

    文章目录 1 VINS fusion的安装1 1 环境和依赖的安装1 2 编译VINS Fusion1 3 编译错误解决方法 2 VINS Fusion跑数据集3 用相机运行VINS Fusion 环境 xff1a Ubuntu20 04
  • Python每日一个小程序

    前几天上网 xff0c 收集了20多道Python练习题 这些练习题还是很有价值的 xff0c 正好最近忙着复习准备校招 xff0c 可以用来练手 我会把每道题都写一篇博客详细阐述解题思路和源代码 xff0c 在每道题目后面附上博客地址 希
  • 数分下(第1讲):一阶微分方程的三类模型求解

    第1 1讲 xff1a 一阶微分方程的解法 第一周第一讲将用3个小时时间 xff0c 完整讲解一阶微分方程y 61 f x y 的三种典型模型求解方法 掌握以下知识点 xff0c 并熟练做题训练 对应同济高数教材第七章1 4节 知识点脑图如
  • 非常详细的 Linux C/C++ 学习路线总结!助我拿下腾讯offer

    点击关注上方 五分钟学算法 xff0c 设为 置顶或星标 xff0c 第一时间送达干货 转自后端技术学堂 正文 我的另一篇文章 腾讯 C 43 43 后台开发面试笔试知识点参考笔记 整理了 C 43 43 后台开发知识点 xff0c 本文尝
  • 一线互联网公司程序员技术面试的流程以及注意事项

    先来了解面试的流程是什么 xff0c 然后再一一做准备 xff01 企业一般通过几轮技术面试来考察大家的各项能力 xff0c 一般流程如下 xff1a 一面机试 xff1a 一般会考选择题和编程题 二面基础算法面 xff1a 就是基础的算法
  • 为什么C++永不过时?

    Linus曾说过 xff1a C 43 43 是一门很恐怖的语言 xff0c 而比它更恐怖的是很多不合格的程序员在使用着它 xff01 这足以说明C 43 43 有多难 xff01 不过 xff0c 你也要明白 难度越高意味着含金量与竞争力
  • STM32 USB学习笔记6

    主机环境 xff1a Windows 7 SP1 开发环境 xff1a MDK5 14 目标板 xff1a STM32F103C8T6 开发库 xff1a STM32F1Cube库和STM32 USB Device Library 现在来分
  • Invalid bound statement (not found)

    目录 一 遇到的问题 二 分析思路 1 映射文件 2 测试类 三 解决方案 一 遇到的问题 前几日 xff0c 有个工作不久的同事找我帮他解决一个 Mybatis 的问题 他写了一个增删改查 xff0c 但是在启动程序的时候报错 xff1a