MyBatis

作者: Cathy 分类: 编程开发 发布时间: 2023-09-01 13:46

什么是 MyBatis

  • MyBatis 是一个半 ORM 框架,内部封装了 JDBC,使得开发时只需要关注 SQL 语句本身,不需要处理加载驱动、创建连接等复杂的过程
  • 通过 XML 文件和注解配置,并通过 Java 对象和 statement 的动态参数进行映射,生成最终执行的 SQL 语句
  • 最后由 Mybatis 框架执行 SQL 并将结果映射为 Java 对象并返回

ORM 是什么

  • ORM,对象关系映射
  • 数据库表实体类对应,通过操作实体类就实现操作数据库表

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

  • MyBatis 在查询关联对象或关联集合对象时,需要手动编写 SQL 来完成

JDBC 编程有哪些不足之处,MyBatis 是如何解决的?

  • 数据库连接创建、释放频繁,会造成系统资源浪费
    • MyBatis 通过线程池管理数据库连接,实现连接复用
  • SQL 语句写在代码中,代码不容易维护
    • MyBatis 将 SQL 语句放在配置文件或注解
  • 向 SQL 语句传参麻烦
    • MyBatis 通过参数映射功能,将 Java 对象映射到 SQL 语句中
  • 结果集解析麻烦
    • MyBatis 通过结果集映射功能,将查询结果映射到 Java 对象中

MyBatis 编程步骤是什么样的?

  1. 读取配置文件,创建 SqlSessionFactory 工厂
  2. 通过 SqlSessionFactory 工厂创建 SqlSession 对象
  3. 使用 SqlSession 创建 Dao 接口的代理对象
  4. 使用代理对象执行方法
  5. 调用 session.commit() 提交事务
  6. 调用 session.close() 关闭会话

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

#{} 预处理语句参数占位符:

  • MyBatis 处理#{}时,会将其替换为?号,调用 set 方法赋值
  • 可以防止 SQL 注入问题

${}文本替换:

  • MyBatis 处理 ${}时,会直接使用字符串替换
  • 容易出现 id 的类型不匹配问题和 SQL 注入攻击

当实体类中的属性名和表中的字段名不一样 ,怎么办 ?

  • 在 SQL 语句中定义数据库别名
  • 通过 <resultMap> 来映射字段名和实体类属性名的关系

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

  • Java 代码中添加 SQL 通配符
string wildcardname = “%smi%”;
list<name> names = mapper.selectlike(wildcardname);
<select id=”selectlike”>
    select * from foo where bar like #{value}
</select>
  • SQL 语句拼接通配符%,会引起 SQL 注入
string wildcardname = “smi”;
list<name> names = mapper.selectlike(wildcardname);
<select id=”selectlike”>
    select * from foo where bar like "%"#{value}"%"
</select>

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

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

  • SimpleExecutor :每次开启一个 Statement 对象,用完立刻关闭
  • ReuseExecutor :重复使用创建的 Statement 对象
  • BatchExecutor :缓存多个 Statement 对象,一起执行批量更新

通常一个 xml 映射文件,都会写一个 Dao 接口与之对应,Dao 接口的工作原理是什么?

  1. 定义接口: 定义 DAO 接口,其中包含与数据库操作相关的方法,如插入、更新、删除、查询等
  2. 实现接口: 针对 DAO 接口,创建实现类,这些实现类包含实际的数据库操作逻辑
  3. 映射文件: 使用 XML 文件,用于定义 Java 对象与数据库表的映射关系
  4. 配置: 在应用程序启动时,通过依赖注入或配置文件配置,将 DAO 接口与其对应的实现类进行关联
  5. 使用: 在应用程序中,当需要与数据库交互时,调用 DAO 接口中的方法,而不必关心实际的数据库操作细节。DAO 实现类会根据接口中定义的方法来执行相应的数据库操作,并将结果映射为 Java 对象返回

Dao 接口里的方法,参数不同时,方法能重载吗?

  • Dao 接口里的方法可以重载
  • 但是 MyBatis 的 XML 里面的 ID 不允许重复

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

  • 使用 <resultMap> 标签,自定义数据库列名和对象属性名之间的映射关系
  • 使用 SQL 列的别名功能,将列的别名属性对应为对象属性名

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

  • 顺序传参法:#{} 里面的数字代表传入参数的顺序
  • 注解传参法:#{} 里面的名称对应的是注解@Param 括号里面修饰的名称
  • Map 传参:#{} 里面的名称对应的是 Map 里面的 key 名称
  • Java Bean 传参法:#{} 里面的名称对应的是 User 类里面的成员属性

MyBatis 动态 SQL 有什么用?执行原理?有哪些动态 SQL?

  • MyBatis 的动态 SQL 允许在 XML 映射文件中以标签的形式编写动态 SQL 语句,根据运行时的条件动态生成 SQL 语句,从而使得 SQL 查询更加灵活
  • 执行原理根据表达式的值完成逻辑判断并动态拼接 SQL
  • MyBatis 提供了 9 种动态 SQL 标签: 常用的有 if | where | foreach

MyBatis 实现一对多有几种方式,怎么操作的?

联合查询嵌套查询

  • 联合查询是几个表联合查询,只查询一次,通过在 resultMap 里面的 collection 节点配置一对多的类就可以完成
  • 嵌套查询是先查一个表,根据这个表里面的结果的外键 id,去再另外一个表里面查询数据

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

  • MyBatis 支持延迟加载
  • MyBatis 的延迟加载是通过代理对象懒加载的技术实现的:
    • 代理对象: 当您从数据库查询一个对象时,MyBatis 不直接返回实际的对象,而是返回了一个代理对象。代理对象持有实际对象的引用,并且能够在需要时触发实际数据的加载
    • 懒加载触发: 访问代理对象的某个属性时,MyBatis 会检查该属性是否已经加载。如果尚未加载,MyBatis 会发起相应的 SQL 查询以从数据库中获取数据

MyBatis 的一级、二级缓存

MyBatis 提供了两级缓存来优化数据库查询性能:一级缓存二级缓存

  1. 一级缓存(本地缓存):
    • 一级缓存是 MyBatis 默认开启
    • 在同一个 SqlSession 内部进行数据缓存的
    • 在同一个 SqlSession 中,如果执行了相同的 SQL 语句,MyBatis 会将查询结果缓存在一级缓存中,下次访问相同 SQL 时,会直接从缓存中获取数据,而不再去查询数据库
    • 一级缓存的生命周期是与 SqlSession 相关的,当 SqlSession 被关闭或者数据发生变更时,缓存会被清空
  2. 二级缓存(全局缓存):
    • 二级缓存是在 SqlSessionFactory 层面进行数据缓存的
    • 可以被多个 SqlSession 共享
    • 二级缓存通常在应用程序的不同请求之间使用,或用于在不同的 SqlSession 之间共享数据,从而减少数据库访问
    • 二级缓存默认是关闭的,需要进行配置开启

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

MyBatis 的接口绑定是指将一个接口与一个或多个 XML 映射文件关联起来,从而可以通过接口方法来执行 SQL 语句,无需手动编写 SQL

  • XML 映射文件
  • 注解
  • Mapper 接口代理

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注