zoukankan      html  css  js  c++  java
  • mybatis源码分析——常见错误异常分析

    1:根据sqlId没有找到对应的MapperStatement,有可能是sql语句不存在、或者sqlId的名字和mapper方法中的名字对不上

    Exception in thread "main" org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.mybatis.mapper.UserMapper.listUsers
    	at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:196)
    	at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:44)
    	at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:59)
    	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)
    	at com.sun.proxy.$Proxy0.listUsers(Unknown Source)
    	at com.example.mybatis.TestMybatis.main(TestMybatis.java:27)
    

      

    从异常的栈信息中,可以看到调用listUsers方法,会调用到代理的invoke方法

    List<User> list =  userMapper.listUsers("hello105");

    调到invoke这个方法:
    final MapperMethod mapperMethod = cachedMapperMethod(method);

    实例化MapperMethod对象:
    private MapperMethod cachedMapperMethod(Method method) {
      MapperMethod mapperMethod = methodCache.get(method);
    if (mapperMethod == null) {
    mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());
    methodCache.put(method, mapperMethod);
    }
    return mapperMethod;
    }

    实例化sqlCommand对象:
    public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {
    this.command = new SqlCommand(config, mapperInterface, method);
    this.method = new MethodSignature(config, method);
    }

    2:mapper.xml 中 ,元素重复的问题,有可能是 resultMap 重复,sql、或者 select等元素重复,也有可能jar包重复了,或者名字重复等

    Caused by: java.lang.IllegalArgumentException: Result Maps collection already contains value for com.example.mybatis.mapper.UserMapper.test
    	at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:816)
    	at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:788)
    	at org.apache.ibatis.session.Configuration.addResultMap(Configuration.java:570)
    	at org.apache.ibatis.builder.MapperBuilderAssistant.addResultMap(MapperBuilderAssistant.java:214)
    	at org.apache.ibatis.builder.ResultMapResolver.resolve(ResultMapResolver.java:47)
    	at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:285)
    	at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:252)
    	at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElements(XMLMapperBuilder.java:244)
    	at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:116)
    	... 7 more
    

      

    之前的章节我们说过,XMLMapperBuilder是专门用来解析mapper.xml文件,下面我们来从源码的层面分析一下:

    从栈信息中可以看出,

     找到解析resultMap元素的方法:

    resultMap的节点会在resultMapElement方法中解析:

    解析后会向configuration中resultMap的缓存中放,由于id重复,所以会抛出异常

     抛出异常信息的逻辑:

    3:看下面的异常,提示ResultMap缓存中没有userMapper.test的元素

     

    Exception in thread "main" Disconnected from the target VM, address: '127.0.0.1:52974', transport: 'socket'
    org.apache.ibatis.builder.IncompleteElementException: Could not find result map UserMapper.test
    	at org.apache.ibatis.builder.MapperBuilderAssistant.getStatementResultMaps(MapperBuilderAssistant.java:346)
    	at org.apache.ibatis.builder.MapperBuilderAssistant.addMappedStatement(MapperBuilderAssistant.java:290)
    	at org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parseStatement(MapperAnnotationBuilder.java:317)
    	at org.apache.ibatis.builder.annotation.MethodResolver.resolve(MethodResolver.java:33)
    	at org.apache.ibatis.session.Configuration.buildAllStatements(Configuration.java:738)
    	at org.apache.ibatis.session.Configuration.hasStatement(Configuration.java:702)
    	at org.apache.ibatis.session.Configuration.hasStatement(Configuration.java:697)
    	at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:183)
    	at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:44)
    	at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:59)
    	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)
    	at com.sun.proxy.$Proxy3.selectUser(Unknown Source)
    	at com.example.mybatis.TestMybatis.main(TestMybatis.java:27)
    Caused by: java.lang.IllegalArgumentException: Result Maps collection does not contain value for UserMapper.test
    	at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:832)
    	at org.apache.ibatis.session.Configuration.getResultMap(Configuration.java:584)
    	at org.apache.ibatis.builder.MapperBuilderAssistant.getStatementResultMaps(MapperBuilderAssistant.java:344)
    	... 12 more
    

      

    这个异常是因为resultMap的名称对应不上,要么直接写test简称,要么直接全路径名

    不能写成其他的名字,下面通过分析源码的形式看一下为什么报错:

    这里有个应用命名空间的方法:

    如果base是只有带命名空间直接返回,如果包含点,抛异常,如果不带命名空间,则拼接命名空间与方法名,所以resultMap上面的名称要么简写,要么全路径名称。

      public String applyCurrentNamespace(String base, boolean isReference) {
        if (base == null) {
          return null;
        }
        if (isReference) {
          // is it qualified with any namespace yet?
          if (base.contains(".")) {
            return base;
          }
        } else {
          // is it qualified with this namespace yet?
          if (base.startsWith(currentNamespace + ".")) {
            return base;
          }
          if (base.contains(".")) {
            throw new BuilderException("Dots are not allowed in element names, please remove it from " + base);
          }
        }
        return currentNamespace + "." + base;
      }
    

      

  • 相关阅读:
    申请加分项
    课程评价
    本周总结
    热词2
    热词1
    php大作业
    css网格布局
    php实验4
    本周总结
    css边框图像
  • 原文地址:https://www.cnblogs.com/warrior4236/p/13094041.html
Copyright © 2011-2022 走看看