本文的所有题目均从网络整理
Mybatis
1. #{ } 和 ${ }两种占位符的区别
- #{ }是预编译处理,Mybatis在处理时,会将sql语句中的 #{ } 替换为 ? 号,调用PreparedStatement的set方法来赋值,可以防止sql注入。效率更高。
- ${ } 是字符串替换,Mybatis在处理时,就是把 ${ } 替换成变量的值。适用于替换属性名的情况。可能参数sql注入。
2. DAO接口为什么不需要实现类,它的工作原理。
- DAO接口有一个对应名称相同的xml映射文件,将DAO接口中的方法与对应sql语句绑定(或者直接在接口方法上使用注解方式绑定sql语句)。Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,因此不需要实现类,代理对象proxy会拦截接口方法,转而执行该方法所代表的sql,然后将sql执行结果返回。Dao接口里的方法,是不能重载的,因为使用全限名+方法名绑定唯一sql语句。
3. Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
- 第一种是使用< resultMap >标签,逐一定义列名和对象属性名之间的映射关系。
- 第二种是使用sql列的别名功能,将列别名书写为对象属性名。
- 有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,无法完成赋值。
4. Mybatis的一级缓存和二级缓存
- 一级缓存(本地缓存)的作用域是SQL Session,在同一个SqlSession中,执行查询语句时,会先在SqlSession的缓存中去查找,若存在则直接取出;否则去数据库中查找,并把查找结果写在缓存中。在执行insert、update、delete后会清除该缓存。该缓存使用HashMap数据结构,key为hashcode+statementId+sql语句,value为查询结果。
- 二级缓存(全局缓存)的作用域时Mapper,即一个作用于一个映射文件下的所有语句,默认关闭。可以在配置xml映射文件中开启。
<cache
eviction="FIFO" <!--默认清除策略为 LRU-->
flushInterval="60000" <!--刷新间隔, 默认不设置, 只在调用语句时刷新-->
size="512" <!--引用数量, 默认1024-->
readOnly="true"/> <!--只读-->
- 也可以使用自定义缓存类,该类必须实现 org.apache.ibatis.cache.Cache 接口,且提供一个接受 String 参数作为 id 的构造器。
<cache type="com.domain.something.MyCustomCache"/> <!--声明使用自定义缓存-->