Java面试——MyBatis篇

news2024/12/26 11:25:02

在这里插入图片描述

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。
🍎个人主页:Java Fans的博客
🍊个人信条:不迁怒,不贰过。小知识,大智慧。
💞当前专栏:Java面试题总结
✨特色专栏:国学周更-心性养成之路
🥭本文内容:JJava面试——MyBatis篇

文章目录

    • 1、什么是MyBatis
    • 2、说说MyBatis的优点和缺点
    • 3、#{}和${}的区别是什么?
    • 4、当实体类中的属性名和表中的字段名不一样 ,怎么办 ?
    • 5、Mybatis是如何进行分页的?分页插件的原理是什么?
    • 6、Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
    • 7、 如何执行批量插入?
    • 8、Xml映射文件中,除了常见的select|insert|updae|delete标签之外,还有哪些标签?
    • 9、MyBatis实现一对一有几种方式?具体怎么操作的?
    • 10、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
    • 11、说说Mybatis的缓存机制:
    • 12、JDBC 编程有哪些步骤?
    • 13、MyBatis 中见过什么设计模式?
    • 14、MyBatis 中比如 UserMapper.java 是接口,为什么没有实现类还能调用?

在这里插入图片描述

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对象并返回。(从执行sql到返回result的过程)。

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、#{}和${}的区别是什么?

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

  Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;Mybatis在处理${}时,就是把${}替换成变量的值。

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

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

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

 <select id=”selectorder” parametertype=”int” resultetype=”me.gacl.domain.order”>
	select order_id id, order_no orderno ,order_price price form orders 
	where
	order_id=#{id};
</select>

  第2种: 通过来映射字段名和实体类属性名的一一对应的关系。

<select id="getOrder" parameterType="int" resultMap="orderresultmap">
	select * from orders where order_id=#{id}
</select>
<resultMap type=”me.gacl.domain.order” id=”orderresultmap”>
	<!–-用id属性来映射主键字段-–>
	<id property=”id” column=”order_id”>
	<!–-用result属性来映射非主键字段,property为实体类属性名,column为数据表中的属性-–>
	<result property = “orderno” column =”order_no”/>
	<result property=”price” column=”order_price” />
</reslutMap>

5、Mybatis是如何进行分页的?分页插件的原理是什么?

  Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。可以在sql内直接拼写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页,比如:MySQL数据的时候,在原有SQL后面拼写limit。

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

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

  第一种是使用标签,逐一定义数据库列名和对象属性名之间的映射关系。

  第二种是使用sql列的别名功能,将列的别名书写为对象属性名。

  有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

7、 如何执行批量插入?

  首先,创建一个简单的insert语句:

<insert id=”insertname”>
	insert into names (name) values (#{value})
</insert>

  然后在java代码中像下面这样执行批处理插入:

list<string> names = new arraylist();
names.add(“fred”);
names.add(“barney”);
names.add(“betty”);
names.add(“wilma”);
// 注意这里 executortype.batch
sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch);
try {
	namemapper mapper = sqlsession.getmapper(namemapper.class);
	for (string name : names) {
		mapper.insertname(name);
	}
	sqlsession.commit();
}catch(Exception e){
	e.printStackTrace();
	sqlSession.rollback();
	throw e;
}
finally {
	sqlsession.close();
}

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

  加上动态sql的9个标签,其中为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成策略标签。

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

  有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在resultMap里面配置association节点配置一对一的类就可以完成;嵌套查询是先查一个表,根据这个表里面的结果的 外键id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表的查询通过select属性配置。

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

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

  它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。

  当然了,不光是Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的。

11、说说Mybatis的缓存机制:

Mybatis整体:

在这里插入图片描述

一级缓存localCache

  在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的 SQL,MyBatis 提供了一级缓存的方案优化这部分场景,如果是相同的 SQL 语句,会优先命中一级缓存,避免直接对数据库进行查询,提高性能。

  每个 SqlSession 中持有了 Executor,每个 Executor 中有一个 LocalCache。当用户发起查询时,MyBatis 根据当前执行的语句生成 MappedStatement,在 Local Cache 进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库,结果写入 Local Cache,最后返回结果给用户。具体实现类的类关系图如下图所示:
在这里插入图片描述

  1. MyBatis 一级缓存的生命周期和 SqlSession 一致。
  2. MyBatis 一级缓存内部设计简单,只是一个没有容量限定的 HashMap,在缓存的功能性上有所欠缺。
  3. MyBatis 的一级缓存最大范围是 SqlSession 内部,有多个 SqlSession 或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为 Statement。

二级缓存

  在上文中提到的一级缓存中,其最大的共享范围就是一个 SqlSession 内部,如果多个 SqlSession之间需要共享缓存,则需要使用到二级缓存。开启二级缓存后,会使用 CachingExecutor 装饰Executor,进入一级缓存的查询流程前,先在 CachingExecutor 进行二级缓存的查询,具体的工作流程如下所示。
