当前位置: 首页 > news >正文

MyBatis题

1. Mybatis 是什么?它的核心工作原理是什么?

  • 是什么:Mybatis 是一个优秀的持久层框架,它避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。它使用简单的 XML 或注解来配置和映射原始类型、Map 和 POJO 到数据库的记录。

  • 核心原理:Mybatis 通过 SQL Mapper 机制,将 SQL 语句和 Java 方法进行绑定。开发者只需定义 SQL 语句,Mybatis 就会负责底层与数据库的交互,并将查询结果自动映射为 Java 对象。

2. 为什么说 Mybatis 是一个半自动化的 ORM 框架?它和 Hibernate 有什么区别?

  • 半自动化:Mybatis 的 SQL 语句需要开发者手动编写,它只是将 SQL 执行结果自动映射为 Java 对象。它让开发者对 SQL 有完全的控制权。

  • 区别

    • SQL 控制:Mybatis 让开发者自由编写 SQL,可以进行 SQL 优化;Hibernate 则是完全的 ORM,它自动生成 SQL,开发者无法直接控制。

    • 学习成本:Mybatis 简单易学,入门快;Hibernate 概念较多,学习曲线陡峭。

    • 灵活性:Mybatis 更灵活,适合复杂的、需要手动优化的业务 SQL;Hibernate 适合 CRUD 简单、业务不复杂的场景。

3. Mybatis 的配置文件有哪些?

Mybatis 的核心配置文件主要有两个:

  • mybatis-config.xml:Mybatis 的全局配置文件,包含了数据库连接、类型别名、插件、映射器(Mapper)等核心配置。

  • Mapper XML 文件:用于定义 SQL 语句和结果映射的 XML 文件,每个 Mapper 接口通常对应一个 XML 文件。

4. #$ 符号有什么区别?

  • #:表示一个预编译参数占位符。Mybatis 在处理时,会将 # 替换为 ?,并使用 PreparedStatement 来执行,可以有效防止 SQL 注入

  • $:表示一个字符串占位符。Mybatis 会直接将 $ 替换为变量的字面量值,不进行预编译。不安全,容易导致 SQL 注入。通常用于动态传入表名或排序列名。

5. 什么是动态 SQL?有哪些常用的标签?

动态 SQL 是 Mybatis 的强大特性,它允许你根据传入的参数,动态地拼接 SQL 语句。

常用的动态 SQL 标签有:

  • <if>:简单的条件判断。

  • <choose>, <when>, <otherwise>:类似 Java 的 if/else if/else 结构。

  • <where>:自动添加 WHERE 关键字,并处理 SQL 语句开头多余的 ANDOR

  • <set>:用于 UPDATE 语句,自动处理更新字段之间多余的逗号。

  • <foreach>:用于构建 IN 语句或批量插入。

6. 如何传递多个参数?

有三种主要方式:

  1. 使用 @Param 注解:最推荐的方式,清晰直观。

    Java

    User selectUser(@Param("name") String name, @Param("age") int age);
    
  2. 使用 Map:将参数放入一个 Map 中,通过键名访问。

  3. 使用 JavaBean/POJO:将参数封装成一个 Java 对象,在 XML 中通过对象的属性名访问。

7. resultTyperesultMap 的区别?

  • resultType:用于将查询结果直接映射为简单数据类型简单 POJO 对象。要求数据库列名和 POJO 的属性名完全一致,否则需要使用 as 别名。

  • resultMap:用于复杂的自定义映射。当数据库列名和 POJO 属性名不一致、需要处理复杂关系(如一对一、一对多)或进行复杂数据类型转换时,必须使用 resultMap

8. 如何实现一对一和一对多关系映射?

  • 一对一:使用 <association> 标签。

  • 一对多:使用 <collection> 标签。

这两个标签都可以通过嵌套查询(N+1 问题)或嵌套结果(一次查询解决)两种方式来实现。

9. Mybatis 的缓存机制是怎样的?

Mybatis 提供了两级缓存:

  1. 一级缓存(默认开启)SqlSession 级别的缓存。在同一个 SqlSession 中,如果执行相同的查询,会直接从缓存中获取结果。

  2. 二级缓存(默认关闭)Mapper 级别的缓存。多个 SqlSession 可以共享缓存。需要手动开启。

10. 什么是懒加载(Lazy Loading)?如何配置?

懒加载也叫延迟加载,指在查询主对象时,不立即查询其关联对象的数据,而是等到真正使用到关联对象时才去查询。这可以避免不必要的数据库查询,减少 N+1 问题。

  • 配置:在 mybatis-config.xml 中将 lazyLoadingEnabled 设置为 true

11. SqlSessionFactorySqlSession 有什么区别?

  • SqlSessionFactory:是 Mybatis 的核心类,用于创建 SqlSession 对象。一个应用通常只有一个 SqlSessionFactory 实例。

  • SqlSession:是 Mybatis 与数据库交互的会话,包含了所有执行 SQL 的方法。SqlSession 不是线程安全的,每次请求都应该新创建一个

12. 为什么说 Mapper 接口和 Mapper XML 是绑定的?

Mybatis 通过两种方式将它们绑定:

  1. 命名空间(Namespace):XML 文件的 namespace 必须是 Mapper 接口的全限定名。

  2. 方法名:XML 文件中 <select><insert> 等标签的 id 必须和 Mapper 接口中的方法名一致。

13. Mybatis 如何获取自增主键?

可以使用 <insert> 标签的 useGeneratedKeyskeyProperty 属性。

  • useGeneratedKeys="true":启用获取自增主键的功能。

  • keyProperty:将自增主键的值设置到 Java 对象的哪个属性中。

