mybatis加载xml文件错误及其影响 您所在的位置:网站首页 webxml头文件 mybatis加载xml文件错误及其影响

mybatis加载xml文件错误及其影响

2022-12-28 21:27| 来源: 网络整理| 查看: 265

一次在做一个项目的过程中,发现mybatis加载xml文件错误,导致了后面所有的sql都报了这个sql语句的错误,一时没有摸到头脑,在此分析下。

在mybatis加载xml文件的时候,会解析所有的文件,同时把statement错误的文件放到一个集合中去,代码如下:

private void buildStatementFromContext(List 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(); paramPositions = new ArrayList(); 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,如果转化出错,则会直接抛出异常。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有