在这里插入图片描述

  二级缓存开启后,同一个 namespace 下的所有操作语句,都影响着同一个 Cache,即二级缓存被多个 SqlSession 共享,是一个全局的变量。
当开启缓存后,数据的查询执行的流程为:

二级缓存 -> 一级缓存 -> 数据库

  1. MyBatis 的二级缓存相对于一级缓存来说,实现了 SqlSession 之间缓存数据的共享,同时粒度更加细,能够到 namespace 级别,通过 Cache 接口实现类不同的组合,对 Cache 的可控性也更强。
  2. MyBatis 在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。
  3. 在分布式环境下,由于默认的 MyBatis Cache 实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将 MyBatis 的 Cache 接口实现,有一定的开发成本,直接使用 Redis、Memcached 等分布式缓存可能成本更低,安全性也更高。

12、JDBC 编程有哪些步骤?

  1. 装载相应的数据库的 JDBC 驱动并进行初始化:
Class.forName("com.mysql.jdbc.Driver");
  1. 建立 JDBC 和数据库之间的 Connection 连接:
Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8", "root", "123456");
  1. 创建 Statement 或者 PreparedStatement 接口,执行 SQL 语句。
  2. 处理和显示结果。
  3. 释放资源。

13、MyBatis 中见过什么设计模式?

在这里插入图片描述

14、MyBatis 中比如 UserMapper.java 是接口,为什么没有实现类还能调用?

  使用JDK动态代理+MapperProxy。本质上调用的是MapperProxy的invoke方法。


  码文不易,本篇文章就介绍到这里,如果想要学习更多Java系列知识点击关注博主,博主带你零基础学习Java知识。与此同时,对于日常生活有困扰的朋友,欢迎阅读我的第四栏目:《国学周更—心性养成之路》,学习技术的同时,我们也注重了心性的养成。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/342859.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flutter(一)介绍、Dart语言简介

Flutter介绍 纯原生开发主要面临动态化更新和开发成本两个问题&#xff0c;而针对这两个问题&#xff0c;诞生了一些跨平台的动态化框架 跨平台技术简介 Flutter 是 Google 推出并开源的移动应用开发框架&#xff0c;主打跨平台、高保真、高性能。开发者可以通过 Dart 语言开…

【云原生kubernetes】k8s service使用详解

一、什么是服务service&#xff1f; 在k8s里面&#xff0c;每个Pod都会被分配一个单独的IP地址,但这个IP地址会随着Pod的销毁而消失&#xff0c;重启pod的ip地址会发生变化&#xff0c;此时客户如果访问原先的ip地址则会报错 &#xff1b; Service (服务)就是用来解决这个问题的…

Django设计模式以及模板层介绍

MVC和MTV 传统的MVC作用&#xff1a;降低模块间的耦合度&#xff08;解耦&#xff09;Django的MTV模式 作用&#xff1a;降低模块间的耦合度&#xff08;解耦&#xff09;什么是模板 1、模板是可以根据字典数据动态变化的html网页2、模板可以根据视图中传递的字典数据动态生成相…

AtCoder Grand Contest 061(题解)

A - Long Shuffle 这道题本质是一个找规律的题 既然是打表题&#xff0c;我们先暴力把他打出来 (盗一张图.jpg) 接下来就是在这张图中挖掘答案 我们可以明显的看到偶数行是有一些规律的 要么是相邻对的互换&#xff0c;要么不变 不变和互换的位置也有讲究&#xff0c;在二进制…

DS期末复习卷(四)

一、选择题(每题1分共 20分) 1&#xff0e;设一维数组中有n个数组元素&#xff0c;则读取第i个数组元素的平均时间复杂度为&#xff08;C &#xff09;。 (A) O(n) (B) O(nlog2n) © O(1) (D) O(n2) 数组读取元素的时间复杂度为O&#xff08;1&#xff09; 2&#xff0e;设…

SpringCloud Alibaba

文章目录&#x1f68f; 第十七章 SpringCloud Alibaba入门简介&#x1f6ac; 一、为什么使用Alibaba&#x1f6ad; 1、spring netflix进入维护模式&#x1f6ad; Spring cloud alibaba&#x1f6ac; 二、如何使用&#xff1f;&#x1f6ac; 三、版本对应&#x1f68f; 第十八章…

Jmeter接口测试+压力测试

jmeter是apache公司基于java开发的一款开源压力测试工具&#xff0c;体积小&#xff0c;功能全&#xff0c;使用方便&#xff0c;是一个比较轻量级的测试工具&#xff0c;使用起来非常简单。因为jmeter是java开发的&#xff0c;所以运行的时候必须先要安装jdk才可以。jmeter是免…

朴素贝叶斯算法和拉普拉斯平滑详细介绍及其原理详解

相关文章 K近邻算法和KD树详细介绍及其原理详解朴素贝叶斯算法和拉普拉斯平滑详细介绍及其原理详解 文章目录相关文章前言一、朴素贝叶斯算法二、拉普拉斯平滑总结前言 今天给大家带来的主要内容包括&#xff1a;朴素贝叶斯算法、拉普拉斯平滑。这些内容也是机器学习的基础内容…

AXI-Lite 学习笔记

AXI-Lite 学习笔记 参考 FPGA&#xff1a;AXI_Lite总线基础2-1]、第二节 AXI总线介绍、ZYNQ PL与PS交互专题_哔哩哔哩_bilibili AXI-Lite总线系列1 - 基础知识_哔哩哔哩_bilibili AXI4 介绍 AXI4 是ARM公司提出的一种片内总线&#xff0c;描述了主从设备之间的数据传输方式。主…

深入浅出原核基因表达调控(乳糖操纵子、色氨酸操纵子)

原核基因表达调控 前言 自然界里&#xff0c;能量时有时无&#xff0c;各种生命为了让自己能够活下去&#xff0c;需要适应环境&#xff0c;在不同的环境合成不同的蛋白质。 原核生物体内有很多细胞&#xff0c;细胞里面有很多蛋白质&#xff0c;但是这些蛋白质在这些细胞里…

React Draggable插件实现拖拽功能

React Draggable插件实现拖拽功能1.下载Draggable插件2.引入Draggable插件3.设置一个div&#xff0c;并设置样式&#xff0c;并用Draggable包裹起来4.设置拖拽的范围5.Draggable常用props1.下载Draggable插件 npm install react-draggable2.引入Draggable插件 // 引入拖拽插件…

浅谈指向二维数组元素的指针变量

(1)指向数组元素的指针变量 例1.有一个3X4的二维数组,要求用指向元素的指针变量输出二维数组各元素的值. 编写程序 1 #include <stdio.h>2 int main()3 {4 int a[3][4] { 1,3,5,7,9,11,13,15,17,19,21,23 };5 int *p;6 for (p a[0]; p < a[0] 12; p) …

sni+tomcat漏洞复现

sni SNI产生背景 SSL以及TLS&#xff08;SSL的升级版&#xff09;为客户端与服务器端进行安全连接提供了条件。但是&#xff0c;由于当时技术限制&#xff0c;SSL初期的设计顺应经典的公钥基础设施 PKI(Public Key Infrastructure)设计&#xff0c;PKI 认为一个服务器只为一个…

SpringBoot简单集成OpenFeign

问题 在SpringBoot中简单集成Feign&#xff0c;不想使用Rest Temple了。 步骤 Maven <properties><spring.cloud-version>2022.0.1</spring.cloud-version></properties> <dependencyManagement><dependencies><dependency><g…

javaEE 初阶 — 连接管理机制

文章目录连接管理机制1. 建立连接&#xff08;三次握手&#xff09;2. 断开连接&#xff08;四次挥手&#xff09;TCP 的工作机制确认应答机制 超时重传机制 连接管理机制 比如 主机A 的空间存储了 主机B 的 ip 和 端口&#xff0c;主机B 的空间存储了 主机A 的 ip 和 端口。…

autoCAD2022 - 设置新的原点

文章目录autoCAD2022 - 设置新的原点概述笔记UCS原点设置功能的菜单位置ENDautoCAD2022 - 设置新的原点 概述 上次整板子的dxf时, 原来的原点不合适, 想调整一下. 当时整完了, 没记录. 这次用的时候, 又找半天… 设置新原点的功能, 不在顶部菜单中, 而是在视图右上角的UCS图标…

微服务网关(十二)redis流量统计

微服务网关&#xff08;十二&#xff09;redis流量统计中间件 redis流量统计中间件 redis详细&#xff1a; redis.go: // RedisConfPipline redis连接的设置方法&#xff0c;例如在流量统计中间件中设置数据和超时时间 func RedisConfPipline(pip ...func(c redis.Conn)) e…

Linux 内核定时器实验

目录 一、内核时间管理简介 二、内核定时器简介 三、驱动编写 1、修改makefile 2、添加定义 3、初始化led函数 4、添加调用 5、初始化定时器与定时器处理函数 这部分代码如下 四、ioctl函数 五、内核添加unlocked_ioctl 函数 1、添加设备操作集unlocked_ioctl成员 2…

【Android 后台持续定位】

最近工作中遇到了一个涉及后台持续性定位的问题。这里做一下总结&#xff1a;随着Android版本的条件&#xff0c;Google对后台服务管控的也是越来越严格。 这时有的小伙伴会说了&#xff0c;开启一个service然后把服务和通知关联一下变成前台服务&#xff0c;不就行了&#xff…

steam/csgo搬砖,2023年最暴利的项目

这个项目赚钱主要来源于两个地方&#xff1a; 1.比如说今天美元的汇率是1美元6.8人民币&#xff0c;那我们有特定的渠道能拿到1美元5.0-5.5左右人民币的价格&#xff0c;100美元的汇率差利润就有180元左右的利润&#xff0c;当然这个价格是根据国际的汇率上下会有浮动的。 2.…