Zeros Tech Zeros Tech
首页
架构
大数据
数据库
  • 面试

    • Java面试
    • 大数据面试
    • 架构面试
语言
运维
关于
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

迹_Jason

全栈工程师
首页
架构
大数据
数据库
  • 面试

    • Java面试
    • 大数据面试
    • 架构面试
语言
运维
关于
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 面试

    • 架构面试

    • 大数据面试

    • Java

      • JVM面试
      • JVM垃圾回收面试题
      • Java多线程面试
      • JVM优化面试
      • HashMap面试
      • ConcurrentHashMap面试
      • ThreadLocal面试
      • MySQL面试题
      • Mongo 面试题
      • Redis面试题
      • IO面试题
      • Mybatis 面试题
        • 拓展
      • Spring面试题
      • 算法面试题
  • 技术
  • 面试
  • Java
迹_Jason
2021-02-08

Mybatis 面试题

# Mybatis 面试

# 什么是 ORM 框架?

用于实现面向对象编程语言里不同系统的数据之间的转换

# 什么是 MyBatis?

答:MyBatis 是一个可以自定义 SQL、存储过程和高级映射的持久层框架。

# 讲下 MyBatis 的缓存?

答:MyBatis 的缓存分为一级缓存和二级缓存,一级缓存放在 session 里面,默认就有,二级缓存放在它的命名空间里,默认是不打开的,使用二级缓存属性类需要实现 Serializable 序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/>

https://www.cnblogs.com/cxuanBlog/p/11333021.html#%E4%BA%8C%E7%BA%A7%E7%BC%93%E5%AD%98%E5%BC%80%E5%90%AF%E6%9D%A1%E4%BB%B6 (opens new window)

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

1)、Mybatis 使用 RowBounds 对象进行分页,也可以直接编写 sql 实现分页,也可以使用 Mybatis 的分页插件。

2)、分页插件的原理:实现 Mybatis 提供的接口,实现自定义插件,在插件的拦截方法内拦 截待执行的 sql,然后重写 sql。

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

# Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql 的执行原理不? 答:

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

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

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

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

  1. #{} 是预编译处理,${} 是字符串替换。
  2. Mybatis 在处理 #{} 时,会将 sql 中的#{}替换为 ? 号,调用 PreparedStatement 的 set 方法来赋值;
  3. Mybatis 在处理 ${} 时,就是把 ${} 替换成变量的值。 #{} 会有数据类型的处理,比如字符串会加引号处理,当替换表名这类场景时,就会存在问题,需要使用 ${}
  4. 使用 #{} 可以有效的防止 SQL 注入,提高系统安全性。

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

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

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

  1. Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的就是一对一,collection 指的就是一对多查询。在 Mybatis 配置文件中,可以配置是否 启用延迟加载 lazyLoadingEnabled=true|false。

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

# 什么是 MyBatis 的接口绑定,有什么好处?

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

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

第一种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系。

第二种是使用 sql 列的别名功能,将列别名书写为对象属性名,比如 T_NAME AS NAME,对 象属性名一般是 name,小写,但是列名不区分大小写,Mybatis 会忽略列名大小写,智能 找到与之对应对象属性名,你甚至可以写成 T_NAME AS NaMe,Mybatis 一样可以正常工 作。

有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时使用反射给对象的属性 逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

# 当实体类中的属性名和表中的字段名不一样,如果将查询的结果封装到指定 pojo?

  1. 通过在查询的 sql 语句中定义字段名的别名。

  2. 通过<resultMap>来映射字段名和实体类属性名的一一对应的关系。

# 模糊查询 like 语句该怎么写

  1. 在 java 中拼接通配符,通过#{}赋值
  2. 在 Sql 语句中拼接通配符 (不安全 会引起 Sql 注入)

# Mybatis 中如何执行批处理?

使用 BatchExecutor 完成批处理。

# Mybatis 都有哪些 Executor 执行器?它们之间的区别是什么?

