Skip to content

Commit 12dccbb

Browse files
committed
MySQL是如何执行一条SQL语句的
1 parent 9de5999 commit 12dccbb

3 files changed

Lines changed: 138 additions & 0 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# MySQL是如何执行一条SQL的
2+
3+
先附上一张图:
4+
5+
![执行过程图](http://media.dreamcat.ink/uPic/SQL%E6%89%A7%E8%A1%8C%E7%9A%84%E5%85%A8%E9%83%A8%E8%BF%87%E7%A8%8B.png)
6+
7+
**MySQL内部可以分为服务层和存储引擎层两部分:**
8+
1. **服务层包括连接器、查询缓存、分析器、优化器、执行器等**,涵盖MySQL的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
9+
2. **存储引擎层负责数据的存储和提取**,其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。现在最常用的存储引擎是InnoDB,它从MySQL 5.5.5版本开始成为了默认的存储引擎。
10+
11+
**Server层按顺序执行sql的步骤为**
12+
客户端请求->**连接器**(验证用户身份,给予权限) -> **查询缓存**(存在缓存则直接返回,不存在则执行后续操作)->**分析器**(对SQL进行词法分析和语法分析操作) -> **优化器**(主要对执行的sql优化选择最优的执行方案方法) -> **执行器**(执行时会先看用户是否有执行权限,有才去使用这个引擎提供的接口)->**去引擎层获取数据返回**(如果开启查询缓存则会缓存查询结果)
13+
14+
简单概括:
15+
- **连接器**:管理连接、权限验证;
16+
- **查询缓存**:命中缓存则直接返回结果;
17+
- **分析器**:对SQL进行词法分析、语法分析;(判断查询的SQL字段是否存在也是在这步)
18+
- **优化器**:执行计划生成、选择索引;
19+
- **执行器**:操作引擎、返回结果;
20+
- **存储引擎**:存储数据、提供读写接口。
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# 手写SpringAOP
2+
3+
## 定义advice接口
4+
5+
```java
6+
public interface Advice extends InvocationHandler {
7+
}
8+
```
9+
10+
## 定义方法回调接口
11+
```java
12+
public interface MethodInvocation {
13+
void invoke();
14+
}
15+
```
16+
17+
## 定义前置通知
18+
```java
19+
public class BeforeAdvice implements Advice {
20+
21+
private Object bean; // bean对象
22+
23+
private MethodInvocation methodInvocation; // 方法调用
24+
25+
public BeforeAdvice(Object bean, MethodInvocation methodInvocation) {
26+
this.bean = bean;
27+
this.methodInvocation = methodInvocation;
28+
}
29+
30+
@Override
31+
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
32+
// 在目标方法前调用,前置
33+
methodInvocation.invoke();
34+
return method.invoke(bean, args);
35+
}
36+
}
37+
```
38+
39+
## 定义后置通知
40+
```java
41+
public class AfterAdvice implements Advice {
42+
43+
private Object bean;
44+
45+
private MethodInvocation methodInvocation;
46+
47+
public AfterAdvice(Object bean, MethodInvocation methodInvocation) {
48+
this.bean = bean;
49+
this.methodInvocation = methodInvocation;
50+
}
51+
52+
@Override
53+
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
54+
// 业务逻辑调用
55+
Object invoke = method.invoke(bean, args);
56+
// 后置通知调用
57+
methodInvocation.invoke();
58+
return invoke;
59+
}
60+
}
61+
```
62+
63+
## 定义目标方法接口
64+
```java
65+
public interface HelloService {
66+
void sayHelloWorld();
67+
}
68+
```
69+
70+
## 实现目标方法
71+
```java
72+
public class HelloServiceImpl implements HelloService {
73+
74+
@Override
75+
public void sayHelloWorld() {
76+
System.out.println("hello world...");
77+
}
78+
}
79+
```
80+
81+
## SpringAOP的实现
82+
```java
83+
public class SimpleAOP {
84+
// 反射代理
85+
public static Object getProxy(Object bean, Advice advice) {
86+
return Proxy.newProxyInstance(SimpleAOP.class.getClassLoader()
87+
, bean.getClass().getInterfaces(), advice);
88+
}
89+
}
90+
```
91+
92+
## 简单测试
93+
```java
94+
public class SimpleAOPTest {
95+
public static void main(String[] args) {
96+
// 1. 创建一个 MethodInvocation 实现类 切面逻辑类
97+
MethodInvocation logTask = () -> System.out.println("log task start");
98+
MethodInvocation logTaskEnd = () -> System.out.println("log task end");
99+
100+
// 业务逻辑类
101+
HelloServiceImpl helloService = new HelloServiceImpl();
102+
103+
// 2. 创建一个Advice 切入点
104+
BeforeAdvice beforeAdvice = new BeforeAdvice(helloService, logTask);
105+
AfterAdvice afterAdvice = new AfterAdvice(helloService, logTaskEnd);
106+
107+
// 3. 为目标对象生成代理
108+
HelloService helloServiceImplProxy = (HelloService) SimpleAOP.getProxy(helloService, beforeAdvice);
109+
HelloService helloServiceImplProxyAfter = (HelloService) SimpleAOP.getProxy(helloService, afterAdvice);
110+
111+
helloServiceImplProxy.sayHelloWorld();
112+
helloServiceImplProxyAfter.sayHelloWorld();
113+
114+
}
115+
}
116+
```

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@
256256
- [查看JVM吐血系列](/Interview/crazy/个人吐血系列-总结JVM.md)
257257
- [查看Spring吐血系列](/Interview/crazy/个人吐血系列-总结Spring.md)
258258
- [手写SpringIoc容器](/Interview/codes/spring/手写SpringIoc容器.md)
259+
- [手写SpringAOP代码](/Interview/codes/spring/手写SpringAOP代码.md)
260+
- [MySQL是如何执行一条SQL语句的](/Interview/codes/spring/MySQL是如何执行一条SQL语句的.md)
259261

260262

261263
### 设计模式

0 commit comments

Comments
 (0)