MyBatis常见面试问题
# MyBatis 常见面试问题
# 1. #{}和${}的区别是什么?
#{}
是将传入的值按照字符串的形式进行处理,如:
select user_id,user_name from t_user where user_id = #{user_id}
MyBatis首先会进行预编译,将#{user_id}替换成?占位符,然后在执行时替换成实际要传入的user_id值,可以防止SQL注入。
${}
是做简单的字符串替换,MyBatis只会创建普通的SQL语句,将传入的值直接拼到SQL语句中,如:
select user_id,user_name from t_user where user_id = ${user_id}
# 2. 既然$不安全,为什么还需要$,什么时候会用到它?
它可以解决一些特殊情况下的问题。例如,在一些动态表格中(根据不同的条件产生不同的动态列),我们要传递SQL的列名,根据某些列进行排序,或者传递列明给SQL都是比较常见的场景,这就无法使用预编译的方式了。
# 3. MyBatis的xml文件和Mapper接口是怎么绑定的?
是通过xml文件中,<mapper>
根便签的namespace属性进行绑定的,即namespace属性的值需要配置成接口的全限定类名,MyBatis内部就会通过这个值将这个接口与整个xml关联在一起。
# 4. MyBatis分页和自己写的分页哪个效率高?
自己写的分页效率高。
在Mybatis中,可以通过分页插件实现分页,也可通过分页SQL自己实现分页。分页插件的原理是,拦截查询SQL,在整个SQL基础上自动为其添加LIMIT分页条件。它会大大提高开发的效率,但是无法对分页语句做出有针对性的优化,比如分页偏移量很大的情况,而这些在自己写的分页SQL里却是可以灵活实现的。
# 5. MyBatis的缓存机制?
MyBatis分为一级缓存和二级缓存。
一级缓存:
也称本地缓存,默认开启,不能关闭。一级缓存存在于SqlSession的生成周期中,即它是SqlSession级别的缓存。在同一个SqlSession中查询时,MyBatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对象中。如果同一个SqlSession中执行的方法和参数完全一致,,那么通过算法会生成相同的键值,当Map缓存对象中已经存在该键值时,则会返回缓存中的对象。
二级缓存:
二级缓存存在于SqlSessionFactory的生命周期中,即它是SqlSessionFactory级别的缓存。若想使用二级缓存,需要配置。
MyBatis的二级缓存是和命名空间绑定的,即二级缓存需要配置在Mapper.xml映射文件中。在保证二级缓存的全局配置开启的情况下,给Mapper.xml开启二级缓存只需要在Mapper.xml中添加<cache />
。
ORM:Object Relational Mapping,用于实现面向对象编程语言里不同类型系统的数据之间的转换