1. #{} 和 ${} 的区别
- #{} 是编译预处理,${} 是字符串替换
- mybatis在处理 #{} ,会将sql语句中的 #{} 替换为 ?,再调用PreparedStatement中的set方法进行赋值,可以有效防止sql注入,提高系统安全
- mybatis处理 ${} 时,会直接替换为变量的值,存在sql注入风险。
2. xml 映射文件中有哪些常用标签
resultMap : 描述如何从数据库结果集中加载对象
sql : sql片段,可被其它语句引用的可重用语句块
include: 引入sql 片段
selectKey: 对于某些不支持主键自增或者可能不支持主键自增的JDBC驱动 所引用的策略标签
动态sql中的
1)if
2)choose, 和其联用的when,otherwise
3)trim
- where
5) set
6) foreach
7) script
8) bind
3. mapper与xml之间的映射规则
- mapper接口的全限名,就是xml映射文件中namespace的值
- 接口中的方法名就是 MappedStatement中id的值,方法中的参数,就是传递给sql语句中的参数
- 当调用接口方法时,会以接口全限名 + 方法名拼接的字符串作为 key ,可以唯一确定一个MappedStatement
4. mapeer接口的工作原理
mapper接口的的工作原理是基于JD动态代理,MyBatis运行时使用JDK动态代理为Mapper接口生成代理对象(proxy),代理对象会拦截该接口中的方法,去执行MappedStatement所代表的sql,然后将sql执行结果返回
5. mapper中的接口可以重载吗?
接口中的方法可以重载,但是xml的配置文件中的ID不可以重复。也就是说重载方法都只对应一个MappedStatement, 因此要保证,无论调用哪一个重载后的方法,最终的sql语句没有语法错误并能正确执行。
6. mybatis 有几种分页
- 数组分页: 将查询出所有符合条件的结果集,再用subList截取结果集进行分页
- sql分页: 在sql语句中使用limit 进行分页
- 拦截器分页: 拦截所有需要进行分页的请求,然后在sql语句中统一加上limit 进行分页
- RowBounds分页: 在接口方法中添加RowBounds对象参数。
7. 逻辑分页和物理分页的区别
- 逻辑分页: 将所有满足条件的数据一次性从数据库查出加载到内存中,在内存中在逻辑上进行分页(数组分页,RowBounds分页)
- 物理分页:直接特定sql语句,从数据库中查询所需要的数据
- 物理分页的速度并不一定快于逻辑分页。
8. 请简述动态sql及其原理
- 动态sql即在xml映射文件中,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能
- 原理 利用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql
9. mybatis如何将sql执行结果的封装为目标对象并返回的
- 第一种 使用resultMap标签,逐一定义列名(column)和对象属性(property)之间的映射关系
- 第二种 使用sql列的别名。将列的别名设置为对象的属性名
- 有了列名别名之间的映射关系后,MyBatis通过反射创建对象,同时使用反射给对象的属性赋值并返回
10 mybatis是否支持延迟加载?
- mybatis仅支持association关联对象和collection关联集合的延迟加载
- 通过lazyLoadingEnabled = true/false进行配置
11. 不同的xml映射文件中,id是否可以重复
不同的xml映射文件,如果配置了namespace,id就可以重复。如果每页配置namespace,id就不能重复。
因为 namespace + id 是作为 Map<String, MappedStatement>中的key使用,如果配置了namespace,namespace不同,即使id相同,namespace + id 也是不同的,保证了key的唯一
12. mybatis的缓存机制
- 一级缓存
- 作用域为sqlSession,默认开启
- 一级缓存失效的情况
- 在不同的sqlSession中,有着不同的一级缓存
- 同一个sqlSession中,查询条件不同
- 同一个sqlSession两次查询期间执行了增删改操作
- 同一个sqlSession两次查询期间手动清空了缓存
- 二级缓存
- 作用域为Application, 默认不开启,需要在配置文件中设置开启
- 开启二级缓存后,实体类要实现序列化接口,且需要在映射文件中添加 标签 ,配置相关属性,或使用默认配置;并将select标签中设置useCache = true
- 二级缓存是多个sqlSession所共享的