Mybatis 模块面试题
#{}和${}的区别
前者预编译的占位符 后者是直接替换为字符串。后者不安全,可能能被进行SQL注入
具体的执行过程如下:
- 将SQL语句中的#{}替换为问号(?)。
- 创建PreparedStatement对象,将替换后的SQL作为参数传递给它
- 通过PreparedStatement的setXXX()方法,将参数值按照对应的位置绑定到问号上。XXX表示参数的数据类型,比如setInt()、setString()等。
- 执行PreparedStatement的executeQuery()或executeUpdate()方法,将绑定好的SQL语句发送到数据库进行执行。
缓存
一级缓存
本地缓存 (sqlsession级别的)PerpetualCache,HashMap 存储
具体流程:
第一次执行 select 完毕会将查到的数据写入 SqlSession 内的 HashMap 中缓存起来
第二次执行 select 会从缓存中查数据,如果 select 同传参数一样,那么就能从缓存中返回数据,不用去数据库了,从而提高了效率
注意:
如果 SqlSession 执行了 DML 操作(insert、update、delete),并 commit 了,那么 mybatis 就会清空当前 SqlSession 缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现差异
二级缓存
mapper 级别的缓存,也就是同一个 namespace 的 mapper.xml ,当多个 SqlSession 使用同一个 Mapper 操作数据库的时候,得到的数据会缓存在同一个二级缓存区域
具体流程:
1.当一个
sqlseesion执行了一次select后,在关闭此session的时候,会将查询结果缓存到二级缓存2.当另一个
sqlsession执行select时,首先会在他自己的一级缓存中找,如果没找到,就回去二级缓存中找,找到了就返回,就不用去数据库了,从而减少了数据库压力提高了性能
Dao接口方法不可以重载
MyBatis后,DAO层方法不能重载了。因为MyBatis将将接口中方法解析后构造成了MappedStatement对象后,在设置其id属性时,传递的值是接口名 + “.” + 方法名(Java中的方法重载规则是方法名相同,但参数类型或参数位置不同)。而在StrictMap的put方法中,会先判断容器中是否已包含相同key,如果已包含就抛出异常,而不是覆盖已有值。