目录
MyBatis是什么?
为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?
传统JDBC开发存在的问题
Mybatis是如何解决传统JDBC开发的问题的?
Hibernate 和 MyBatis 的区别
#{}和${}的区别
Mybatis中的缓存机制
Mybatis都有哪些Executor执行器?它们之间的区别是什么?
MyBatis是一个半自动的ORM(对象关系映射)持久层框架,支持定制化SQL。
之所以说mybatis是半自动的,是因为mybatis需要手动写sql。Hibernate属于全自动的,因为配置java bean和数据表的映射关系后,可以直接使用hql进行数据库操作,不需要编写sql;不过hql并不是万能的,对于某些复杂的查询场景会非常麻烦。
#{}是占位符,预编译处理;${}是拼接符,字符串替换,没有预编译处理。预编译就是传入的参数只会被当成值,因为会为参数加上单引号;而${}不会加单引号,参数可能会称为sql语句的一部分。
https://www.cnblogs.com/wuzhenzhao/p/11103043.html
mybatis中有一、二级缓存,默认一级缓存是开启的,开启二级缓存需要进行配置。mybatis查询数据的顺序是:二级缓存——>一级缓存——>数据库。
一级缓存
作用域:一级缓存的作用域是SqlSession,也就是数据库会话。项目中通常会创建多个SqlSession,它们之间是相互独立的,这意味着内部的缓存数据也是相互独立的。数据结构:SqlSession类有一个Executor属性,这个属性中维护了一个PerpetualCache对象,里面有一个HashMap,这个HashMap就是用来存储一级缓存数据的。缓存更新机制:当执行select语句时,会将查询结果存储在当前会话的一级缓存中;当执行更新操作(insert、update、delete)时,为了保证当前会话中缓存的一致性,当前会话中的缓存会失效。生命周期:一级缓存的生命周期是数据库会话的生命周期,当会话结束后,一级缓存也失效了。问题:若项目中存在多个会话,当一个会话在数据库中修改了另一个会话中缓存的数据,另一个会话就有可能读到脏数据。解决:mybatis一级缓存有两种:session和statement。可以把缓存模式改成statement(配置文件中配置),这样每次查询结束时会清理掉一级缓存(BaseExecutor的query方法)。二级缓存
作用域:二级缓存主要是为了解决一级缓存不能跨会话共享的问题,作用域是namespace,也就是一个mapper内的所有方法共享一份缓存,而所有mapper缓存对所有的会话都是共享的。数据结构或实现:SqlSession使用CachingExecutor执行sql语句,CachingExecutor是对普通Executor的装饰,查询时会先从会话外部指定的namespace缓存中进行查找,有就返回,没有就委托被装饰的Executor(执行器)进行查找,会先查找一级缓存,有就返回,没有就查询数据库,然后把数据添加到一级和二级缓存中。缓存更新机制:缓存添加和失效的机制和一级缓存一致。生命周期:和整个应用的生命周期一致。问题:跨namespace也可能会出现数据脏读的问题。解决:1.多个namespace共享一个缓存(如下)。2.关闭二级缓存。 <cache-ref namespace="其它命名空间" />