Generated comprehensive interview preparation materials covering: - Distributed systems (transactions, locks, ID generation, consistency) - Database (indexing, sharding, replication, transactions) - Caching (Redis, cache problems, distributed lock) - Message queues (RocketMQ, Kafka) - Concurrency (ThreadLocal, ConcurrentHashMap, thread pools) - JVM (GC, memory, tuning) - System design (seckill, short URL, IM, feed, LBS) - Algorithms (B+ tree, LRU, Red-Black tree, Skip list, Timing wheel) - Network (TCP/IP, HTTP/HTTPS) - Security (encryption, SQL injection, XSS) - Performance tuning - Design patterns - Microservices (Spring Boot, Gateway, Service Mesh) - Container orchestration (Kubernetes, Docker) - CI/CD, observability Each file includes: - Detailed questions - Comprehensive answers - Code examples - Real project experience - Alibaba P7 level requirements 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>
178 lines
3.6 KiB
Markdown
178 lines
3.6 KiB
Markdown
# 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. 批量操作
|
||
|
||
**方式 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 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 监控体系
|