MyBatis 运行原理
MyBatis 是一个半自动化的 ORM 框架,其核心运行原理围绕 SQL 与 Java 对象的映射展开,通过动态代理和反射机制实现数据库操作。
配置加载阶段
MyBatis 启动时会加载全局配置文件(如mybatis-config.xml),解析数据源、事务管理器等基础配置。同时加载 Mapper 映射文件(XML 或注解),将 SQL 语句与接口方法绑定。
SQL 会话创建
通过SqlSessionFactoryBuilder构建SqlSessionFactory,再由工厂生成SqlSession。SqlSession是核心交互对象,提供增删改查 API,内部通过执行器(Executor)管理数据库操作。
动态代理机制
调用 Mapper 接口方法时,MyBatis 使用 JDK 动态代理生成代理对象。MapperProxy拦截方法调用,根据方法名和参数匹配映射的 SQL 语句。
SQL 解析与执行
代理对象将方法调用转为MappedStatement操作,通过ParameterHandler处理参数,StatementHandler构建 JDBCPreparedStatement,最终由执行器完成数据库交互。
结果映射
ResultSetHandler将查询结果转换为 Java 对象,依据ResultMap配置进行属性映射,支持自动驼峰转换或自定义类型处理器(TypeHandler)。
缓存机制
一级缓存(SqlSession级别)默认开启,二级缓存(Mapper级别)需手动配置。执行更新操作时会自动清空缓存,保证数据一致性。
核心组件协作流程
- 接口调用:用户调用 Mapper 接口方法。
- 代理拦截:
MapperProxy解析方法签名,定位对应的MappedStatement。 - 参数处理:
ParameterHandler将 Java 参数转换为 SQL 参数。 - SQL 执行:
Executor通过 JDBC 执行 SQL,可能经过缓存判断。 - 结果转换:
ResultSetHandler将ResultSet转为方法返回类型。
示例代码片段
// 初始化阶段 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 运行时阶段 try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectById(1); // 触发动态代理与SQL执行 }关键设计特点
- 灵活性:SQL 与代码分离,支持动态 SQL(
<if>,<foreach>等标签)。 - 低侵入性:无需强制继承或实现特定接口。
- 可扩展性:插件机制可拦截四大对象(Executor、StatementHandler 等)。
- 性能优化:支持批量操作、延迟加载、缓存策略。