Mybatis面试题

1、Mybatis工作原理

        Mybatis面试题_第1张图片

        (1) 读取Mybatis配置文件。mybatis-config.xml 为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息。

        (2)加载映射文件。映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

        (3)构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。

        (4)创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。

        (5)Executor 执行器:MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。

        (6)MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。

        (7)输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。

        (8)输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程

2、Mybatis编程步骤

        (1)创建SQLSessionFactory对象

        (2)通过SQLSessionFactory获取SQLSession对象

        (3)通过SqlSession获得Mapper代理对象

        (4)通过Mapper代理对象,执行数据库操作

        (5)执行成功,则使用SQLSession提交事务

        (6)执行失败,则使用SQLSession回滚事务

        (7)关闭会话

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

        #{}是SQL的参数占位符,Mybatis会将SQL中的#{}替换为?号,在SQL执行前会使用PreparedStatement的参数设置方法。#{}是预编译处理,可以有效防止SQL注入,提高系统安全性。

        ${}是Properties文件中的变量占位符,它可以用于XML标签属性值SQL内部,属于字符串替换

4、Mybatis缓存

        Mybatis中有一级缓存和二级缓存,默认情况下一级缓存是开启的,而且是不能关闭的。

        一级缓存是指 SqlSession 级别的缓存,当在同一个 SqlSession 中进行相同的 SQL 语句查询时,第二次以后的查询不会从数据库查询,而是直接从缓存中获取,一级缓存最多缓存 1024 条 SQL。

        二级缓存是指可以跨 SqlSession 的缓存。是 mapper 级别的缓存,对于mapper 级别的缓存不同的sqlsession 是可以共享的。

5、一级缓存原理(SqlSession级别)

        Mybatis面试题_第2张图片

        第一次发出一个查询 sql,sql 查询结果写入 sqlsession 的一级缓存中,缓存使用的数据结构是一个 map。

        同一个 sqlsession 再次发出相同的 sql,就从缓存中取出数据。如果两次中间出现 commit 操作 (修改、添加、删除),本 sqlsession 中的一级缓存区域全部清空,下次再去缓存中查询不到,所以要从数据库查询,从数据库查询到再写入缓存 。

6、二级缓存原理(Mapper级别)

        

Mybatis面试题_第3张图片

        二级缓存的范围是 mapper 级别,mapper 以命名空间为单位创建缓存数据结构,结构是 map。mybatis 的二级缓存是通过 CacheExecutor 实现的。所有的查询操作,在 CacheExecutor 中都会先匹配缓存中是否存在,不存在则查询数据库。

7、接口绑定有几种实现方式,分别是怎么实现的?

        接口绑定,就是在MyBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,我们直接调用接口方法就可以,这样比起原来了SqlSession提供的方法我们可以有更加灵活的选择和设置。

        接口绑定有三种实现方式:

        1)通过XML Mapper里面写SQL来绑定。在这种情况下,要指定XML映射文件里面的"namespace"必须为接口的全路径名。

        2)通过注解绑定,就是在接口的方法上面加上@Select、@Update、@Insert、@Delete注解,里面包含SQL语句来绑定。

        3)是第二种的特例,也是通过注解绑定,在接口的方法上面加上@SelectProvider、@UpdateProvider、@InsertProvider等注解,通过java代码生成对应的动态SQL。

8、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?

        Mybatis仅支持association关联对象和collection关联集合对象的延迟对象。其中association指的是一对一,collection指的是一对多查询。在Mybatis配置文件中,可以配置来启用延迟加载的功能。默认情况下,延迟加载的功能是关闭的。

        它的原理是:使用CGLIB或Javassist创建目标对象的代理对象。当调用代理对象的延迟加载属性的getting方法时,进入拦截器方法。比如调用a.getB().getName()方法,进入拦截器的invoke(...)方法,发现 a.getB() 需要延迟加载时,那么就会单独发送事先保存好的查询关联 B 对象的 SQL ,把 B 查询上来,然 后调用 a.setB(b) 方法,于是 a 对象 b 属性就有值了,接着完成 a.getB().getName() 方法的调用。这就 是延迟加载的基本原理。

9、Mybatis是如何进行分页的?分页插件的原理是什么?

        Mybatis使用Rowbounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非数据库分页。

        所以,实际场景下不适合直接使用Mybatis原有的RowBounds对象进行分页。而是使用如下两种方案:

        1、在SQL内直接书写带有数据库分页的参数来完成数据库分页功能

        2、也可以使用分页插件来完成数据库分页。

这两者都是基于数据库分页,差别在于前者是工程师手动编写分页条件,后者是插件自动添加分页条件。

        分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义分页插件。在插件的拦截方法内,拦截待执行的SQL,然后重写SQL,根据dialect(方言),添加对应的物理分页语句和物理分页参数。

        举例:SELECT * FORM student,拦截SQL后重写为:SELECT * FROM student LIMI 0,10;

10、Mybatis动态SQL是做什么的?都有哪些动态SQL?简述动态SQL的执行原理?

        Mybatis动态SQL是Mybatis的强大特性之一,可以让我们在XML映射文件内,以XML标签的形式编写动态SQL,完成逻辑判断和动态拼接SQL的功能。

        Mybatis提供了9种动态SQL标签:

        其执行原理为,使用 OGNL 的表达式,从 SQL 参数对象中计算表达式的值,根据表达式的值动态拼接 SQL ,以此来完成动态 SQL 的功能。

11、Mybatis的XMLMapper文件中,不同的XML映射文件,id是否可以重复?

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

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

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

        第一种, 通过在查询的 SQL 语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。代码如下:

        第二种,是第一种的特殊情况。大多数场景下,数据库字段名和实体类中的属性名差,主要是前者为下划线风格,后者为驼峰风格。在这种情况下,可以直接配置如下,实现自动的下划线转驼峰的功能。


    

        第三种,通过 来映射字段名和实体类属性名的一一对应的关系。代码如下:


    
    
    
    
    


13、简述 Mybatis 的 XML 映射文件和 Mybatis 内部数据结构之间的映射关系?

       Mybatis 将所有 XML 配置信息都封装到 All-In-One 重量级对象Confifiguration内部。

        在 XML Mapper 文件中:

        1) 标签,会被解析为 ParameterMap 对象,其每个子元素会被解析为 ParameterMapping 对象。
        2)标签,会被解析为ResultMap对象,其每个子元素会被解析为ResultMapping 对象。
        3)每一个 SELECT * FROM students LIMIT #{start}, #{end}

        2、保持传递多个参数,使用@Param注解。代码如下:

// 调用方法
return studentMapper.selectStudents(0, 10);

// Mapper 接口
List selectStudents(@Param("start") Integer start, @Param("end") Integer end);

// Mapper XML 代码

        3、保持传递多个参数,不使用 @Param 注解。代码如下:

// 调用方法
return studentMapper.selectStudents(0, 10);

// Mapper 接口
List selectStudents(Integer start, Integer end);

// Mapper XML 代码
      

你可能感兴趣的:(java,java,面试,mybatis)