14. 什么是 N+1 查询问题?如何解决?

N+1 问题是指,当查询一个主列表时,Mybatis 会先执行一次查询获取主列表,然后针对列表中的每一个对象,再单独执行一次查询去获取其关联对象,总共需要 1 + N 次查询。

  • 解决方案

    1. 使用联结查询:使用 <association><collection> 的嵌套结果(Result Map),通过一次 JOIN 查询获取所有数据。

    2. 使用懒加载:如果不需要立即使用关联对象,可以开启懒加载来延迟查询。

15. 解释下 Mybatis 的生命周期对象

  • SqlSessionFactoryBuilder:构建器,用于从 XML 或 Java 配置中创建 SqlSessionFactory,用完即弃。

  • SqlSessionFactory:会话工厂,用于创建 SqlSession。它是线程安全的,通常是单例的。

  • SqlSession:会话,用于执行 SQL。它不是线程安全的,每次请求都应创建新实例。

  • Mapper:映射器接口,它的实例由 SqlSession 创建,用于调用 XML 中定义的 SQL。

16. Mybatis 的 XML 映射文件中 <select> 标签的属性有哪些?

  • id:映射的 Java 方法名。

  • parameterType:入参类型。

  • resultType:返回值类型,简单类型或 POJO。

  • resultMap:自定义结果集映射。

  • statementType:可选 STATEMENTPREPAREDCALLABLE,默认为 PREPARED

17. 如何整合 Mybatis 和 Spring?

主要通过 mybatis-spring 模块进行整合。

  • 在 Spring 配置中,配置 SqlSessionFactoryBean,注入数据源和 Mybatis 核心配置文件。

  • 配置 MapperScannerConfigurer@MapperScan 注解,让 Spring 自动扫描 Mapper 接口,并将其注册为 Bean。

18. 为什么要使用 Mybatis?它的优点是什么?

  • SQL 灵活性:开发者可以完全控制 SQL,方便进行 SQL 优化。

  • 半自动化:兼顾了 SQL 编写的灵活性和 ORM 框架的自动化映射。

  • 配置简单:配置相对简单,学习成本低。

  • SQL 与代码分离:将 SQL 语句从 Java 代码中解耦,便于维护。

19. Mybatis 的执行流程是怎样的?

  1. 加载 mybatis-config.xml 和 Mapper XML 文件,创建 SqlSessionFactory

  2. 通过 SqlSessionFactory 创建 SqlSession

  3. 通过 SqlSession 获得 Mapper 接口的代理对象。

  4. 调用 Mapper 接口方法。

  5. 代理对象根据方法名,找到对应的 SQL 语句,并执行预编译。

  6. 将参数传入预编译的 SQL 语句。

  7. 执行 SQL,获取结果集。

  8. Mybatis 将结果集映射到 Java 对象,并返回。

20. XML 和注解方式映射 SQL,有什么区别?

  • XML 方式

    • 优点:SQL 和 Java 代码分离,便于维护;支持更复杂的动态 SQL;支持更复杂的映射关系。

    • 缺点:工作量大,需要维护两个文件。

  • 注解方式

    • 优点:简单,不需要 XML 文件,适用于简单的 SQL。

    • 缺点:不支持复杂的动态 SQL 和映射关系,代码和 SQL 耦合在一起。

总结:通常在项目中,对于简单的 CRUD 和单表查询,可以使用注解。对于复杂的、需要动态 SQL 和联结查询的,则必须使用 XML

http://www.xdnf.cn/news/1379107.html

相关文章:

  • 前端开发中的CSS变量管理:实现缓存与响应式更新
  • PostgreSQL15——常用函数
  • 农行广西区分行携手广西专精特新商会共探金融赋能专精特新企业新路径
  • Milvus 向量数据库开发实战指南
  • 基于Vue2+elementUi实现树形 横向 合并 table不规则表格
  • 现代前端状态管理:从原理到实战(Vue/React全栈方案)
  • 笔记本电脑蓝牙搜索不到设备-已解决
  • 算法之排序
  • 媒体查询案例之修改背景颜色
  • 从枯燥C++到趣味音乐:我的Windows系统底层探索之旅
  • TypeScript:never类型
  • C++ RAII 浅谈
  • 从Cgroups精准调控到LXC容器全流程操作​:用pidstat/stress测试Cgroups限流,手把手玩转Ubuntu LXC容器全流程​
  • 冒泡排序算法详解(python code)
  • Two Knights (数学)
  • 大模型微调示例三之Llama-Factory_Lora
  • 【C++详解】用哈希表封装实现myunordered_map和 myunordered_set
  • Kubernetes一Prometheus概述
  • [linux仓库]透视文件IO:从C库函数的‘表象’到系统调用的‘本质’
  • [调试][实现][原理]用Golang实现建议断点调试器
  • 获取小红书某个用户列表
  • 【LeetCode 热题 100】32. 最长有效括号——(解法二)动态规划
  • 集成电路学习:什么是TensorFlow
  • AI实时故障诊断系统(实时采集信号)
  • Python 正则表达式完全指南:从基础语法到实战案例
  • 【从0带做】基于Springboot3+Vue3的呱呱同城(微服务项目)
  • 实现微信小程序的UniApp相机组件:拍照、录像与双指缩放
  • ARM相关的基础概念和寄存器
  • PCIe 5.0 SSD连续读写缓存用完速度会骤降吗?
  • 2024年09月 Python(三级)真题解析#中国电子学会#全国青少年软件编程等级考试