返回顶部
首页 > 资讯 > 后端开发 > JAVA >Invalid bound statement (not found)
  • 120
分享到

Invalid bound statement (not found)

mybatisjava数据库statement 2023-10-09 12:10:36 120人浏览 独家记忆
摘要

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

目录

一、遇到的问题

二、分析思路

1、映射文件

2、测试类

三、解决方案


一、遇到的问题

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

二、分析思路

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

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

1、映射文件

                    select user_name userName from user    

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 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 目录,在该目录下创建下级目录是不能一次性创建的,要创建完成一个目录后再创建另外的下级目录

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

来源地址:https://blog.csdn.net/keyboard_/article/details/127830039

--结束END--

本文标题: Invalid bound statement (not found)

本文链接: https://lsjlt.com/news/426292.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作