MyBatis四大组件和SqlSession四大对象详解

MyBatis四大核心组件

SqlSessionFactoryBuilder

SqlSessionFactoryBuilder的核心源码分析:

public class SqlSessionFactoryBuilder {
    public SqlSessionFactory build(Reader reader) {
        try {
            // 解析配置文件,创建Configuration对象
            XMLConfigBuilder parser = new XMLConfigBuilder(reader);
            return build(parser.parse());
        } catch (Exception e) {
            throw ExceptionFactory.wrapException("Error building SqlSession.", e);
        }
    }

    // Configuration对象创建SqlSessionFactory
    public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactory(config);
    }
}

源码解析要点:

  1. 配置文件解析过程:

    public Configuration parse() {
        if (parsed) {
            throw new BuilderException("Each XMLConfigBuilder can only be used once.");
        }
        parsed = true;
        parseConfiguration(parser.evalNode("/configuration"));
        return configuration;
    }
    
  2. Configuration类的重要属性:

    public class Configuration {
        protected Environment environment;
        protected boolean lazyLoadingEnabled = false;
        protected boolean aggressiveLazyLoading = false;
        protected boolean multipleResultSetsEnabled = true;
        // ... 更多配置属性
    }
    

SqlSessionFactory

DefaultSqlSessionFactory的核心实现:

public class DefaultSqlSessionFactory implements SqlSessionFactory {
    private final Configuration configuration;
    
    // 创建SqlSession的核心方法
    @Override
    public SqlSession openSession() {
        return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
    }
    
    // 从数据源创建SqlSession
    private SqlSession openSessionFromDataSource(ExecutorType execType, 
            TransactionIsolationLevel level, boolean autoCommit) {
        Transaction tx = null;
        try {
            // 获取环境配置
            final Environment environment = configuration.getEnvironment();
            // 创建事务工厂
            final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
            // 创建事务
            tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
            // 创建Executor
            final Executor executor = configuration.newExecutor(tx, execType);
            // 创建DefaultSqlSession
            return new DefaultSqlSession(configuration, executor, autoCommit);
        } catch (Exception e) {
            closeTransaction(tx);
            throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
        }
    }
}

SqlSession

DefaultSqlSession的关键源码:

public class DefaultSqlSession implements SqlSession {
    private final Configuration configuration;
    private final Executor executor;
    private final boolean autoCommit;
    
    // 查询操作的实现
    @Override
    public <E> List<E> selectList(String statement, Object parameter) {
        try {
            // 获取MappedStatement
            MappedStatement ms = configuration.getMappedStatement(statement);
            // 通过执行器查询
            return executor.query(ms, wrapCollection(parameter),
                    RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
        } catch (Exception e) {
            throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
        }
    }
    
    // 获取Mapper接口的实现
    @Override
    public <T> T getMapper(Class<T> type) {
        return configuration.getMapper(type, this);
    }
}

Mapper接口

MapperProxy的动态代理实现:

public class MapperProxy<T> implements InvocationHandler, Serializable {
    private final SqlSession sqlSession;
    private final Class<T> mapperInterface;
    private final Map<Method, MapperMethodInvoker> methodCache;
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            // Object方法直接调用
            if (Object.class.equals(method.getDeclaringClass())) {
                return method.invoke(this, args);
            }
            // 其他方法走代理
            return cachedInvoker(method).invoke(proxy, method, args, sqlSession);
        } catch (Throwable t) {
            throw ExceptionUtil.unwrapThrowable(t);
        }
    }
}

SqlSession的四大对象

Executor

Executor的核心实现和类型:

public interface Executor {
    ResultHandler NO_RESULT_HANDLER = null;
    
    // 更新方法
    int update(MappedStatement ms, Object parameter) throws SQLException;
    
    // 查询方法
    <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, 
            ResultHandler resultHandler) throws SQLException;
    
    // 事务方法
    Transaction getTransaction();
    void commit(boolean required) throws SQLException;
    void rollback(boolean required) throws SQLException;
}

// SimpleExecutor的实现
public class SimpleExecutor extends BaseExecutor {
    @Override
    protected int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
        Statement stmt = null;
        try {
            Configuration configuration = ms.getConfiguration();
            // 创建StatementHandler
            StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, 
                    RowBounds.DEFAULT, null, null);
            // 准备语句
            stmt = prepareStatement(handler, ms.getStatementLog());
            // 执行更新
            return handler.update(stmt);
        } finally {
            closeStatement(stmt);
        }
    }
}

ParameterHandler

参数处理器的实现:

public class DefaultParameterHandler implements ParameterHandler {
    @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();
                    // 获取参数值并设置
                    value = metaObject.getValue(propertyName);
                    TypeHandler typeHandler = parameterMapping.getTypeHandler();
                    typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType());
                }
            }
        }
    }
}

ResultSetHandler

结果集处理器的核心实现:

