1. 程式人生 > >mybatis載入xml檔案錯誤及其影響

mybatis載入xml檔案錯誤及其影響

一次在做一個專案的過程中,發現mybatis載入xml檔案錯誤,導致了後面所有的sql都報了這個sql語句的錯誤,一時沒有摸到頭腦,在此分析下。

在mybatis載入xml檔案的時候,會解析所有的檔案,同時把statement錯誤的檔案放到一個集合中去,程式碼如下:

  private void buildStatementFromContext(List<XNode> list, String requiredDatabaseId) {
    for (XNode context : list) {
      final XMLStatementBuilder statementParser = new XMLStatementBuilder(configuration, builderAssistant, context, requiredDatabaseId);
      try {
        statementParser.parseStatementNode();
      } catch (IncompleteElementException e) {
        configuration.addIncompleteStatement(statementParser);
} } }

重點看catch中的語句:
  public void addIncompleteStatement(XMLStatementBuilder incompleteStatement) {
    incompleteStatements.add(incompleteStatement);
  }

incompleteStatements是載入錯誤的Statements集合。而當每次執行任何sql語句的時候,都會檢查incompleteStatements是否為空,如果為空的話,就一直報那個載入錯誤的xml檔案。程式碼如下:

我們從MapperProxy類的invoke方法一直往下走:

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (method.getDeclaringClass() == Object.class) {
      return method.invoke(this, args);
    }
    final Class<?> declaringInterface = findDeclaringInterface(proxy, method);
    final MapperMethod mapperMethod = new MapperMethod(declaringInterface, method, sqlSession);
final Object result = mapperMethod.execute(args); if (result == null && method.getReturnType().isPrimitive() && !method.getReturnType().equals(Void.TYPE)) { throw new BindingException("Mapper method '" + method.getName() + "' (" + method.getDeclaringClass() + ") attempted to return null from a method with a primitive return type (" + method.getReturnType() + ")."); } return result; }

  public MapperMethod(Class<?> declaringInterface, Method method, SqlSession sqlSession) {
    paramNames = new ArrayList<String>();
    paramPositions = new ArrayList<Integer>();
    this.sqlSession = sqlSession;
    this.method = method;
    this.config = sqlSession.getConfiguration();
    this.hasNamedParameters = false;
    this.declaringInterface = declaringInterface;
    this.objectFactory = config.getObjectFactory();
    setupFields();//設定欄位
    setupMethodSignature();//設定方法驗證
    setupCommandType();//命令型別:select,update,delete,insert
    validateStatement();//驗證statement
  }

  private void setupCommandType() {
    MappedStatement ms = config.getMappedStatement(commandName);
    type = ms.getSqlCommandType();
    if (type == SqlCommandType.UNKNOWN) {
      throw new BindingException("Unknown execution method for: " + commandName);
    }
  }
在獲取命令型別前,先獲取到MappedStatement,同時在獲取MappedStatement前會有一個驗證,是否有未完成的Statement:
  public MappedStatement getMappedStatement(String id, boolean validateIncompleteStatements) {
    if (validateIncompleteStatements) {
      buildAllStatements();
    }
    return mappedStatements.get(id);
  }

  protected void buildAllStatements() {
    if (!incompleteResultMaps.isEmpty()) {
      synchronized (incompleteResultMaps) {
        // This always throws a BuilderException.
        incompleteResultMaps.iterator().next().resolve();
      }
    }
    if (!incompleteCacheRefs.isEmpty()) {
      synchronized (incompleteCacheRefs) {
        // This always throws a BuilderException.
        incompleteCacheRefs.iterator().next().resolveCacheRef();
      }
    }
    if (!incompleteStatements.isEmpty()) {
      synchronized (incompleteStatements) {
        // This always throws a BuilderException.
        incompleteStatements.iterator().next().parseStatementNode();
      }
    }
  }

如果有未完成是MappedStatement的話就會,繼續完成轉化MappedStatement,如果轉化出錯,則會直接丟擲異常。

相關推薦

mybatis載入xml檔案錯誤及其影響

一次在做一個專案的過程中,發現mybatis載入xml檔案錯誤,導致了後面所有的sql都報了這個sql語句的錯誤,一時沒有摸到頭腦,在此分析下。 在mybatis載入xml檔案的時候,會解析所有的檔案,同時把statement錯誤的檔案放到一個集合中去,程式碼如下:

解決 mybatis 載入xml配置檔案bug

