1、${} 和#{}的区别
${}是properties文件中的变量占位符,可用于标签属性值和sql内部,属于静态文本替换。如${drive}会被静态替换为com.mysql.jdbc.Drive
#{}是sql的参数占位符,mybatis会把sql中的#替换为?,当sql执行前会使用paeparedStatement的参数设置方法,按顺序给sql的?占位符设置参数值。
#{}可以最大程度的防止SQL注入。${}无法防止SQL注入。
mybatis排序order by 用${}。一般用于传入数据库对象,如表名,字段名。
#{}把传入的参数都当做字符串处理,会加上“”。
${}会把传入的参数直接显示生成到SQL中。
例子:
select * from table_name order by id.
如果用#{},SQL就变成了select * from table_name order by “id”;
如果用${},SQL就是select * from table_name order by id。
2、xml映射文件中,常见的标签有哪些?
<mapper>:每个映射文件的根标签,重点关注<mapper>的namespace属性
用于编写增删改查语句的标签:<select><insert><update><delete>
动态sql标签:trim|where|set|foreach|if|choose|when|otherwise
sql标签:<sql> 可以重用的SQL语句,可以被其他语句引用
<resultMap> 用于解决返回结果是多张表的情况,定义一个map
属性:
id:表示该标签的唯一标识
parameterType:输入参数类型
resultType:返回结果类型,一般是一个实体类
resultMap:返回结果类型是一个map,配合<resultMap>使用
3、mybatis xml映射文件里,不同xml映射文件id是否可以重复?
答:如果配置了namespace,那么id是可以重复的,如果没有配置namespace,那么id是不能重复。namespace+id是作为一个map的key使用的。
4、mybatis的一级缓存和二级缓存
答:(1)一级缓存
①、mybatis的一级缓存是指sqlsession,作用域是sqlsession,mybatis默认开启一级缓存。
②、在同一个sqlsession中,执行相同的查询SQL,第一次会去查询数据库,并把结果放在缓存里,第二次直接从缓存中取,如果两次SQL之间发生了增删改操作,则sqlsession的缓存清空。
(2)二级缓存
①、mybatis的二级缓存是指mapper映射文件,二级缓存的作用域是同一个namespace下的mapper映射文件内的内容,多个SQLsession共享,需要手动开启二级缓存。
②、同一个namespace下的mapper文件中,执行相同的SQL,第一次回去查询数据库,并写入缓存中,第二次则直接在缓存中取,如果两次SQL之间发生了增删改操作,则二级缓存清空。
5、mybatis是如何进行分页的?原理是什么?
答:mybatis是使用RowBounds对象进行分页的,它是针对ResultSet结果集执行的内存分页,而非物理分页。如果要物理分页可以在SQL内直接书写带有物理分页的参数来完成物理分页,也可以使用分页插件来完成物理分页。
分页插件的原理是使用mybatis提供的插件接口,实现自定义的插件,在插件的拦截方法内拦截待执行的SQL,然后重写SQL,根据方言,添加对应的物理分页语句和物理分页参数。
6、mybatis是否支持延迟加载?原理是什么?
答:mybatis仅支持一对一和一对多查询支持延迟加载,在配置文件中,可以配置是否启用延迟加载,lazyLoadingEnabled=true|false.
它的原理是,使用CGLIB创建目标对象的代理对象,当调用方法时,进入拦截器方法,比如a.getB().getName(),拦截器方法发现a.getB()是null,则先查询关联B对象的查询,把B查询出来,这B对象就有值了,再完成a.getB().getName(),这就是延迟加载的原理。
7、mybatis判断是否相等的情况的问题
当MyBatis 判断条件为等于的时候,常量需要加 .toString() 来转换,这种方法是稳定的,推荐使用,比如:
- <!-- 正确的,稳定,推荐使用 -->
- <if test="newsImage != null and newsImage == '1'.toString()">
- <![CDATA[ and len(newsImage) > 0 ]]>
- </if>