10道不得不会的MyBatis面试题

简介: 10道不得不会的MyBatis面试题10道不得不会的MyBatis面试题

MyBatis

本系列《最少必要面试题》

1. 什么是MyBatis

这个问题主要是对比JDBC来看
  1. MyBatis是一个ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动,创建连接,创建statement等复杂的过程。开发人员不需要编写原生态sql,可以严格控制sql执行性能,灵活度高。
  2. MyBatis可以使用xml或者注解来配置映射原生信息,将POJO映射成数据库中的记录,避免了几乎所有的JDBC代码和手动设置的参数以及获取结果集。

2. MyBatis的优点

  1. 基于SQL语句编程,相对灵活(相对于hibernate),支持写动态sql语句并可重复使用。
  2. 减少代码量,消除了冗余代码。(类似于JDBC的封装)
  3. 与Spring完美集成。
  4. 提供映射标签支持字段关系映射。

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

  1. {}预编译处理、是占位符,${}是字符串替换、是拼接符。

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

Mybatis在处理#{}的时候会将sql中的#{}替换成?号,调用PreparedStatement来赋值

/* SQL */
如:select * from user where name = #{userName};设userName=javapub

看日志我们可以看到解析时将#{userName}替换成了 ?

select * from user where name = ?;

然后再把 javapub 放进去,外面加上单引号

Mybatis在处理${}的时候就是把${}替换成变量的值,调用Statement来赋值

/* SQL */
如:select * from user where name = #{userName};设userName=javapub

看日志可以发现就是直接把值拼接上去了

select * from user where name = javapub;

这极有可能发生sql注入,下面举了一个简单的sql注入案例

4. 一个 Xml 映射文件,都会写一个 Dao 接口与之对应,这个 Dao 接口的工作原理是什么?

Dao 接口就是人们常说的 Mapper 接口,接口的全限名,就是映射文件中的 namespace 的值,接口的方法名就是映射文件中 MappedStatement 的 id 值,接口方法内的参数就是传递给 sql 的参数。

接口里的方法是不能重载的,因为是全限名+方法名的保存和寻找策略。

Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行接口方法所对应的MappedStatement所代表的sql,然后将sql执行结果返回。

MappedStatement:MappedStatement维护了一条 <select|update|delete|insert>节点的封装,包括了传入参数映射配置、执行的SQL语句、结果映射配置等信息。

<select id="selectAuthorLinkedHashMap" resultType="java.util.LinkedHashMap">
        select id, username from author where id = #{value}
</select>

5. 如何获取自动生成的(主)键值?

用法:

<insert /> 标签中添加 useGeneratedKeys="true" 等属性

<insert id="insert" useGeneratedKeys="true" keyProperty="id" keyColumn="id"
        parameterType="person" >
    INSERT INTO person(name, pswd)
    VALUE (#{name}, #{pswd})
</insert>

当 Mybatis 解析 xml节点是,读到 insert 有配置时,会判断是否 有配置 useGeneratedKeys,如果有则会使用 Jdbc3KeyGenerator 作为sql回显,否则会以 NoKeyGenerator 作为主键回显。

底层封装了JDBC获取自增主键,即当使用 prepareStatement 或者 Statement时候,可以通过 getGeneratedKeys 获取 当条插入语句的自增而成的主键。例子

    Connection conn = DriverManager.getConnection(url, "root", "123456");
    String[] columnNames = {"id", "name"};
    PreparedStatement stmt = conn.prepareStatement(sql, columnNames);
    stmt.setString(1, "jack wang");
    stmt.executeUpdate();
    ResultSet rs = stmt.getGeneratedKeys();
    int id = 0;
    if (rs.next()) {
        id = rs.getInt(1);
        System.out.println("----------" + id);
    }

6. Mybatis 动态 sql 有什么用?有哪些动态 sql?执行原理?

Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。

Mybatis 提供了9种动态sql标签: trim | where | set | foreach | if | choose | when | otherwise | bind

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

是不是有点懵,继续阅读:

科普:

OGNL 是 Object-Graph Navigation Language 的缩写,对象-图行导航语言。例如 #{} 语法。

OGNL 作用是在对象和视图之间做数据的交互,可以存取对象的属性和调用对象的方法,通过表达式可以迭代出整个对象的结构图。

参考一个很形象的例子。

有一个学生对象 student,属性分别有 id = 10,name = '小明' 和 课程对象 course,其中 course 对象中属性有:分数 score = 88,排名 rank = 5。

对象关系图如下:

student

    id:10

    name:小明

    course:

        score:88

        rank:5

当上下文(环境)中的对象为 student 的时候,也就是在 Mybatis 中查询时传入的参数对象为 student 的时候:

通过 OGNL 表达式直接获取上下文中对象的属性值,比如:

{id} —> 10,相对于当前上下文对象.getId(),即 student.getId() 。

{name} —> 小明。

{course.score} —> 88,相当于 student.getCourse().getScore()。

所以,通过 OGNL 表达式,可以迭代出整个对象的结构图。

发布 《最少必要面试题》

7. 什么是Mybatis的一级、二级缓存?

一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认一级缓存是开启的。

当Mybaits与Spring整合的时候,不带Spring事务的方法内,每次请求数据库,都会新建一个SqlSession,这时候是使用不到一级缓存的。除了事务问题,还有调用了Sqlsession的修改、添加、删除、commit()、close()等方法时,一级缓存也会被清空。

二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace)。即使开启了二级缓存,不同的sqlsession之间的缓存数据也不是想互访就能互访的,必须等到sqlsession关闭了以后,才会把其一级缓存中的数据写入二级缓存。默认不打开二级缓存。

