Java面试题(五)–Rabbits

1、什么是MyBatis?

1、Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。

2、MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

3、通过xml文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。

2、MyBatis的优点和缺点?

优点

1、基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。

2、与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;

3、很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)

4、能够与Spring很好的集成;

5、提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。

缺点

1、SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。

2、SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

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

第1种: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。

第2种: 使用resultMap来定义字段和属性的映射关系

4、xml映射文件中,除了常见的select|insert|updae|delete标签之外,还有哪些标签?

if

使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。比如:

Java面试题(五)--Rabbits
choose、when、otherwise

有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

Java面试题(五)--Rabbits
还是上面的例子,但是策略变为:传入了 “title” 就按 “title” 查找,传入了 “author” 就按 “author” 查找的情形。若两者都没有传入,就返回标记为 featured 的 BLOG。

where、set

如下sql语句的定义:

Java面试题(五)--Rabbits
如果没有匹配的条件会怎么样?最终这条 SQL 会变成这样:
Java面试题(五)--Rabbits
这会导致查询失败。如果匹配的只是第二个条件又会怎样?这条 SQL 会是这样:
Java面试题(五)--Rabbits
这个查询也会失败。这个问题可以使用简单地用条件元素来解决,比如在where后面添加一个恒等的条件:1 = 1。

MyBatis 有一个简单且适合大多数场景的解决办法。而在其他场景中,可以对其进行自定义以符合需求。而这,只需要一处简单的改动:

Java面试题(五)--Rabbits
where元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”, where 元素也会将它们

去除。

set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。比如:

Java面试题(五)--Rabbits
这个例子中, set元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。

foreach

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:

Java面试题(五)--Rabbits
foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以

及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符!

5、如何获取自动生成的(主)键值?(高频)

使用insert标签中的useGeneratedKeys和keyProperty 属性。使用方式如下所示:

Java面试题(五)--Rabbits
属性说明:

1、useGeneratedKeys:是够获取自动增长的主键值。true表示获取。

2、keyProperty :指定将获取到的主键值封装到哪儿个属性里

6、使用MyBatis的代理开发有哪些要求?

使用Mapper代理方式,必须满足以下要求:

1、定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下。

2、设置SQL映射文件的namespace属性为Mapper接口全限定名

3、在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id属性值,并保持参数类型和返回值类型一致

7、#{}和${}的区别是什么?(高频)

1、#{}是预编译处理,${}是字符串替换。

2、Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

3、Mybatis在处理${}时,就是把${}替换成变量的值。

4、使用#{}可以有效的防止SQL注入,提高系统安全性。

8、Mybatis是如何进行分页的?分页插件的原理是什么?(高频)

分页方式:

1、在执行sql语句的时候直接拼接分页参数

2、使用Mybatis的分页插件(PageHelper)进行分页

分页插件的原理:分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

public class PageInterceptor implements Interceptor

举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,10

9、如何执行批量插入数据?(高频)

批量插入数据:

1、mybatis的接口方法参数需要定义为集合类型List

2、在映射文件中通过forEach标签遍历集合,获取每一个元素作为insert语句的参数值

10、MyBatis实现一对一有几种方式?具体怎么操作的?

两种方式:

1、联合查询

2、嵌套查询

联合查询操作:联合查询是几个表联合查询,只查询一次, 通过在resultMap使用 association标签配置查询到的关联数据的映射关系。

嵌套查询操作:嵌套查询是先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查询数据,也是通过 association配置,但另外一个表的查询通过select属性配置。

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

Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled=true|false。

默认情况下延迟加载是关闭的。

实现原理:

它的原理是,使用CGLIB创建 目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用order.getUser().getUserName(),拦截器invoke()方法发现order.getUser()是null值,那么就会单独发送事先保存好的查询关联User对象的sql,把User查询上来,然后调用order.setUser(user),于是order的对象user属性就有值了,接着完成order.getUser().getUserName()方法的调用。

12、什么是Mybatis的一级缓存和二级缓存?(高频)

1、一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当Session进行flush或close之后,该Session中的所有Cache就将清空,默认打开一级缓存。如下所示:

Java面试题(五)--Rabbits
使用同一个sqlSession对象获取两次UserMapper对象,进行了两次用户数据的查询。

Java面试题(五)--Rabbits
只执行了一次sql语句。说明第二次查询的时候使用的是缓存数据。

2、二级缓存:二级缓存是基于namespace和mapper的作用域起作用的,不是依赖于SQL session,默认也是采用 PerpetualCache,HashMap 存储。

Java面试题(五)--Rabbits

当执行完sqlSession1.close()方法时一级缓存就已经被清空掉了。再次获取了一个新的sqlSession对象,那么此时就需要再次查询数据

Java面试题(五)--Rabbits

默认情况下二级缓存并没有开启,要想使用二级缓存,那么就需要开启二级缓存

3、对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了新增、修改、删除操作后,默认该作用域下所有 select 中的缓存将被 clear。

注意事项:

1、二级缓存需要缓存的数据实现Serializable接口

2、只有会话提交或者关闭以后,一级缓存中的数据才会转移到二级缓存中

3、可自定义存储源,如 Ehcache。

13、请说说MyBatis的工作原理?

1、读取 MyBatis 配置文件:mybatis-config.xml 为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息,例如数据库连接信息。

2、加载映射文件。映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在MyBatis 配置文件 mybatis-config.xml 中加载。

mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

3、构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。

4、创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。