摘要:mybatis 【問題描述】                    mybatis在載入配置檔案時,有可能會拋“"Could not find SQL statement to include with refid"異常資訊。            在windows

複雜SQL語句的書寫(mybatisXML檔案的核心)

select sd.name as dptName, pro.`name` as provinceName, c.`name` as cityName, a.`name` as areaName, info.id, dpt.*, info.*, gd.*

mybatis---mapper.xml檔案

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd" > <mapper na

mybatis---Config.xml檔案配置

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "mybatis-3-config.dtd" > <co

關於mvnen專案下hibernate mybaits打包無法載入xml檔案

maven專案打包時,如果java目錄下有xml檔案,則打包時不會載入xml檔案,但是有時我們mybatis或hibernate的xml會寫在java目錄下。 解決方案: 在專案pom檔案build中加入如下配置即可解決問題 <resources>

mybatisXML檔案列舉比較用法

package com.farer.collection.enums; /** * @Title: AssetTypeEnum.java * @Package com.farer.collection.enums * @Description:

mybatisxml檔案第一行報錯解決辦法

將   <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "<span style="color: #

三大框架之一 —— mybatismybatis-config.xml 檔案配置

1.常用標籤: 標籤必須按照指定順序書寫: properties(傳遞配置檔案), settings(設定命名方式), typeAliases(設定別名), typeHand

java ee SSM框架連線資料庫四個配置檔案之二: mybatis-config.xml檔案配置

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD

Kotlin通過Id操作View,Adapter和動態載入Xml檔案也可以類似操作

如果使用kotlin,什麼butterknife繫結,Xutil註解都不需要,只需要通過id就可以操作view,非常方便,但是在使用的過程中還是遇到兩個值得記錄的問題如下: 針對adapter中通過id來操作 針對動態載入佈局通過id來操作 其實兩者本質

MyBatisxml檔案中模糊查詢的寫法

資料庫中某表的一個欄位為name,我需要對它進行模糊查詢的時候使用了下面的方法,解決了這個問題。 <select id="findList" resultType="DwfxGzysxl"> SELECT <include refid="d

mybatis MyBatis Mapper.xml檔案中 $和#的區別

1.  MyBatis Mapper.xml檔案中 $和#的區別   網上有很多,總之,簡略的寫一下,作為備忘。例子中假設引數名為 paramName,型別為 VARCHAR 。 1.優先使用#{paramName,jdbcType=VARCHAR} 寫法,

載入xml出現錯誤

Referenced file contains errors (http://www.springframework.org/schema/beans/spring-beans-3.1.xsd). For more information, right click on

MyBatis Mapper XML檔案詳解

MyBatis 的真正強大在於它的對映語句,也是它的魔力所在。由於它的異常強大,對映器的 XML 檔案就顯得相對簡單。如果拿它跟具有相同功能的 JDBC 程式碼進行對比,你會立即發現省掉了將近 95% 的程式碼。MyBatis 就是針對 SQL 構建的,並且比普通的方法做

mybatisxml檔案中的SQL語句不能以分號結尾

在mybatis的sql配置檔案中,如果是單獨的sql語句,就是不是儲存過程,寫的sql語句是不能使用分號做結尾的,不然程式執行的時候會報ora-00911: 無效字元.如: 百度了下,具體的原因是   “Oracle資料庫介面對書寫格式要求非常嚴格,有時候即使多加

mybatis mapper.xml檔案裡怎麼呼叫靜態方法

剛用mybatis時,當時想要在mapper.xml檔案裡呼叫靜態方法,比如某個物件的id是由工具類的靜態方法生成的,所以想在insert語句裡呼叫那個工具類的靜態方法,不過當時搜尋了半天沒有解決,最近在另一個專案組無意中看到其他同事寫的mapper檔案發現裡面就有這個用法

mybatis Mapper XML 檔案 Result Maps 一對一與一對查詢

 一對一關聯查詢 建立一個實體類 package com.touchspring.annualparty.base.entity; import java.util.Date; public class Chat { private String id;

C++ 載入.xml檔案

///首先寫一個ProductNameConfig.xml <?xml version="1.0" encoding="GB2312" ?> <Root> <Product> <Parameter ProductID="C

使用XmlDocument/XmlDataDocument類載入XML檔案時如何忽略DTD驗證

在XML檔案含有外部DTD驗證的時候,使用XmlDocument/XmlDataDocument類的Load方法會丟擲如下的例外: System.Xml.XmlException: 未找到所需的 DTD 標記。 行 m,位置 n。 我們可以採用下面的方法不去載入外部資源: