Mybatis、Mybatis-Plus面试题

本文详细梳理了Mybatis和Mybatis-Plus的面试重点,包括Mybatis的定义、优缺点、与JDBC的区别、执行流程、缓存机制、动态SQL以及一对一映射。还介绍了Mybatis-Plus的自动识别表、主键策略、逻辑删除和乐观锁等特性。通过对这些知识点的探讨,展示了Mybatis和Mybatis-Plus在实际应用中的价值和优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要参考以下资料并加入一些平时学习时的问题做整理!!! 如果版权问题,立刻删除!
新版Java面试专题视频教程,java八股文面试全套真题+深度详解(含大厂高频面试真题)_哔哩哔哩_bilibili

Mybatis

1、什么是Mybatis?

  • MyBatis是一款基于Java的持久层框架,它提供了一种简单的方式来映射数据库操作到Java对象。它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态SQL,可以严格控制SQL执行性能,灵活度高。
  • MyBatis可以使用XML注解配置映射原生信息,将POJO映射成数据库中的记录,避免了几乎所有JDBC代码和手动设置参数以获取结果集
  • 通过XML文件或注解的方式将要执行的各种statement配置起来,并通过Java对象和statement中的SQL的动态参数进行映射生成最终执行的SQL语句,最后由MyBatis框架执行SQL并将结果映射为Java对象并返回

2、说说MyBatis的优点和缺点?

  • 优点
    1. 基于SQL语句编程,相当灵活,不会对应用程序或数据库的现有设计造成任何影响,SQL写在XML里,解除SQL与程序代码的耦合(用注解写就另说了),便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用
    2. 与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码不需要手动开关连接
    3. 提供应设标签,支持对象与数据库的ORM字段关系映射,提供对象关系映射标签,支持对象关系组件维护
  • 缺点
    1. SQL语句编写的工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求
    2. SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库
    3. XML配置较为繁琐,MyBatis的配置文件中需要编写大量的XML代码来描述SQL语句和映射关系,这可能会使配置文件显得较为繁琐

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

  • #{}在SQL语句中表示一个占位符,它可以防止SQL注入攻击,并且可以自动进行参数类型转换。在执行SQL语句时,MyBatis会将参数值以安全的方式设置到SQL语句中。底层使用的是PreparedStatement#{}占位符替换为?
  • ${}在SQL语句中也表示一个占位符,但它不会对参数进行任何处理,直接将参数值拼接到SQL语句中,因此容易引发SQL注入攻击。底层使用的是Statement

4、MyBatis执行流程是什么样子的?

  • ①读取MyBatis配置文件:mybatis-config.xml加载运行环境和映射文件
  • ②构造会话工厂SqlSessionFactory,一个项目只需要一个,单例的,一般由 spring进行管理
  • ③会话工厂创建SqlSession对象,这里面就含了执行SQL语句的所有方法
  • ④操作数据库的接口,Executor执行器,同时负责查询缓存的维护
  • ⑤Executor接口的执行方法中有一个MappedStatement类型的参数,封装了 映射信息
  • ⑥输入参数映射
  • ⑦输出结果映射

5、Mybatis是否支持延迟加载?延迟加载的底层原理知道吗?

  • 支持,在Mybatis配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled=true|false,默认是关闭的或者在mapper文件中设置fetch_type=lazy

  • 延迟加载在底层主要使用的CGLIB动态代理完成的

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bYt9gE52-1689324466934)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/5da20e57-b808-4394-86ae-dc64b83818a8/Mybatis%E5%BB%B6%E8%BF%9F%E5%8A%A0%E8%BD%BD.png)]

    • 使用CGLIB创建目标对象的代理对象,这里的目标对象就是开启了 延迟加载的mapper
    • 当调用目标方法时(获取另一个实体对象),进入拦截器invoke方法,发现目标方法是null 值,再执行sql查询(懒加载)
    • 获取数据以后,调用set方法设置属性值,再继续查询目标方法,就 有值了

6、Mybatis的一级、二级缓存用过吗?

  • mybatis的一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,SqlSession级别,**默认开启。**同一个SqlSession内部的多次查询操作,如果查询的参数和查询语句都相同,那么第一次查询时查询结果会被缓存到一级缓存中,后续的查询操作会直接从缓存中获取结果,而不会再去查询数据库。一级缓存的生命周期与SqlSession的生命周期相同,当SqlSession被关闭时,一级缓存也会被清空。

  • 二级缓存是基于namespace和mapper的作用域起作用的,不是依赖于SQL session,默认也是采用 PerpetualCache,HashMap 存储。**因此当多个SqlSession操作同一个Mapper时,他们之间共享一个二级缓存。二级缓存需要单独开启,二级缓存的缓存时间是无限制的,但是它的缓存策略是基于LRU(最近最少使用)算法的。**为了提高缓存命中率,MyBatis还提供了缓存清空机制,可以通过在Mapper中配置flushCache="true"来清空缓存。此外,MyBatis还支持基于注解的缓存配置,可以通过在Mapper接口或方法上添加@CacheNamespace或者@CacheNamespaceRef注解来配置缓存

    • 1,全局配置文件

      <settings>
          <setting name="cacheEnabled" value="true>  
      </settings>
      
    • 2,映射文件

      使用<cache/>标签让当前mapper生效二级缓存

  • 二级缓存的注意事项

    • 1,对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了新增、修改、删除操作后,默认该作用域下所有 select 中的缓存将被 clear。
    • 2,二级缓存需要缓存的数据实现Serializable接口
    • 3,只有会话提交或者关闭以后,一级缓存中的数据才会转移到二级缓存中。

7、插入数据后如何获取插入数据库数据的主键?

  • 在Mapper 接口中的方法上添加一个@Options注解,并在注解中指定属性useGeneratedKeys=truekeyProperty="实体类属性名"
  • Mybatis Plus: 自动将主键值回写到实体类中

8、如何处理Java实体类属性名和数据库表中的字段名不一致的情况?

  • 如果实体类属性名和数据库表查询返回的字段名不一致,Mybatis不能自动封装,将会导致这些字段的值为null。

  • 解决方法如下:

    • SQL语句中,对不一样的列名起别名,别名和实体类属性名一样
    @Select("select id, username, password, name, gender, image, job, entrydate, " +
    "dept_id AS deptId, create_time AS createTime, update_time AS updateTime " +
    "from emp " + "
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值