# Lagou-Assignments **Repository Path**: javis_code/Lagou-Assignments ## Basic Information - **Project Name**: Lagou-Assignments - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-04-04 - **Last Updated**: 2021-11-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 编程题 单元测试位置:gosh-query-test/src/test/java/com/gosh/AssignmentTest.java 实现代码入口位置:gosh-query/src/main/java/com/gosh/sqlsession/SqlSessionFactoryBuilder.java # 简单题 #### 1、Mybatis动态sql是做什么的?都有哪些动态sql?简述一下动态sql的执行原理? Mybatis动态sql作用是根据入参预编译出sql,在传统的jdbc操作中,根据条件进行sql拼接很容易出错,而mybatis的动态sql会做一些特殊操作,例如``标签,无需为了后面的`and`条件预先写上1=1,mybatis会自动处理判断什么时候追加`where` 动态sql标签有 | 标签 | 作用 | | ---- | ---- | | if | 判断语句 | | choose(when、otherwise) | 与Java if else相似 | | trim(where,set) | 辅助元素,用于拼接SQL条件语句(前缀或后缀的添加与忽略) | | foreach | 循环(批量插入、查询时常用) | | bind | 绑定一个变量,可用于上下文 | | set | 用于update | | where | 用于查询 | | sql | 把通用的sql抽取出来作为一个常量 | | include | 引入sql标签 | 动态sql执行原理: 1. SqlSessionFactory初始化时对配置文件mapper标签进行解析(configurationElement()) 2. buildStatementFromContext()创建XMLStatementBuilder并对节点进行解析 3. 解析过程中把sql分别解析成多个sqlNode并保存到对应实现中,最后一并封装成MappedStatement并保存到Configuration的MappedStatementMap中 4. 调用SqlSession操作数据库时,Executor会调用SqlNode中的apply方法进行sql拼接 5. 最后通过GenericTokenParser将sql转换成标准的jdbc sql,并进行参数设置 #### 2、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么? 支持,使用association或者collection进行对象关联,当用到相关的对象时再去进行查询。 实现原理主要使用Javassist或Cglib,调用关联对象方法时会进行拦截查询关联对象 #### 3、Mybatis都有哪些Executor执行器?它们之间的区别是什么? | 执行器 | 作用 | | ---- | ---- | | BaseExecutor | Executor最顶层的实现,实现了大部分通用功能,定义了doUpdate、doFlushStatements、doQuery、doQueryCursor抽象方法由子类进行实现 | | SimpleExecutor | 最简单的BaseExecutor实现,进行了jdbc创建连接,执行sql,关闭连接等基础操作 | | BatchExecutor | 基于JDBC的addBatch、executeBatch功能实现批处理操作 | | CachingExecutor | 支持二级缓存的 Executor 的实现类 | | ClosedExecutor | 已经关闭了的执行器 | | ReuseExecutor | 比SimpleExecutor多了缓存| #### 4、简述下Mybatis的一级、二级缓存(分别从存储结构、范围、失效场景。三个方面来作答)? | 缓存 | 存储结构 | 范围|失效场景 | ---- | ---- | | 一级缓存 | map|Session|当sqlSession调用close()方法就会失效 | 二级缓存 | 没局限,可自定义实现或使用第三方缓存实现|Application级别基于mapper文件的namespace,多个sqlsession可以共享同一个mapper中的二级缓存区域| #### 5、简述Mybatis的插件运行原理,以及如何编写一个插件? 原理: 1. MyBatis在初始化的时候会从配置文件中解析`interceptor`标签收集所有的插件 2. 创建四大对象(ResultSetHandler、StatementHandler、ParameterHandler、Executor)时不是直接返回,而是通过interceptorChain.pluginAll(parameterHandler),执行完所有Interceptor.plugin才返回target包装后的对象 编写一个插件的流程: 1. 实现`Interceptor`接口 2. 类名上注解`@Intercepts`并定义需要拦截的对象、方法、以及方法重载的入参 3. 在mybatis配置文件中注册当前插件的全类名,并且可以自定义入参