• [Java] [Spring boot] Mybatis generator 生成Mapper.xml无效的问题


    报错:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):
    百度出来的解决方案:
    1:Mapper.xml中的namespace不对应和mapper接口不对应

    2:Mapper.xml中的方法(即id)和mapper接口中的方法名字不同或对应的方法不存在

    3:返回类型不匹配(即没有正确配置ResultMap或者ResultType)

    4:可能xml文件有缓存或者修改后没保存

    5:可能没有配置MapperScan导致dao方法没有被扫描注入

    6:配置文件中mybatis.mapper-locations或mybatis.typeAliasesPackage配置不正确
    不管用

    背景介绍

    我是把Mybatis generator集成到自己的项目中
    在这里插入图片描述
    generator.xml配置

    
    DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    <generatorConfiguration>
    
        
        <context id="DB2Tables" targetRuntime="MyBatis3">
            
            <plugin type="com.mybatis.plugin.MysqlPaginationPlugin" />
            <commentGenerator>
                <property name="suppressAllComments" value="true" />
            commentGenerator>
            
            <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                            connectionURL="jdbc:mysql://127.0.0.1:3306/quick_project?characterEncoding=utf8&useSSL=false"
                            userId="root" password="123456">
                <property name="useInformationSchema" value="true"/>
                <property name="nullCatalogMeansCurrent" value="true" />
            jdbcConnection>
    
            <javaTypeResolver>
                <property name="forceBigDecimals" value="false" />
            javaTypeResolver>
            
            <javaModelGenerator targetPackage="com.quick.user.model" targetProject="src/main/java">
                <property name="enableSubPackages" value="true" />
                <property name="trimStrings" value="true" />
            javaModelGenerator>
            
            <sqlMapGenerator targetPackage="mybatis" targetProject="src/main/resources">
                <property name="enableSubPackages" value="true" />
            sqlMapGenerator>
            
            <javaClientGenerator type="XMLMAPPER" targetPackage="com.quick.user.mapper" targetProject="src/main/java">
                <property name="enableSubPackages" value="true" />
            javaClientGenerator>
            
            <table tableName="user" domainObjectName="User"
                   enableCountByExample="true"
                   enableUpdateByExample="true"
                   enableDeleteByExample="true"
                   enableSelectByExample="true"
                   selectByExampleQueryId="true"
                   enableSelectByPrimaryKey="true"
                   enableUpdateByPrimaryKey="true"
                   enableDeleteByPrimaryKey="true"
                   selectByPrimaryKeyQueryId="true" >
                <columnOverride column="xx" javaType="java.lang.String" jdbcType="VARCHAR" />
            table>
        context>
    generatorConfiguration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    特别注意下上述配置的插件com.mybatis.plugin.MysqlPaginationPlugin
    这是我自己本地重写的分页插件jar包。
    以下是配置的pom

     <build>
            <finalName>user-servicefinalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-maven-pluginartifactId>
                plugin>
                <plugin>
                    <groupId>org.mybatis.generatorgroupId>
                    <artifactId>mybatis-generator-maven-pluginartifactId>
                    <version>1.3.2version>
                    <configuration>
                        <configurationFile>
                            src/main/resources/generator.xml
                        configurationFile>
                        <verbose>trueverbose>
                        <overwrite>trueoverwrite>
                    configuration>
                    <dependencies>
                        <dependency>
                            <groupId>com.mybatisplugingroupId>
                            <artifactId>generator-mysql-plugin-pageartifactId>
                            <version>1.0version>
                        dependency>
                        <dependency>
                            <groupId>mysqlgroupId>
                            <artifactId>mysql-connector-javaartifactId>
                            <version>8.0.13version>
                        dependency>
                    dependencies>
                plugin>
            plugins>
    
        build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    项目整合

    我使用的nacos配置的yaml文件

    spring:
    #数据库配置
      datasource:
        druid:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/quick_project?useUnicode=true&characterEncoding=utf-8&useSSL=false
          username: root
          password: 123456
          filters: config
    
    #设置日志级别,ERROR/WARN/INFO/DEBUG,默认是INFO以上才显示
    logging:
      level:
        root: INFO
    
    mybatis:
      mapper-locations: classpath:mybatis/*.xml
      type-aliases-package: com.quick.user.model
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    问题分析

    以上的都配置好了,而且给种网上提出的问题都已经检查过,但是还是报错org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):

    调试

    打断点在问题逻辑处
    找到MapperMethod.SqlCommand方法

    public SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method) {
          final String methodName = method.getName();
          final Class<?> declaringClass = method.getDeclaringClass();
          MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, declaringClass,
              configuration);
          if (ms == null) {
            if (method.getAnnotation(Flush.class) != null) {
              name = null;
              type = SqlCommandType.FLUSH;
            } else {
              throw new BindingException("Invalid bound statement (not found): "
                  + mapperInterface.getName() + "." + methodName);
            }
          } else {
            name = ms.getId();
            type = ms.getSqlCommandType();
            if (type == SqlCommandType.UNKNOWN) {
              throw new BindingException("Unknown execution method for: " + name);
            }
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    通过调试分析,得出问题出在ms==null这一块上面。接下来继续分析MapperMethod.resolveMappedStatement这个方法

    private MappedStatement resolveMappedStatement(Class<?> mapperInterface, String methodName,
            Class<?> declaringClass, Configuration configuration) {
          String statementId = mapperInterface.getName() + "." + methodName;
          if (configuration.hasStatement(statementId)) {
            return configuration.getMappedStatement(statementId);
          } else if (mapperInterface.equals(declaringClass)) {
            return null;
          }
          for (Class<?> superInterface : mapperInterface.getInterfaces()) {
            if (declaringClass.isAssignableFrom(superInterface)) {
              MappedStatement ms = resolveMappedStatement(superInterface, methodName,
                  declaringClass, configuration);
              if (ms != null) {
                return ms;
              }
            }
          }
          return null;
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    其中configuration.hasStatement(statementId)会判断有没有这个sql对应的方法。分析发现,org.apache.ibatis.session.Configuration方法中的属性 mappedStatements 为空。
    那么为什么mappedStatements为空呢,我怀疑mybatis.mapper-locations属性没有被正确加载解析,导致无法正确的找到每个接口方法对应的sql。
    而且我这边也没有相关的重写sqlSessionFactory这个方法。
    此时应该想到自己写了分页插件包可能导致引包冲突的问题。

    结果

    针对以上分析原因大概率得出包冲突造成的。因此在pom的build去掉自己本地插件包generator-mysql-plugin-page
    最终的pom

    <build>
            <finalName>user-servicefinalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-maven-pluginartifactId>
                plugin>
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
            plugins>
    
        build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    搞定Mapper.xml无效问题

  • 相关阅读:
    JavaScript单例模式
    WPF 制作 Windows 屏保
    UI设计师的工作职责 优漫动游
    Python爬虫-使用代理伪装IP
    计算机毕业设计JAVA百姓点评网的设计与实现mybatis+源码+调试部署+系统+数据库+lw
    【C++】模板进阶
    记录上百页html生成pdf的历程和坑(已用bookjs-easy解决)(生成、拼接pdf、接收服务端pdf)
    NEFU算法设计与分析课程设计
    ES6和ES5的区别
    4.0体验站|我对OceanBase 4.0社区版的体验与看法
  • 原文地址:https://blog.csdn.net/qq_27695659/article/details/127930441