public class DefaultResultSetHandler implements ResultSetHandler {
    @Override
    public List<Object> handleResultSets(Statement stmt) throws SQLException {
        final List<Object> multipleResults = new ArrayList<>();
        int resultSetCount = 0;
        // 获取第一个结果集
        ResultSetWrapper rsw = getFirstResultSet(stmt);
        
        // 获取结果映射
        List<ResultMap> resultMaps = mappedStatement.getResultMaps();
        while (rsw != null && resultMaps.size() > resultSetCount) {
            ResultMap resultMap = resultMaps.get(resultSetCount);
            // 处理结果集
            handleResultSet(rsw, resultMap, multipleResults, null);
            // 获取下一个结果集
            rsw = getNextResultSet(stmt);
            resultSetCount++;
        }
        return multipleResults;
    }
}

StatementHandler

StatementHandler的实现层次:

public interface StatementHandler {
    Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException;
    void parameterize(Statement statement) throws SQLException;
    int update(Statement statement) throws SQLException;
    <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException;
}

// PreparedStatementHandler的实现
public class PreparedStatementHandler extends BaseStatementHandler {
    @Override
    public int update(Statement statement) throws SQLException {
        PreparedStatement ps = (PreparedStatement) statement;
        ps.execute();
        return ps.getUpdateCount();
    }
    
    @Override
    public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
        PreparedStatement ps = (PreparedStatement) statement;
        ps.execute();
        return resultSetHandler.handleResultSets(ps);
    }
}

工作流程源码分析

完整的SQL执行流程:

// 1. 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

// 2. 创建SqlSession
try (SqlSession session = sqlSessionFactory.openSession()) {
    // 3. 获取Mapper接口
    UserMapper mapper = session.getMapper(UserMapper.class);
    
    // 4. 执行SQL(内部流程)
    User user = mapper.getUserById(1);
    // 4.1 MapperProxy拦截调用
    // 4.2 SqlSession调用Executor
    // 4.3 Executor创建StatementHandler
    // 4.4 StatementHandler使用ParameterHandler设置参数
    // 4.5 StatementHandler执行SQL
    // 4.6 ResultSetHandler处理结果集
    
    // 5. 提交事务
    session.commit();
}

JDK 17特性应用:

// 使用Record定义简单的参数对象
public record UserQuery(String name, Integer age) {}

// 使用Switch表达式
public Object convertValue(Object value) {
    return switch (value) {
        case String s -> "String: " + s;
        case Integer i -> "Integer: " + i;
        case UserQuery q -> "Query: " + q.name() + ", " + q.age();
        default -> throw new IllegalArgumentException("Unsupported type");
    };
}

// 使用Text Blocks定义SQL
String sql = """
    SELECT id, name, age 
    FROM users 
    WHERE name = #{name} 
      AND age > #{age}
    """;

核心接口和实现类关系图

classDiagram
    SqlSessionFactory <|-- DefaultSqlSessionFactory
    SqlSession <|-- DefaultSqlSession
    Executor <|-- BaseExecutor
    BaseExecutor <|-- SimpleExecutor
    BaseExecutor <|-- ReuseExecutor
    BaseExecutor <|-- BatchExecutor
    StatementHandler <|-- BaseStatementHandler
    BaseStatementHandler <|-- SimpleStatementHandler
    BaseStatementHandler <|-- PreparedStatementHandler
    BaseStatementHandler <|-- CallableStatementHandler
    class SqlSessionFactory {
        +openSession() SqlSession
    }
    class Executor {
        +update(MappedStatement, Object)
        +query(MappedStatement, Object, RowBounds, ResultHandler)
    }
    class StatementHandler {
        +prepare(Connection, Integer)
        +parameterize(Statement)
        +update(Statement)
        +query(Statement, ResultHandler)
    }

最佳实践和性能优化建议

  1. 合理使用缓存:
@CacheNamespace(
    implementation = PerpetualCache.class,
    eviction = LruCache.class,
    size = 1024,
    flushInterval = 120000
)
public interface UserMapper {
    @Options(useCache = true)
    User getUserById(Integer id);
}
  1. 批量操作优化:
try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
    UserMapper mapper = session.getMapper(UserMapper.class);
    for (User user : userList) {
        mapper.insertUser(user);
    }
    session.commit();
}
  1. 动态SQL优化:
<select id="findUsers" resultType="User">
    SELECT * FROM users
    <where>
        <if test="name != null">AND name LIKE #{name}</if>
        <if test="age != null">AND age > #{age}</if>
    </where>
</select>

总结

  1. 源码层面的组件协作:

    • SqlSessionFactoryBuilder → Configuration → SqlSessionFactory
    • SqlSessionFactory → Executor → StatementHandler
    • StatementHandler → ParameterHandler/ResultSetHandler
  2. 性能优化关键点:

    • 合理使用缓存机制
    • 批量操作时使用BatchExecutor
    • 动态SQL的优化
    • 延迟加载的配置
  3. JDK 17新特性的应用:

    • Record类型简化参数对象
    • Switch表达式增强
    • Text Blocks优化SQL编写

这些组件通过精心的设计和实现,共同构成了MyBatis的核心功能,理解它们的源码实现对于进行框架定制和性能优化具有重要意义。