# MyBatis 核心原理 ## 问题 1. MyBatis 的核心组件有哪些? 2. MyBatis 的缓存机制(一级缓存、二级缓存)? 3. MyBatis 的插件原理是什么? 4. #{} 和 ${} 的区别是什么? 5. MyBatis 如何处理批量操作? 6. MyBatis 的动态 SQL 是如何实现的? --- ## 标准答案 ### 1. MyBatis 核心组件 ``` Configuration(全局配置) ↓ SqlSession(会话) ↓ Executor(执行器) ↓ StatementHandler(语句处理器) ↓ ParameterHandler(参数处理器) ↓ ResultSetHandler(结果集处理器) ``` --- ### 2. 缓存机制 **一级缓存(SqlSession 级别)**: ```java SqlSession session = sqlSessionFactory.openSession(); User user1 = session.selectOne("selectUser", 1); User user2 = session.selectOne("selectUser", 1); // 从缓存获取 ``` **二级缓存(Mapper 级别)**: ```xml ``` ```java User user1 = session1.selectOne("selectUser", 1); session1.close(); // 一级缓存清空,写入二级缓存 User user2 = session2.selectOne("selectUser", 1); // 从二级缓存获取 ``` --- ### 3. 插件原理 **拦截的四大组件**: - Executor - StatementHandler - ParameterHandler - ResultSetHandler **示例**: ```java @Intercepts({ @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}) }) public class SqlInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 前置逻辑 Object result = invocation.proceed(); // 后置逻辑 return result; } } ``` --- ### 4. #{} vs ${} | 特性 | #{} | ${} | |------|-----|-----| | **预处理** | 是(PreparedStatement) | 否(Statement) | | **SQL 注入** | 安全 | 不安全 | | **类型转换** | 自动 | 需手动 | | **动态表名/列名** | 不支持 | 支持 | **示例**: ```xml SELECT * FROM users WHERE id = #{id} SELECT * FROM users WHERE id = ${id} SELECT * FROM ${tableName} WHERE id = #{id} ``` --- ### 5. 批量操作 **方式 1:SqlSession 批量**: ```java SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH); try { UserMapper mapper = session.getMapper(UserMapper.class); for (User user : users) { mapper.insert(user); } session.commit(); } finally { session.close(); } ``` **方式 2:Batch Insert**: ```xml INSERT INTO users (name, email) VALUES (#{user.name}, #{user.email}) ``` --- ### 6. 动态 SQL **常用标签**: ```xml ``` --- ### 7. 阿里 P7 加分项 **深度理解**: - 理解 MyBatis 的代理机制(MapperProxy) - 理解二级缓存的并发问题 - 理解插件的责任链模式 **实战经验**: - 有处理 MyBatis 性能问题的经验 - 有自定义插件的经验 - 有 MyBatis 与 Spring 集成的经验 **架构能力**: - 能设计多数据源方案 - 能设计分库分表的 MyBatis 方案 - 能设计 MyBatis 监控体系