5、Executor执行器:MyBatis底层定义了一个Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。

6、MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的

SQL 语句的 id、参数等信息。

7、输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。

8、输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。

14、Mybatis都有哪些Executor执行器?它们之间的区别是什么?(高频)

Mybatis有三种基本的Executor执行器, SimpleExecutorReuseExecutorBatchExecutor

1、SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象,也是Mybatis默认使用的执行器。

2、ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map

3、BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。

Original: https://www.cnblogs.com/xy1857/p/16557938.html
Author: Orator-xy
Title: Java面试题(五)–Rabbits

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/593953/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • nginx 转发接口出现 403 forbidden

    当你尝试完网上解决nginx 403 forbidden 的方法后仍然出现访问后台接口403的问题 不妨把问题定位到服务器和程序服务上 通过定位程序日志 发现在启动的时候日志报 n…

    Java 2023年5月30日
    080
  • 搞定面试官:咱们从头到尾再说一次 Java 垃圾回收

    接着前几天的两篇文章,继续解析JVM面试问题,送给年后想要跳槽的小伙伴 万万没想到,面试中,连 ClassLoader类加载器 也能问出这么多问题….. 万万没想到,J…

    Java 2023年5月29日
    096
  • 记一次慢查询优化sql

    分析sql,从哪几方面考虑进行优化 SELECT IFNULL(SUM(total.cityPayMoneySum),0) AS cityPayMoneySum,total.cit…

    Java 2023年6月7日
    0103
  • JAVA入门基础_从零开始的培训_SpringBoot2入门

    SpringBoot2快速入门 配置maven仓库的配置文件 创建一个Maven项目,修改pom文件添加依赖 创建一个Controller控制器 运行项目即可,最终的项目目录如下 …

    Java 2023年6月9日
    061
  • Kafka基本理论

    基本特点 异步解耦、削峰填谷 Topic 分区/分区备份,集群互为某分区备份 broker控制,分区leader/follower 单分区保证消息时间顺序 offset,分区内消息…

    Java 2023年6月9日
    082
  • [感谢坑娘][回忆3年前]茜色的终点线….

    虽然没有H的汉化,我还是走到茜色的终点 其实我有想过,也有人说坑娘能填坑就不叫坑娘 虽然之前都是玩着EGO游戏… 虽然最早我接触GALGAME是 Man at work…

    Java 2023年5月29日
    079
  • Idea插件SequenceDiagram快速查看方法调用

    Idea打开setting->plugins安装插件SequenceDiagram 快速查看方法调用 在方法名上右键点击SequenceDiagram即可生成方法调用图 最上…

    Java 2023年6月7日
    073
  • 【SSM框架】MyBatis笔记 — 动态sql讲义+实战;map在动态sql中的使用;列名与类中成员变量名不同的两种解决方案

    讲义: 动态sql可以定义代码片断,可以进行逻辑判断,可以进行循环处理(批量处理),使条件判断更为简单。 一、动态sql核心标签: 1、 2、 <!–定义代码片断–&gt…

    Java 2023年6月8日
    092
  • Java学习 (17) Java数组篇(01)数组定义&数组声明和创建以及内存分析

    数组的定义 数组的声明和创建 内存分析 语法实例 1.静态初始化 2.动态初始化 3.数组的默认初始化 数组的定义 数组是相同类型数据的有序集合. 数组描述的是相同类型的若干个数据…

    Java 2023年6月8日
    086
  • [新手专用]Oracle Database Express 创建表空间的方法

    简介: Oracle 10g Express Edition (XE) 集成了 Oracle HTML DB 2.1 ,便于开发基于 Web 的应用. 当然,这个免费是肯定有功能限…

    Java 2023年5月29日
    084
  • maven添加oracle的依赖驱动

    1、下载需要的jdbc jar 包 2、下载jar包 3、在当前目录下输入cmd进入控制台 4、控制台输入 命令解释 5、执行后有如下就表示成功 6、在maven配置 1、下载需要…

    Java 2023年6月5日
    0110
  • 【工作篇】了解升级 Spring 版本导致的跨域问题

    一、背景 最近需要统一升级 Spring 的版本,避免 common 包和各个项目间的 Spring 版本冲突问题。这次升级主要是从 Spring 4.1.9.RELEASE 升级…

    Java 2023年6月5日
    097
  • 双缓冲绘图

    双缓冲绘图 大家小时候都玩过飞机大战吧,当我们在玩这种飞行射击类游戏时,背景图总是不断地向下移动的,从而给我们营造出一种飞机正在向前飞行的游戏体验。那么,图片的快速变化是如何实现的…

    Java 2023年6月5日
    078
  • 超简单的抖音去水印原理教程

    一、前言 抖音去水印方法很简单,以前一直没有去研究,以为搞个去水印还要用到算法去除,直到动手的时候才发现这么简单,不用编程基础都能做。 二、原理与步骤 其实抖音它是有一个隐藏无水印…

    Java 2023年6月7日
    0140
  • 终止线程的运行

    终止线程的执行 强制终止用的是stop()方法,因为这种方法会丢失数据,所以一般不采用这种方法。 原理是直接杀死线程,这样的话线程中没有保存的数据就会丢失 /* 在java中强制终…

    Java 2023年6月9日
    0119
  • IO多路复用

    划分内核态/用户态 之前说过七层/五层/四层的 &#x7F51;&#x7EDC;&#x6A21;&#x578B;,我们从网络模型可以看出 &…

    Java 2023年6月7日
    089
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球