现在大多数应用都是支持分布式的,一般情况都是用中间件作为缓存层,比如redis。开启 MyBatis 的二级缓存也会多一步序列化和反序列化,影响服务性能。

8. MyBatis的工作原理

一图胜千文

在这里插入图片描述

  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 对结果集的解析过程。

9. 什么是MyBatis的接口绑定?有哪些实现方式?

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

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

  • 通过注解绑定,就是在接口的方法上面加上 @Select、@Update 等注解,里面包含Sql语句来绑定;
  • 通过xml里面写SQL来绑定, 在这种情况下,要指定xml映射文件里面的 namespace 必须为接口的全路径名。当Sql语句比较简单时候,用注解绑定, 当SQL语句比较复杂时候,用xml绑定,一般用xml绑定的比较多。

10. Mybatis的分页原理

Mybatis 使用 RowBounds 对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,所以一般不会使用。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

分页插件的原理就是使用 MyBatis 提供的插件接口,实现自定义插件,在插件的拦截方法内,拦截待执行的SQL,然后根据设置的 dialect(方言),和设置的分页参数,重写SQL ,生成带有分页语句的SQL,执行重写后的SQL,从而实现分页。

举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,10

在这里插入图片描述

低谷蓄力

《最少必要面试题》

10道不得不会的Java基础面试题

10道不得不会的MySQL基础面试题

10道不得不会的Java并发基础面试题

10道不得不会的JVM面试题

10道不得不会的ElasticSearch面试题

10道不得不会的Spring面试题

10道不得不会的 Redis 面试题

10道不得不会的 Kafka 面试题

10道不得不会的 MyBatis 面试题

10道不得不会的 Docker 面试题

目录
相关文章
|
6月前
|
缓存 Java 数据库连接
Mybatis缓存相关面试题有多卷
使用 MyBatis 缓存机制需要注意以下几点: 对于频繁更新和变动的数据,不适合使用缓存。 对于数据的一致性要求比较高的场景,不适合使用缓存。 如果配置了二级缓存,需要确保缓存的数据不会影响到其他业务模块的数据。 在使用缓存时,需要注意缓存的命中率和缓存的过期策略,避免缓存过期导致查询性能下降。
105 0
|
6月前
|
Java 关系型数据库 数据库连接
BATJ高频面试249道题:微服务+多线程+分布式+MyBatis +Spring
本文收集整理了各大厂常见面试题N道,你想要的这里都有内容涵盖:Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Spring、Spring Boot、Spring Cloud、RabbitMQ、Kafka、Linux 等技术栈,希望大家都能找到适合自己的公司,开开心心的撸代码。
|
5月前
|
SQL 缓存 Java
MyBatis最经典的20道面试题,你都会了吗?
MyBatis最经典的20道面试题,你都会了吗?
68 0
|
6月前
|
SQL 缓存 Java
Mybatis面试题
Mybatis面试题
|
4月前
|
SQL Java 数据库连接
Java面试题:简述ORM框架(如Hibernate、MyBatis)的工作原理及其优缺点。
Java面试题:简述ORM框架(如Hibernate、MyBatis)的工作原理及其优缺点。
77 0
|
6月前
|
存储 缓存 Java
什么!?实战项目竟然撞到阿里面试的原题!???关于MyBatis Plus的缓存机制
什么!?实战项目竟然撞到阿里面试的原题!???关于MyBatis Plus的缓存机制
|
6月前
|
SQL Java 数据库连接
MyBatis常见面试题总结2
MyBatis常见面试题总结
53 0
|
6月前
|
SQL Java 数据库连接
MyBatis常见面试题总结1
MyBatis常见面试题总结
64 0
|
6月前
|
SQL Java 数据库连接
答案很详细的MyBatis面试题(含示例代码)
MyBatis是一种优秀的持久层框架,它是一个轻量级的、优化的、功能强大的Java持久层框架,它的设计理念是贴近SQL、便于使用、高效并且功能丰富。通过MyBatis的使用,开发者能够更加专注于业务逻辑的实现,而不用过多关注底层的数据库操作。MyBatis通过XML或注解的方式配置SQL映射文件,并将Java的POJO(Plain Old Java Object,普通的Java对象)与数据库中的记录进行映射,使得开发人员能够以面向对象的方式来操作数据库,同时兼顾了SQL的灵活性和效率。灵活的SQL映射。
288 0
|
6月前
|
SQL Java 数据库连接
MyBatis常见面试题和答案(2020最新版)
MyBatis常见面试题和答案(2020最新版)
286 0