8.面试题——Mybatis

1.Mybatis是什么?

Mybatis是一种流行的Java对象关系映射(ORM)框架,它将Java对象映射到关系型数据库中的表格。它提供了一种简单的方式来编写SQL语句并将其映射到Java对象,同时避免了很多传统JDBC的冗长代码。在使用Mybatis时,开发人员可以编写简洁的SQL语句,并且可以使用动态SQL和参数映射来进行高效和灵活的数据操作。

除了ORM之外,Mybatis还提供了许多高级功能,如缓存机制、批量操作、分页等等。它可以与多种数据库(如MySQL、Oracle、SQL Server等)和Web框架(如Spring、Spring Boot等)无缝集成,并被广泛应用于各种规模的应用程序中。

2.Mybatis有什么优缺点?

  • 优点:
    • 灵活性强:Mybatis允许开发人员编写自定义SQL语句,能够根据项目需求进行灵活配置和扩展,同时可以避免框架的约束和限制。
    • 可读性好:Mybatis使用简洁的XML或注解配置方式,可以清晰地表达SQL语句和数据映射关系,提高代码的可读性和可维护性。
    • 性能高:Mybatis提供了高效的缓存机制,能够有效地减少数据库操作的次数,并支持批量操作和分页查询等功能,能够提高应用程序的性能。
    • 易于集成:Mybatis可以与多种数据库和Web框架无缝集成,能够适应不同的应用场景,同时也有完善的文档和社区支持。
  • 缺点:
    • 学习成本较高:相比于其他ORM框架,Mybatis需要开发人员熟悉SQL语句的编写和调优,需要一定的学习成本。
    • 配置较为繁琐:Mybatis的配置文件较多,需要开发人员仔细配置,否则容易出现错误。
    • SQL语句调试困难:Mybatis将SQL语句和Java代码分离,当SQL语句出现问题时,调试起来相对困难。
    • 不适合小型项目:对于小型项目而言,Mybatis的优势可能不够明显,反而会增加项目的开发成本和复杂度。

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

#{}使用预编译的方式来处理SQL语句中的参数,将传入的参数值以安全的方式替换掉占位符。在SQL语句执行前,会先将#{}替换为一个问号占位符,然后使用PreparedStatement进行预编译,最后将实际的参数值设置到预编译语句中。使用#{}可以有效地防止SQL注入等安全问题,同时也可以避免一些数据类型转换的问题。

则是直接将参数值替换到 S Q L 语句中。在 S Q L 语句执行前,会直接将 {}则是直接将参数值替换到SQL语句中。在SQL语句执行前,会直接将 则是直接将参数值替换到SQL语句中。在SQL语句执行前,会直接将{}替换为对应的参数值,这种方式的好处是可以直接拼接字符串,但也带来了一些安全问题。使用${}时需要开发人员自行保证参数的合法性,否则可能会出现SQL注入等安全问题。

4.xml 映射文件中有什么标签?

  • CRUD操作标签:包括select、insert、update、delete等标签,用于定义对数据库的增、删、改、查操作。这些标签都包括id、parameterType、resultType等属性,用于指定SQL语句的ID、参数类型和返回结果类型等信息。
  • 结果集映射标签:包括resultMap和result标签,用于定义Java对象和数据库表之间的映射关系,可以将查询结果集映射为Java对象的属性。resultMap标签用于定义映射规则,result标签用于定义单个属性的映射关系。
  • SQL片段标签:包括sql和include标签,用于定义可重用的SQL代码片段。sql标签用于定义SQL语句的代码片段,可以在其他SQL语句中使用,标签用于将其他XML片段引入到当前XML文件中,可以用于复用其他XML片段中定义的SQL语句。
  • 动态SQL标签:包括if、choose、when、otherwise、where、set、foreach和bind等标签,用于动态生成SQL语句中的条件判断、循环、赋值等操作。这些标签可以根据参数值动态生成SQL语句,提高SQL语句的复用性和可维护性。

5.Mapper 接口的工作原理是什么?Mapper 接口里的方法能重载吗?

Mapper接口是Mybatis提供的一种编写SQL映射的方式,可以将SQL语句与Java方法进行关联,使得Java开发人员可以使用面向对象的方式来编写数据访问代码。Mapper接口的工作原理是:

  • 定义Mapper接口:首先,开发人员需要定义一个Java接口,其中每个方法代表一条SQL语句,方法名与SQL语句的ID一致,方法的参数和返回值类型与SQL语句的参数和返回值类型一致。
  • 映射Mapper接口:然后,将Mapper接口与SQL语句进行映射,可以使用XML文件或注解的方式进行映射。映射的方式包括指定SQL语句的ID、参数类型、返回值类型等信息。
  • 使用Mapper接口:最后,在Java代码中使用Mapper接口来进行数据访问,通过Mybatis框架将Mapper接口中的方法与SQL语句进行绑定,实现对数据库的访问操作。

至于Mapper接口中的方法重载问题,答案是:不可以。在Mapper接口中,每个方法名对应着一个唯一的SQL语句ID,方法名相同会造成冲突,因此Mapper接口中的方法不允许重载。如果需要执行不同的SQL语句,可以使用不同的方法名来实现。

6.MyBatis 是否支持延迟加载?它的实现原理是什么?

MyBatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,其中 association 指的是一对一,collection 指的是一对多查询。

在 MyBatis 配置文件中,可以通过设置 lazyLoadingEnabled 属性来启用或禁用延迟加载。当 lazyLoadingEnabled 设置为 true 时,MyBatis 将会开启延迟加载功能。此时,只有在实际使用对象时才会触发关联对象的查询操作,否则不会查询数据库。

MyBatis 延迟加载的原理是,在执行主查询语句时,仅仅查询主表的数据,而不去查询关联表的数据,将关联表的查询延迟到实际需要使用关联对象时再去查询。MyBatis 通过使用代理模式,在查询主表数据时创建代理对象,当实际需要使用关联对象时,再去查询关联表数据并设置到代理对象中,从而实现了延迟加载。

在具体实现时,MyBatis 通过 CGLIB 或 JDK 动态代理来创建代理对象,当代理对象的方法被调用时,会触发代理拦截器的方法。拦截器会检查关联对象是否已经加载,如果未加载,则发送延迟加载的 SQL 语句查询关联表数据,并将查询结果设置到代理对象中。这样,在实际使用关联对象时,就可以避免不必要的关联表查询,从而提高查询性能。

需要注意的是,MyBatis 的延迟加载功能需要配合 lazyLoadingEnabled 属性一起使用,并且需要遵循一些规范和约束,如不能在延迟加载时关闭 SqlSession,不能使用多线程并发访问等。同时,在使用延迟加载时,也需要注意潜在的 N+1 查询问题,需要合理设计 SQL 查询语句,避免不必要的性能损耗。

7.Mybatis 都有哪些 Executor 执行器?有什么区别?

MyBatis 有三种 Executor 执行器,分别是:

  • SimpleExecutor:每执行一次 update 或 select,就开启一个 Statement 对象,用完立刻关闭
    Statement 对象。
  • ReuseExecutor:执行 update 或 select,以 sql 作为 key 查找 Statement
    对象,存在就使用,不存在就创建,用完后,不关闭 Statement 对象,而是放置于 Map 内,供下一次使用。简言之,就是重复使用
    Statement 对象。
  • BatchExecutor:执行 update(没有 select,JDBC 批处理不支持 select),将所有 sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个 Statement 对象,每个Statement 对象都是 addBatch()完毕后,等待逐一执行 executeBatch()批处理的。

其中,SimpleExecutor 是每次请求都会创建一个 Statement 对象,非常耗费性能;ReuseExecutor 在多次请求中,如果有相同的 SQL 语句,就会复用 Statement 对象,优化了性能;BatchExecutor 是执行批量操作时使用,可以一次性执行多条 SQL 语句,优化性能。

在 MyBatis 中,默认使用的是 SimpleExecutor 执行器。可以通过在 MyBatis 的配置文件中指定
< setting name=“defaultExecutorType” value=“REUSE”/>,来改变默认的执行器。

8.MyBatis 中如何指定使用哪一种 Executor 执行器?

在 MyBatis 的配置文件中可以通过 defaultExecutorType 属性来指定默认的执行器类型

另外,针对每个 select、insert、update、delete 标签,也可以通过 executorType 属性来指定该 SQL 语句使用的执行器类型,如:

