Skip to content

MyBatis SQL映射 ​

深入理解MyBatis的SQL映射机制,掌握SQL语句的解析和执行流程,理解参数映射、结果映射等核心功能。

📋 SQL映射概览 ​

SQL映射是MyBatis的核心功能,负责将Java方法调用转换为SQL语句执行。

🎯 一、SQL解析 ​

1.1 XMLMapperBuilder ​

XMLMapperBuilder:

java
public class XMLMapperBuilder extends BaseBuilder {
    
    public void parse() {
        if (!configuration.isResourceLoaded(resource)) {
            configurationElement(parser.evalNode("/mapper"));
            configuration.addLoadedResource(resource);
            bindMapperForNamespace();
        }
    }
}

1.2 MappedStatement ​

MappedStatement:

java
public final class MappedStatement {
    private String resource;
    private Configuration configuration;
    private String id;
    private SqlSource sqlSource;
    private SqlCommandType sqlCommandType;
}

🎯 二、参数映射 ​

2.1 参数处理 ​

ParameterHandler:

java
public interface ParameterHandler {
    Object getParameterObject();
    void setParameters(PreparedStatement ps) throws SQLException;
}

2.2 参数绑定 ​

DefaultParameterHandler:

java
@Override
public void setParameters(PreparedStatement ps) {
    ErrorContext.instance().activity("setting parameters")
            .object(mappedStatement.getParameterMap().getId());
    List<ParameterMapping> parameterMappings = 
            boundSql.getParameterMappings();
    if (parameterMappings != null) {
        for (int i = 0; i < parameterMappings.size(); i++) {
            ParameterMapping parameterMapping = parameterMappings.get(i);
            if (parameterMapping.getMode() != ParameterMode.OUT) {
                Object value;
                String propertyName = parameterMapping.getProperty();
                if (boundSql.hasAdditionalParameter(propertyName)) {
                    value = boundSql.getAdditionalParameter(propertyName);
                } else if (parameterObject == null) {
                    value = null;
                } else if (typeHandlerRegistry.hasTypeHandler(
                        parameterObject.getClass())) {
                    value = parameterObject;
                } else {
                    MetaObject metaObject = configuration.newMetaObject(
                            parameterObject);
                    value = metaObject.getValue(propertyName);
                }
                TypeHandler typeHandler = parameterMapping.getTypeHandler();
                JdbcType jdbcType = parameterMapping.getJdbcType();
                if (value == null && jdbcType == null) {
                    jdbcType = configuration.getJdbcTypeForNull();
                }
                try {
                    typeHandler.setParameter(ps, i + 1, value, jdbcType);
                } catch (TypeException | SQLException e) {
                    throw new TypeException(...);
                }
            }
        }
    }
}

🎯 三、SQL执行 ​

3.1 Executor ​

Executor接口:

java
public interface Executor {
    <E> List<E> query(MappedStatement ms, Object parameter, 
            RowBounds rowBounds, ResultHandler resultHandler) 
            throws SQLException;
    int update(MappedStatement ms, Object parameter) throws SQLException;
}

3.2 SimpleExecutor ​

SimpleExecutor.query:

java
@Override
public <E> List<E> doQuery(MappedStatement ms, Object parameter, 
        RowBounds rowBounds, ResultHandler resultHandler, 
        BoundSql boundSql) throws SQLException {
    Statement stmt = null;
    try {
        Configuration configuration = ms.getConfiguration();
        StatementHandler handler = configuration.newStatementHandler(
                wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
        stmt = prepareStatement(handler, ms.getStatementLog());
        return handler.query(stmt, resultHandler);
    } finally {
        closeStatement(stmt);
    }
}

📖 学习资源 ​

视频教程 ​

书籍推荐 ​

  • 《MyBatis技术内幕》 - 徐郡明

网站资源 ​

✅ 学习检查清单 ​

  • [ ] 已理解SQL解析机制
  • [ ] 已理解参数映射
  • [ ] 已理解SQL执行流程
  • [ ] 已总结核心知识点

上一章节:Mybatis和Tomcat源码深度解析概览
下一章节:MyBatis结果集处理
返回目录:源码阅读