Mybatis面试题
1、Mybatis执行原理?
(1)程序启动时,会加载和解析Mybatis的配置文件(mybatis-config.xml)以及映射文件。配置文件信息存在Configuration对象中,映射文件信息存在MappedStatement对象中,MappedStatement绑定在Configuration中
(2)代码中的Mapper都是接口,实际上操作的是Mybatis通过JDK动态代理生成的代理对象。代理对象调用方法,触发MapperMethod执行具体逻辑。
(3)MapperMethod中有个SqlCommand属性,其通过调用的接口名+方法名,从Configuration中找到MappedStatement对象,此对象中有sql信息,最后是JDBC执行sql的流程。
2、Mybatis中的缓存?
Mybatis中有一级缓存和二级缓存,一级缓存是默认开启的,作用域是sqlSession,在一次会话中如果有相同的sql查询,后续的会从一级缓存中拿数据;二级缓存是默认关闭的,作用域是Mapper,对于不同的会话,只要是sql语句相同,那么后续的会从二级缓存中拿数据。一般我们是关闭一级缓存,开启二级缓存。在分布式架构中,二级缓存中数据的时效性是有问题的,要解决这个问题,可以重写Mybatis的cache接口中的方法,将查询数据放到第三方缓存中比如redis,然后再保证redis和数据库的一致性。
3、#{}和${}的区别?
(1)#{}是参数占位符,用于预处理语句中的参数。在执行SQL前,需要进行预编译,一般使用?符号替换sql语句中的#{},然后解析sql语句生成执行计划。最后在执行时,将#{}的参数绑定到?符号上。此时由于执行计划已经生成,代表sql语句的执行逻辑已经固定,如此可以有效防止sql注入。
(2)${}是字符串占位符,在生成执行计划前,会直接用值替换掉${},替换后的sql语句生成的执行计划可能与预想的不同,有sql注入的风险。