Mybatis面试题汇总

参考前人,因为参考的比较多,所以难以一一写出,后续会继续补充,

目录

1.对MyBatis的理解:

2.Mybatis的优缺点:

3.Mybatis的编程步骤:

4.为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

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

6.Statement和PrepareStatement的区别:

7.Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

8.当实体类中的属性名与数据表中的字段名不同时,如何解决?

9.Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?

10.如何获取自动生成的(主)键值:

11.模糊查询like语句该怎么写?

12.在mapper中如何传递多个参数?

13.Mybatis动态sql是做什么的?都有哪些动态sql?简述一下动态sql的执行原理:

14.一对一、一对多的关联查询 ?

15.使用MyBatis的mapper接口调用有哪些要求:

16.通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?

17.Mybatis缓存:

18.Mybatis和Hibernate的区别


1.对MyBatis的理解:

(百度百科)MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录

 mybatis把sql语句从Java源程序中独立出来, 放在单独的XML文件中编写,给程序的维护带来了很大便利。 ibatis封装了底层JDBC API的调用细节,并能自动将结果集转换成Java Bean对象, 大大简化了Java数据库编程的重复工作。 因为Ibatis需要程序员自己去编写sql语句, 程序员可以结合数据库自身的特点灵活控制sql语句, 因此能够实现比hibernate等全自动orm框架更高的查询效率,能够完成复杂查询

2.Mybatis的优缺点:

  • 优点
  1. 易于上手和掌握
  2. Sql写在xml里面,便于统一管理和优化
  3. 减少Sql与程序代码的耦合
  4.  提供xml标签,支持动态Sql编写  
  • 缺点
  1.     Sql工作量大,尤其是字段多,关联表多时,更是如此
  2.     Sql依赖于数据库,导致数据库移植性差
  3.     由于xml里面标签id必须唯一,导致DAO中方法不支持方法重载。所以dao层必须是接口
     

3.Mybatis的编程步骤:

  1. 创建SqlSessionFactoryBuilder

  2. 通过SqlsesionFactoryBuilder创建sqlSessionFactory

  3. 通过SqlSessionFactory创建sqlSession  

  4. 通过sqlSession执行数据库操作

  5. 调用session.commit()提交事务

  6.  调用session.close()关闭会话

4.为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。

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

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

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

  3. Mybatis在处理${}时,就是把${}替换成变量的成变量的值,使用#{}可以有效的防止SQL注入,提高系统安全性

6.Statement和PrepareStatement的区别:

  1.   PreparedStatement:表示预编译的 SQL 语句的对象。

  2.   PrepareStatement可以使用占位符,是预编译的,批处理比Statement效率高

  3.   在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。

  4.  PreparedStatement的第一次执行消耗是很高的. 它的性能体现在后面的重复执行

7.Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

  • 第一种:使用标签,逐一定义列名和对象属性名之间的映射关系
  • 第二种:使用sql列的别名功能,将列别名书写为对象属性名,比如T_NAME AS NAME,对象属性名一般是name,小写,但是列名不区分大小写,Mybatis会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成T_NAME AS NaMe,Mybatis一样可以正常工作
  • 有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。(会报错no XXXSetter)

8.当实体类中的属性名与数据表中的字段名不同时,如何解决?

  • 解决方式1:

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

  
  • 解决方式2:

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



 

         

         

         

         

         


9.Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?

不同的Xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复;毕竟namespace不是必须的,只是最佳实践而已。

原因就是namespace+id是作为Map的key使用的,如果没有namespace,就剩下id,那么,id重复会导致数据互相覆盖。有了namespace,自然id就可以重复,namespace不同,namespace+id自然也就不同。

10.如何获取自动生成的(主)键值:

  •    解决思路:通过LAST_INSERT_ID()获取刚插入记录的自增主键值,在insert语句执行后,执行select LAST_INSERT_ID()就可以获取自增主键(mysql)
        
     
                  
     
                     select LAST_INSERT_ID()
     
                  
     
              INSERT INTO USER(username,birthday,sex,address)
     
              VALUES(#{username},#{birthday},#{sex},#{address)
     
         

11.模糊查询like语句该怎么写?

 
  1. 表达式: name like"%"#{name}"%" #起到占位符的作用

  2. 表达式: name like '%${name}%' $进行字符串的拼接,直接把传入的值,拼接上去了,没有任何问题

  3. 表达式: name likeconcat(concat('%',#{username}),'%') 这是使用了cancat进行字符串的连接,同时使用了#进行占位

  4. 表达式: name like CONCAT('%','${name}','%') 对上面的表达式进行了简化,更方便了

12.在mapper中如何传递多个参数?

  • 第1种:
//DAO层的函数
Public UserselectUser(String name,String area);  

//对应的xml,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,更多参数一致往后加即可。
  • 第2种: 使用 @param 注解:
import org.apache.ibatis.annotations.param; 
public interface usermapper { 
         user selectuser(@param(“username”) string username, 
         @param(“hashedpassword”) string hashedpassword); 
        }

 

13.Mybatis动态sql是做什么的?都有哪些动态sql?简述一下动态sql的执行原理:

Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。
Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind。(需熟练用法)
其执行原理为,从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。

14.一对一、一对多的关联查询 ?

整体思想:

  1. 本表中一条数据对应另一张表中数据条数判断两表间关系为一对一还是一对多;
  2. 如一对一,则在实体类中存另一表对应实体类对象作为成员变量,如一对多关系,则在本实体类中存另一表对应实体类对象的集合作为成员变量;
  3. 在mapper文件中,将两表的关系进行对应描述,
  
      
      
      
          
          
          
          
              
              
          
      

      
      
      
          
          
          
              
              
          
          
              
              
          
      

  

15.使用MyBatis的mapper接口调用有哪些要求:

  1. Mapper接口方法名和mapper.xml中定义的每个sql的id相同

  2. Mapper接口中输入的参数类型和mapper.xml中定义的每个sql的ParameterType相同

  3. Mapper接口中输出的参数类型和mapper.xml中定义的每个sql的resultType相同

  4. Mapper.xml文件中的namespace即是接口的类路径

16.通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?

  • Dao接口即Mapper接口,接口的全限名也就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。(mapper自动代理的四个规则)

  • Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement,举例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。在Mybatis中,每一个