一.JDBC的执行流程 (面试题一)
JBDC的底层主要是三个接口对象,Connection、Statement、ResultSet。
Connection用于建立与数据库的连接,Statement用于向数据库发送sql语句,ResultSet用于封装sql查询语句的结果。
原始的JDBC操作数据库主要有以下几个步骤:
1.注册驱动
使用 Class.forName() 方法加载数据库驱动程序类。
2.获取连接对象
JDBC的底层其实是使用Socket进行连接数据库的。打开Connection .
3.执行SQL语句,返回执行结果
通过获取Statement实例执行SQL语句。
4.处理执行结果
最后返回的结果集是ResultSet。
5.释放资源
JDBC的执行流程
JBDC底层原理解析-CSDN博客
http://https://blog.csdn.net/qq_51634677/article/details/131445572
二.MyBatis执行流程(面试题二)
MyBatis的工作原理
2.1 Executor执行器
Executor 执行器则是 MyBatis 框架中的 SQL 执行工具,它负责执行 MappedStatement 中定义的 SQL 语句,并根据配置决定是否开启缓存、是否处理批量操作等。当调用 SqlSession 的 CRUD 方法时,SqlSession 会委托给它的内部 Executor 执行器去完成具体的 SQL 执行工作。
Executor 是 MyBatis 执行 SQL 的入口,它是一个策略模式的体现,有多种实现(如 SimpleExecutor、ReuseExecutor、BatchExecutor 等),分别适用于不同的场景(例如是否启用缓存、是否进行批处理等)。
当用户通过 SqlSession 执行某个数据库操作时,Executor 会根据指定的方法名和参数找到相应的 MappedStatement,并负责执行该 SQL 语句。
1.SimpleExecutor – SIMPLE 就是普通的执行器。
2.ReuseExecutor-执行器会重用预处理语句(PreparedStatements)
3.BatchExecutor --它是批处理执行器
2.2 MappedStatement 对象
MappedStatement 对象是 MyBatis 核心配置文件中每一个
<select>、<insert>、<update>、<delete>
等标签的映射,它封装了 SQL 语句以及其参数类型、结果集映射等信息。在 MyBatis 初始化阶段,会将 XML 映射文件或注解解析成一个个 MappedStatement 对象存储起来。
2.3 StatementHandler 语句处理器
StatementHandler 是 Executor 与 JDBC Statement 接口交互的桥梁,它负责对 JDBC Statement 进行进一步的封装和控制。在 Executor 执行 SQL 的过程中,它会通过 StatementHandler 去真正操作数据库,StatementHandler 会根据 MappedStatement 中的信息设置 SQL 参数、预编译 SQL 语句以及处理查询结果集的映射等细节工作。
三者之间的关系可以用以下步骤概括:
-
用户通过 SqlSession 调用一个方法,SqlSession 通过 Executor 找到对应的 MappedStatement。
-
Executor 使用找到的 MappedStatement,结合请求参数,通过 StatementHandler 创建并配置 JDBC Statement。
-
StatementHandler 根据 MappedStatement 中的 SQL 语句及参数映射信息,设置 SQL 参数并执行 SQL。
-
执行 SQL 后,StatementHandler 再次发挥作用,处理数据库返回的结果集,并将其按照 MappedStatement 中定义的结果映射转换为 Java 对象,最终返回给客户端。
三.Mybatis拦截器
拦截的执行顺序是Executor->StatementHandler->ParameterHandler->ResultHandler
3.1 Mybatis提供了四种类型的拦截器:
1. Executor(执行器拦截器):
- 用途:拦截MyBatis执行器方法的执行。
- 使用:允许拦截和自定义MyBatis执行器的行为。例如,可以添加缓存、日志记录或审计功能到执行器中。这些拦截器可以在MyBatis执行的不同阶段扩展或修改其行为。您可以通过实现MyBatis提供的相应接口并在MyBatis配置文件中进行配置来实现这些拦截器。
2. StatementHandler(语句拦截器):
-- 用途:拦截SQL语句的执行。
- 使用:可以在SQL语句执行之前修改或增强它们。例如,可以向WHERE子句添加额外的条件或记录执行的语句。分页等
3. ParameterHandler(参数拦截器):
- 用途:拦截SQL语句的参数设置。
- 使用:允许在将参数设置到SQL语句之前修改或验证它们。例如,可以对作为参数传递的敏感信息进行加密或解密。
4. ResultHandler(结果集拦截器):
- 用途:拦截从SQL语句返回的结果集的处理。
- 使用:可以在将结果集返回给应用程序之前修改或分析它们。例如,可以对结果集数据进行转换或执行额外的计算。
配置(@Intercepts注解--拦截执行器-拦截参数)
@Component
@Intercepts({@Signature(type = ParameterHandler.class, method = "setParameters", args = {PreparedStatement.class})})
public class ParameterPlugin implements Interceptor {ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget();Object parameterObject = parameterHandler.getParameterObject();//第一种,性能高// if(parameterObject instanceof BaseModel){// BaseModel baseModel = (BaseModel) parameterObject;// baseModel.setLastUpdateBy(LocalUserUtil.getLocalUser().getNickName());// }//第二种使用反射处理,扒光撕开Field lastUpdateBy = ReflectUtil.getField(parameterObject.getClass(), "lastUpdateBy");if (lastUpdateBy != null) {ReflectUtil.setFieldValue(parameterObject,lastUpdateBy,LocalUserUtil.getLocalUser().getNickName());}return invocation.proceed();}