<select id="" resultType="User" executorType="BATCH">
  SELECT * FROM user WHERE id = #{id}
</select>

9.MyBatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?

MyBatis 是半自动 ORM 映射工具,它需要手动编写 SQL 语句并将 SQL 语句和 Java 对象进行映射。相比之下,Hibernate 是全自动 ORM 映射工具,它使用对象关系映射技术,将 Java 对象和数据库表进行映射,无需手动编写 SQL 语句。因此,在使用上,MyBatis 更加灵活,可以根据具体的需求编写灵活的 SQL 语句,而 Hibernate 更加便捷,可以快速地进行开发,无需手动编写 SQL 语句。

另外,Hibernate 支持级联操作和对象关系维护,可以自动完成多个对象之间的关联操作,而 MyBatis 不支持级联操作,需要手动编写 SQL 语句来完成多个对象之间的关联操作。

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

一级缓存是指MyBatis在同一个SqlSession中执行相同SQL时,会把查询到的结果缓存到内存中。当下次查询相同SQL时,会直接从缓存中获取数据,避免了重复查询数据库,提高了查询效率。一级缓存是默认开启的,也不需要进行额外配置。

二级缓存是指MyBatis在多个SqlSession之间共享缓存。它可以避免多个SqlSession重复查询同一条数据,提高了应用的性能。但是,使用二级缓存需要进行额外的配置,包括在mapper.xml文件中配置标签以及在MyBatis的配置文件中开启二级缓存。需要注意的是,二级缓存仅仅是对查询结果进行缓存,对于insert、update、delete等操作,并不会清空缓存。

需要注意的是,虽然缓存可以提高应用的性能,但是缓存也有可能带来一些问题,如数据不一致等。因此,在使用缓存时需要根据具体情况进行合理的配置。

11.MyBatis 编程步骤是什么样的?

1、 创建 SqlSessionFactory
2、 通过 SqlSessionFactory 创建 SqlSession
3、 通过 sqlsession 执行数据库操作
4、 调用 session.commit()提交事务
5、 调用 session.close()关闭会话

12.在 Mybatis 中,ResultType 和 ResultMap 的区别是什么?

如果数据库结果集中的列名和要封装实体的属性名完全一致的话用resultType 属性如果数据库结果集中的列名和要封装实体的属性名有不一致的情况用resultMap属性,通过 resultMap 手动建立对象关系映射,resultMap 要配置一下表和类的一一对应关系,所以说就算你的字段名和你的实体类的属性名不一样也没关系,都会给你映射出来

13.在 Mybatis 中你知道的动态 SQL 的标签有哪些?作用分别是什么?

  1. if 是为了判断传入的值是否符合某种规则,比如是否不为空.
  2. where 标签可以用来做动态拼接查询条件,当和if 标签配合的时候,不用显示的声明类型 where 1 = 1 这种无用的条件
  3. foreach 标签可以把传入的集合对象进行遍历,然后把每一项的内容作为参数传到 sql 语句中.
  4. include 可以把大量的重复代码整理起来,当使用的时候直接include即可,减少重复代码的编写;
  5. set适用于更新中,当匹配某个条件后,才会对该字段进行跟新操作

14.谈一下你对 mybatis 缓存机制的理解?

Mybatis 有两级缓存,一级缓存是 SqlSession 级别的,默认开启,无法关闭;二级缓存是 Mapper 级别的,二级缓存默认是没有开启的,但是手动开启

  1. 一级缓存:基础 PerpetualCache 的 HashMap 本地缓存,其存储作用域为Session, 当 Session flush 或 close 之后,Session 中的所有 Cache 就将清空
  2. 二级缓存其存储作用域为 Mapper(Namespace),使用二级缓存属性类需要实现Serializable 序列化接口
  3. 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)
    的进行了 C(增加)/U(更新)/D(删除)操作后,默认该作用域下所有 select 中的缓存将被clear.

当我们的配置文件配置了 cacheEnabled=true 时,就会开启二级缓存,二级缓存是mapper 级别的,如果你配置了二级缓存,那么查询数据的顺序应该为:二级缓存→一级缓存→数据库。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Retrograde-lx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值