MyBatis
我是 javapub,一名 Markdown
程序员从👨💻,八股文种子选手。
: 恭喜你进到面试的最后一个环节!你对 MyBatis 比较熟悉吗?
谢谢面试官!MyBatis 是我最喜欢且熟练使用的持久层框架之一。
: 那很好,我们从基础开始问吧。什么是 MyBatis?
MyBatis 是一款优秀的持久层框架,它内部封装了 JDBC,使开发者只需要关注 SQL 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。
: MyBatis 的工作原理能说一下吗?
MyBatis 的工作原理如下:
- 根据 XML 或注解的配置文件得到映射语句(也就是 SQL)。
- 把要调用的映射语句的参数传入并解析出 statement 中对应的占位符。
- 执行映射语句并得到结果。
- 把结果映射为 Java 对象并返回。
整个过程中最关键的部份是映射文件及映射过程。只有把 SQL 的执行结果映射成 Java 对象,才能达到 ORM 的目的。
: 那它的核心组件有哪些?
MyBatis 的核心组件主要有:
- SqlSessionFactoryBuilder:用于创建 SqlSessionFactory,gue有 XML 或注解来配置。
- SqlSessionFactory:SqlSession 的工厂,用于创建 SqlSession。
- SqlSession:用于执行映射语句并commit、rollback 事务。
- Mapper 接口:用于定义映射语句(也就是 SQL),下面会详细解释。
- 映射文件:包含了映射语句,可以是 XML 或注解。
: 既然你提到了 Mapper 接口,那它是什么?
Mapper 接口是 MyBatis 中非常重要的一个组件。它是由开发人员创建的接口,其中的方法直接对应映射文件中的 SQL 语句。 举个例子:
public interface UserMapper {
User selectUser(int id);
}
然后在映射文件中:
<select id="selectUser" resultType="User">
select * from user where id = #{id}
</select>
之后我们可以直接调用:
User user = session.getMapper(UserMapper.class).selectUser(1);
这样直接调用 Mapper 接口的方法就可以执行对应的 SQL 了,很方便。
: 动态 SQL 又是什么?
MyBatis 的动态 SQL 是非常强大的一个功能。它允许开发人员在 XML 映射文件中直接插入一些逻辑,如:
- if/else 分支
- 动态选择部分内容
- 提取重复代码块
举个例子:
<select id="findActiveBlogWithTitleLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE'
<if test="title != null">
AND title like #{title}
</if>
</select>
这里通过 <if>
标签实现了动态条件查询。只有在方法调用时传入了 title 参数,SQL 语句才会添加 title 的条件判断。 这样的动态 SQL 使得数据库交互更加灵活,不需要在程序中进行大量的字符串拼接。
: 最后两个问题,MyBatis 的缓存机制和插件机制能说一下吗?
- MyBatis 包含一级缓存和二级缓存。
- 一级缓存是 SqlSession 级别的缓
- 一级缓存是 SqlSession 级别的缓存,在同一个 SqlSession 中多次调用同一个 Mapper 的方法,MyBatis 会直接从缓存中获取数据。
- 二级缓存是 Mapper 级别的缓存,多个 SqlSession 去调用同一个 Mapper 的方法,MyBatis 会先去二级缓存中查找是否有数据,有的话直接返回,没有的话再查询数据库。
- MyBatis 的插件机制也很强大。我们可以通过实现 Interceptor 接口来编写插件,用于执行一些增强操作,比如:
- 分页助手:通过拦截执行的 SQL 语句实现物理分页
- 监控日志:监控 SQL 执行时间过长等
- 读写分离:根据方法的注解实现读写分离 举个简单例子:
public class MyFirstPlugin implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 调用方法之前
Object result = invocation.proceed();
// 调用方法之后
return result;
}
}
然后在配置文件中进行配置:
<plugins>
<plugin interceptor="org.mybatis.example.MyFirstPlugin">
<property name="someProperty" value="100"/>
</plugin>
</plugins>
就可以启动对所有 SQL 执行的拦截了。
: MyBatis 的内容我们就先讲到这里,你对它的理解很深入,加油!期待你加入我们团队!
非常感谢面试官的赏识!我会继续努力学习,不断提高自己。也很期待加入贵团队一起成长!
最近我在更新《面试1v1》系列文章,主要以场景化的方式,讲解我们在面试中遇到的问题,致力于让每一位工程师拿到自己心仪的offer,感兴趣可以关注公众号JavaPub追更!
🎁目录合集:
Gitee:https://gitee.com/rodert/JavaPub
GitHub:https://github.com/Rodert/JavaPub