Files
interview/questions/02-数据库/MyBatis核心原理.md
yasinshaw 0e46a367c4 refactor: rename files to Chinese and organize by category
Organized 50 interview questions into 12 categories:
- 01-分布式系统 (9 files): 分布式事务, 分布式锁, 一致性哈希, CAP理论, etc.
- 02-数据库 (2 files): MySQL索引优化, MyBatis核心原理
- 03-缓存 (5 files): Redis数据结构, 缓存问题, LRU算法, etc.
- 04-消息队列 (1 file): RocketMQ/Kafka
- 05-并发编程 (4 files): 线程池, 设计模式, 限流策略, etc.
- 06-JVM (1 file): JVM和垃圾回收
- 07-系统设计 (8 files): 秒杀系统, 短链接, IM, Feed流, etc.
- 08-算法与数据结构 (4 files): B+树, 红黑树, 跳表, 时间轮
- 09-网络与安全 (3 files): TCP/IP, 加密安全, 性能优化
- 10-中间件 (4 files): Spring Boot, Nacos, Dubbo, Nginx
- 11-运维 (4 files): Kubernetes, CI/CD, Docker, 可观测性
- 12-面试技巧 (1 file): 面试技巧和职业规划

All files renamed to Chinese for better accessibility and
organized into categorized folders for easier navigation.

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-03-01 00:10:53 +08:00

178 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
<!-- 开启二级缓存 -->
<cache/>
```
```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}
<!-- ❌ SQL 注入风险 -->
SELECT * FROM users WHERE id = ${id}
<!-- ✅ 动态表名(只能用 ${}-->
SELECT * FROM ${tableName} WHERE id = #{id}
```
---
### 5. 批量操作
**方式 1SqlSession 批量**
```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();
}
```
**方式 2Batch Insert**
```xml
<insert id="batchInsert">
INSERT INTO users (name, email) VALUES
<foreach collection="users" item="user" separator=",">
(#{user.name}, #{user.email})
</foreach>
</insert>
```
---
### 6. 动态 SQL
**常用标签**
```xml
<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="email != null">
AND email = #{email}
</if>
</where>
</select>
<select id="findUsersByIds" resultType="User">
SELECT * FROM users
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
```
---
### 7. 阿里 P7 加分项
**深度理解**
- 理解 MyBatis 的代理机制MapperProxy
- 理解二级缓存的并发问题
- 理解插件的责任链模式
**实战经验**
- 有处理 MyBatis 性能问题的经验
- 有自定义插件的经验
- 有 MyBatis 与 Spring 集成的经验
**架构能力**
- 能设计多数据源方案
- 能设计分库分表的 MyBatis 方案
- 能设计 MyBatis 监控体系