MyBatis常见面试题整理

${}和#{}的区别是什么?

${}是字符串替换,#{}是预编译处理。

Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

Mybatis在处理${}时,就是把${}原样替换成变量的值。

使用#{}可以有效的防止SQL注入,提高系统安全性。

当实体类中的属性名和表中的字段名不一样 ,怎么办 ?

方法一:通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。


方法二:通过 来映射字段名和实体类属性名的一一对应的关系。

模糊查询再MyBatis中怎么写

一般模糊查询都是通过 like %xx% 这种形式来查询的,xx是前端传过来的查询变量,在MyBatis中推荐使用字符串拼接函数的形式来使用,这样出错的可能性较小。


      and user_name like concat('%',#{xx,jdbcType=VARCHAR},'%')

MyBatis中的Mapper只有接口,那实现类是怎么生成的?当我们调用Mapper接口中的某个方法时,这个方法是怎么跟Mapper映射文件中的SQL语句对应起来的。

在使用MyBatis的时候我们只需要定义Mapper接口进行了,具体的Mapper接口实现是通过动态代理的方式生成的。

MyBatis在启动的时候会为每个Mapper映射文件指定一个MapperProxyFactory类,这个类是MapperProxy的工厂类,当我们调用sqlSession1.getMapper时,就会使用
MapperProxyFactory来生成动态代理类。生成的动态代理类代理了Mapper的所有接口。

CbondissuerMapper cbondissuerMapper10 = sqlSession1.getMapper(CbondissuerMapper.class);

下面来回答第二个问题,Mapper接口中的方法是怎么和映射文件中的SQL匹配起来的。

上面提到,Mapper接口的实现类是通过动态代理生成的,熟悉动态代理的应该知道调用Mapper接口的任何接口方法都会调到InvocationHandler接口的
invoke方法,在这里也就是MapperProxy的invoke方法。因为MapperProxy实现了InvocationHandler接口。

查看MapperProxy的invoke方法的源代码,我们会发现接口方法调用可具体的SQL是通过一个叫做MapperStatement的对象关联起来的。

MyBatis在启动时会将Mapper文件中的每一个