Mybatis八股

Mybatis是什么

  • Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,加载驱动、创建连接、创建statement等繁杂的过程,开发者开发时只需要关注如何编写SQL语句,可以严格控制sql执行性能,灵活度高。
  • 作为一个半ORM框架,MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
  • 通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。(从执行sql到返回result的过程)。
  • 由于MyBatis专注于SQL本身,灵活度高,所以比较适合对性能的要求很高,或者需求变化较多的项目,如互联网项目。

Mybatis优缺点

优点

  • 基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
  • 与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
  • 很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
  • 能够与Spring很好的集成;
  • 提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。

缺点

  • SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。
  • SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

Mybatis与Hibernate有哪些不同?

  1. Mybatis不是完全的ORM框架,需要程序员自己编写Sql语句,灵活性高,适合对关系数据模型要求不高的软件开发。
  2. Mybatis无法做到是数据无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件;Hibernate对象/关系映射能力强,有较好的数据无关性。

#{}${}的区别

  • ${}是变量占位符,可以用于标签属性值和sql内部,属于原样文本替换,可以替换任何内容。
mysql 复制代码
select * from users order by ${orderCols}
  • #{}是 sql 的参数占位符,MyBatis 会将 sql 中的#{}替换为? 号,在 sql 执行前会使用 PreparedStatement 的参数设置方法,按序给 sql 的? 号占位符设置参数值,比如 ps.setInt(0, parameterValue)#{item.name} 的取值方式为使用反射从参数对象中获取 item 对象的 name 属性值,相当于 param.getItem().getName()

Mybatis执行流程

  1. 加载Mybatis配置文件: mybatis-config.xml加载运行环境和映射文件
  2. 构造会话工厂SqlSessionFactory
  3. 会话工厂创建SqlSession对象(包含执行SQL语句的所有方法)
  4. Executor操作数据库的接口,同时负责查询缓存的维护
  5. Executor接口的执行方法中有一个MappedStatement类型的参数,封装了映射信息
  6. 输入参数映射
  7. 输出结果映射

Mybatis是否支持延迟加载

Mybatis支持延迟加载,但默认没有开启

  • 延迟加载意思是:需要用到数据时才进行加载,不需要用到数据就不加载数据
  • Mybatis中支持一对一关联对象和一对多关联集合对象的延迟加载
  • 在Mybatis配置文件中,可以配置是否采用延迟加载lazyLoadingEnabled=true|false

何为延迟加载

  1. 使用CGLIB创建目标对象的代理对象
  2. 当调用目标方法user.getOrderList()时,进入拦截器invoke方法,发现user.getOrderList()是null值,执行sql查询order列表
  3. 查询到order后,调用user.setOrderList(List orderList),利用set方法设置属性值,在继续查询目标方法,完成user.getOrderList()的方法调用。

Mybatis的一级、二级缓存

  • 一级缓存:基于PerpetualCache的HashMap本地缓存,其作用域为Session。当Session进行Flush或者Close之后,该Session中所有的Cache就将清空,默认打开一级缓存。
  • 二级缓存是基于namespace和mapper的作用域起作用,不依赖于SQL session,默认也是采用Perpetual,HashMap存储。需要单独开启。一个是在核心配置中改为True,一个是在mapper映射文件中添加'\cache'标识。

Mybatis的二级缓存什么时候回清理缓存中的数据

当某一个作用域(一级缓存Session/二级缓存Namespaces)进行了增删改操作后,默认该作用域下所有select中的缓存都将被删除。

Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗?

Dao接口,即Mapper接口,通常每个xml映射文件都会有一个Dao接口与之对应。接口的权限名就是映射文件中namespace的值;接口的方法名即为MappedStatement的id值;接口方法内的参数就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,将接口权限名+方法名 拼接字符串作为key值,可以定位一个MappedStatement

举例:com.mybatis3.mappers. StudentDao.findStudentById,可以唯一找到 namespacecom.mybatis3.mappers. StudentDao 下面 id = findStudentByIdMappedStatement 。在 MyBatis 中,每一个 <select><insert><update><delete> 标签,都会被解析为一个 MappedStatement 对象。

Mybatis 的 Dao 接口可以有多个重载方法,但是多个接口对应的映射必须只有一个,否则启动会报错。

在Mapper中如何传递多个参数

  1. 若Dao层函数有多个参数,那么其对应的xml中,#{0}代表接收的是Dao层中的第一个参数,#{1}代表Dao中的第二个参数,以此类推。

  2. 使用@Param注解:在Dao层的参数中前加@Param注解,注解内的参数名为传递到Mapper中的参数名。

  3. 多个参数封装成Map,以HashMap的形式传递到Mapper中。

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

MyBatis 动态 sql 可以让我们在 xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。

提供了9种动态sql标签

  • <if></if>
  • <where></where>(trim,set)
  • <choose></choose>(when, otherwise)
  • <foreach></foreach>
  • <bind/>
相关推荐
isNotNullX1 小时前
什么是数据清洗?数据清洗有哪些步骤?
大数据·数据库·数据仓库·数据治理·元数据
雾林小妖1 小时前
Python+pymysql中select count(*)/select *使用方式
数据库·sql
你是橙子那我是谁1 小时前
Redis的list的底层原理
数据库·redis·list
合方圆~小文1 小时前
20倍光学镜头怎么实现20+20倍数实现
数据库·人工智能·硬件工程
阿杰学编程2 小时前
Go 语言中的条件判断和for 循环
java·数据库·golang
文牧之2 小时前
PostgreSQL的扩展lo
运维·数据库·postgresql
我科绝伦(Huanhuan Zhou)2 小时前
MOP数据库备份脚本生成工具
前端·css·数据库
步行cgn2 小时前
MySQL 中 DISTINCT 去重的核心注意事项详解
数据库·mysql
南棱笑笑生2 小时前
20250617在ubuntu20.04.6下编译飞凌OK3576-C_Linux6.1.75_用户资料_R1(更新日期_20241014)
数据库
花开月满西楼3 小时前
Android实例项目【智能家居系统】实现数据库登录注册+动画效果+网页跳转+短信发送!!!
android·数据库·智能家居