mybatis常见面试题
mybatis常见面试题
#{}和${}的区别是什么?
Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的 set方法来赋值;能够防止sql注入.
Mybatis 在处理{}替换成变量的值。
mybatis的一级缓存和二级缓存
1。缓存的作用
缓存的作用:减低数据源的访问频率。从而提高数据源的处理能力。或者提高服务器的响应速度
2。MyBatis中的缓存设计
-
MyBatis中的缓存的架构设计:装饰器模式
-
MyBatis中的一级缓存和二级缓存
-
一级缓存:session级别
一级缓存是SqlSession级别的缓存,它默认是开启的,当同一个sqlsession执行相同的sql语句时,会先从缓存中查找,如果找到了对应的结果。则直接返回缓存中的结果,而不会再次访问数据库。
在实际项目开发中一级缓存一般没有什么作用。
要关闭一级缓存:
<setting name = "localCacheScope" value = "STATEMENT"/>
//还有一个值是SESSION,也就是默认是开启的。 -
二级缓存:SqlSessionFactory级别
二级缓存是Mapper级别的缓存(说白了就是进程级别的缓存),它默认是关闭的。当不同的sqlsession执行相同的sql语句时,如果开启了二级缓存,则会先从缓存中查找,如果找到了对应的结果,则直接返回缓存中的结果,而不会再次访问数据库。
要开启二级缓存:
首先是在全局配置文件中设置:
<setting name = "cacheEnabled" value = "true"/>
然后要在具体的映射文件中设置cache标签
<cache/>
如果映射文件中的某个方法不想开启缓存可以设置useCache = "false"处理。
缺点:二级缓存在单体架构中是不会出现问题的,但是在集群架构中就可能会出现数据不一致的问题。
- 三级缓存:需要我们自定义实现,需要重写一个Cache接口。
缓存的设计
通过装饰模式实现缓存功能扩展
缓存的应用
一级缓存和二级缓存
一级缓存和二级缓存的顺序问题:先二级缓存再一级缓存
为什么会先走二级缓存再走一级缓存?
二级缓存的作用域是SqlSessionFactory级别-90%找到
一级缓存是SqlSession级别的-5%找到
一级缓存和二级缓存底层默认都是基于PerpetualCache来实现的,底层用的是HashMap.
MyBatis的一级缓存只适用于同一个SqlSession,因此它在多个SqlSession之间是无效的。这意味着如果您需要执行多个查询,并且这些查询需要在不同的SqlSession中执行,那么一级缓存就无法提供任何帮助。这种情况下,每次查询都需要从数据库中获取数据,因此缓存命中率为0。
MyBatis的SqlSession并不是线程安全的,因此在多线程环境下使用一级缓存可能会导致问题。如果两个线程共享同一个SqlSession,并且其中一个线程执行了一个查询,那么另一个线程可能会从缓存中获取到不正确的结果。因此,如果您在多线程环境中使用MyBatis,请确保每个线程都有自己的SqlSession。
MyBatis的一级缓存存储在内存中,因此如果您在应用程序中长时间使用同一个SqlSession,那么缓存中的数据可能会占用大量内存。这可能会导致内存泄漏问题,尤其是在长时间运行的应用程序中。
基于这些问题,我们可以看出MyBatis的一级缓存并不是最好的选择。因此,如果您需要缓存查询结果以提高性能,可以考虑使用二级缓存。
MyBatis的二级缓存是在多个SqlSession之间共享的,这意味着如果您在一个SqlSession中执行了更新、插入或删除操作,那么其他SqlSession中的缓存将会失效。但是,MyBatis并没有提供缓存同步机制,因此在更新、插入或删除操作之后,其他SqlSession中的缓存将不再可用,需要手动刷新才行。
当然,在我们的实际项目中,不管是一级缓存还是二级缓存,底层都是基于hashmap来实现的,很容易出现内存溢出。所以在实际项目开发中我们基本上不用。
Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么
底层基于CGLIB来实现。
说一下怎样进行优化mybatis批量操作
使用 ExecutorType.BATCH 执行器
- 原理
- MyBatis 默认的执行器是
SimpleExecutor
,它对于每一个 SQL 语句都会创建一个新的Statement
对象来执行。而BatchExecutor
执行器会将多个 SQL 语句添加到一个批处理中,然后一次性发送到数据库执行,这样可以减少数据库的通信开销。
- MyBatis 默认的执行器是
- 示例代码
- 在 MyBatis 的配置文件中,可以设置执行器类型为
BATCH
:
- 在 MyBatis 的配置文件中,可以设置执行器类型为
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.ExecutorType;
import java.util.List;
public class BatchInsertExample {
public void batchInsert(List<YourEntity> entityList, SqlSessionFactory sqlSessionFactory) {
try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
YourMapper mapper = sqlSession.getMapper(YourMapper.class);
for (YourEntity entity : entityList) {
mapper.insert(entity);
}
sqlSession.commit();
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
2023-09-09 visio设置文本框大小随内容自动调整
2020-09-09 反射技术实战
2020-09-09 使用反射技术操作类中的属性、对象及方法
2020-09-09 反射技术