Mybatis 有三种基本的 Executor 执行器,SimpleExecutor、ReuseExecutor、 BatchExecutor。

  1. SimpleExecutor:每执行一次 update 或 select,就开启一个 Statement 对 象,用完立刻关闭 Statement 对象。

  2. ReuseExecutor:执行 update 或 select,以 sql 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后,不关闭 Statement 对象, 而是放置于 Map

  3. BatchExecutor:完成批处理。

# Mybatis 中如何指定使用哪一种 Executor 执行器?

在 Mybatis 配置文件中,可以指定默认的 ExecutorType 执行器类型,也可以手动给 DefaultSqlSessionFactory 的创建 SqlSession 的方法传递 ExecutorType 类型参数。

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

配置文件设置 usegeneratedkeys 为 true

# resultType resultMap 的区别?

  1. 类的名字和数据库相同时,可以直接设置 resultType 参数为 Pojo 类

  2. 若不同,需要设置 resultMap 将结果名字和 Pojo 名字进行转换

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

  1. 直接在方法中传递参数,xml 文件用#{0} #{1}来获取

  2. 使用 @param 注解:这样可以直接在 xml 文件中通过#{name}来获取

# 什么叫预编译?

通过Statement对象执行SQL语句时,需要将SQL语句发送给DBMS,由DBMS首先进行编译后再执行。

预编译语句和Statement不同,在创建PreparedStatement 对象时就指定了SQL语句,该语句立即发送给DBMS进行编译。当该编译语句被执行时,DBMS直接运行编译后的SQL语句,而不需要像其他SQL语句那样首先将其编译。

# 为什么使用预编译语句

  • 防止SQL注入
  • 提高效率 数据库处理一个SQL语句,需要完成解析SQL语句、检查语法和语义以及生成代码,一般说来,处理时间要比执行语句所需要的时间长。预编译语句在创建的时候已经是将指定的SQL语句发送给了DBMS,完成了解析、检查、编译等工作。因此,当一个SQL语句需要执行多次时,使用预编译语句可以减少处理时间,提高执行效率。
  • 提高代码的可读性和可维护性 将参数与SQL语句分离出来,这样就可以方便对程序的更改和扩展,同样,也可以减少不必要的错误。

# 在标签 <mappers> 下,有几种 mapper 加载方式?哪种方式优先级最高?

Resource、url、package、class 这四种,package 优先级最高。

# mapper 中的例如 select 语句、insert 语句都在哪里保存?

在 MappedStatement 中,是通过 addMappedStatement 方法进行初始化。

# statementType 有哪些?

Any one of STATEMENT, PREPARED or CALLABLE. This causes MyBatis to use Statement, PreparedStatement or CallableStatement respectively. Default: PREPARED.

# Mybatis Spring Boot 项目中默认会检查 config.xml文件吗?

不会,在配置类 MybatisProperties 中默认是关闭的。如果检查是在类初始化的时候进行,他实现了 InitializingBean 接口。

# SqlSessionFactoryBean 的作用是什么?

通过获取各种mybatis配置信息,用于初始化SqlSessionFactory

# Xml 配置方式、Yaml配置方式、Java 配置方式哪种优先级比较高?

Java > Yaml > Xml

# Executor 实现中使用了什么设计模式?

装饰器模式,先通过BaseExecutor实现核心功能,再由Reuse、Simple、BatchExecutor实现各自能力。

# Mybatis 工作原理?

  1. 读取核心配置文件并返回InputStream流对象。
  2. 根据InputStream流对象解析出Configuration对象,然后创建SqlSessionFactory工厂对象
  3. 根据一系列属性从SqlSessionFactory工厂中创建SqlSession
  4. 从SqlSession中调用Executor执行数据库操作&&生成具体SQL指令
  5. 对执行结果进行二次封装
  6. 提交与事务

# 拓展

Mybatis 源码解析入门 (opens new window)

编辑 (opens new window)
IO面试题
Spring面试题

← IO面试题 Spring面试题→

最近更新
01
一致性Hash原理
02-08
02
分布式面试
02-08
03
公共问题
02-08
更多文章>
Theme by Vdoing | Copyright © 2021-2021 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×