Java——《面试题——MyBatis篇》

news2025/1/10 16:56:02

前文

java——《面试题——基础篇》

Java——《面试题——JVM篇》

Java——《面试题——多线程&并发篇》

Java——《面试题——Spring篇》

目录

前文

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");

2.建立 JDBC 和数据库之间的 Connection 连接:

Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?
characterEncoding=UTF-8", "root", "123456");

3.创建 Statement 或者 PreparedStatement 接口,执行 SQL 语句。

4.处理和显示结果。

5.释放资源。

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

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

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

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

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

相关文章

Flask框架制作读取txt文本网页

Pycharm demo项目 app2.py&#xff08;运行&#xff09; index2.html &#xff08;网页&#xff09; 网页访问地址&#xff1a; http://127.0.0.1:5000 网页画面 核心代码(网页) 点击按钮弹窗选择 txt 文件&#xff08;index2.html&#xff09; <form method"post&…

探索CSS中的粘性定位:解锁网页布局的新可能

这篇文章详细解释了CSS中的sticky定位方式&#xff0c;并讲解了它的工作原理。 CSS中的sticky定位有很好的浏览器支持&#xff0c;但许多开发者并没有使用它。原因有两方面&#xff1a;一是等待浏览器支持的时间太长&#xff0c;导致这个特性被遗忘&#xff1b;二是大部分开发…

OpenCV项目开发实战--一步一步介绍使用 OpenPose 进行基于深度学习的人体姿势估计--C++/Python源码

文末附基于Python和C++两种方式实现的测试代码下载链接 在本教程中,使用 OpenCV 进行基于深度学习的人体姿态估计。我们将详细说明如何在您自己的应用程序中使用预训练 Caffe 模型。 1.姿态估计(又名关键点检测) 姿态估计是计算机视觉中的一个普遍问题,我们在其中检测物体…

西门子Mendix入门

首先进入网址Mendix 点击下方sign up进入带注册页面 我的注册成功后需要等会才能完成注册&#xff0c;我是下午开始注册的&#xff0c;晚上九点半的时候就可以登陆了 点击右上方create Apps 之后进入到这个页面选择应用程序模板 这里我们搜索Task选择第一个 单击Select Templa…

【Arduino+ESP32专题】Visual Studio Code界面重置为默认状态

在使用Visual Studio Code进行编程的时候&#xff0c;有时不小心把某些状态栏或功能框关闭了&#xff0c;不知道从哪里再次打开。因此有一个办法是曲线救国&#xff0c;可以让Visual Studio Code界面重置为默认状态就行了。 方式1 选择右上角Open Settings(UI)图标 打开文档把…

GC相关的

1、判断对象是否为垃圾的算法 引用计数算法可达性分析算法 引用计数算法 判断的标准&#xff1a; 通过判断对象的引用数量来决定对象是否可以被回收。 每个对象实例都有一个引用计数器&#xff0c;被引用则1&#xff0c;完成引用则-1。 任何引用计数为0的对象实例可以被当…

操作系统-I/O管理-I/O系统(设备独立性软件)

目录 一、假脱机技术(SPOOLing技术) 二、设备的分配与回收 2.1设备分配考虑因素 设备的固有属性 设备分配算法 设备分配中的安全性 2.2静态分配和动态分配 2.3设备分配管理中的数据结构 DTC COCT CHCT SDT 三、缓冲区管理 3.1单缓冲 3.2 双缓冲 ​3.2循环缓冲 3.…

1746_Perl中面向对象的目录处理模块

全部学习汇总&#xff1a; GreyZhang/perl_basic: some perl basic learning notes. (github.com) 说起来我还不懂Perl的面向对象编程技术&#xff0c;只是在前阵子看到了书中提到了一句&#xff0c;用到了一个例子。今天看书的时候又看到了类型形势的代码&#xff08;代码中很…

25利用 灰色预测模型预测发电量(附matlab程序)

1.简述 学习目标&#xff1a; 灰色预测模型预测发电量 根据原始发电量数据预测需要年份的发电量 发电量预测是电力系统规划与运行的基础,是电力市场运作中的重要组成部分.目前,对发电量预测的研究已经比较深入,常用的发电量预测方法有:灰色预测法,线性回归模型,自回归移动平均模…

软件测试(1)

软件测试就是用来验证产品特性是否满足用户需求 调试是发现并解决软件中的缺陷 开发人员编码阶段进行 测试是用来发现软件中的缺陷 测试人员&#xff0c;开发人员&#xff08;单元测试&#xff0c;集成测试&#xff09; 测试贯穿于整个软件的生命周期&#xff0c;但是调…

免费在线压缩图片的网站

1. TinyPNG - 这是一个非常受欢迎的在线图片压缩网站,可以压缩 PNG 和 JPG 图片,保证无损压缩。 网址&#xff1a;TinyPNG – Compress WebP, PNG and JPEG images intelligently 2. Compressor.io - 这也是一个很好的在线图片压缩工具,可以批量上传和压缩图片,支持 PNG, JPG 和…

逆向Android开发工程,抓包!抓包!学习哪里?

抓包是什么&#xff1f; 在Android逆向工程中&#xff0c;抓包是一项重要的技术&#xff0c;用于获取手机应用程序与服务器之间的通信数据。通过抓包&#xff0c;可以分析应用程序的网络请求&#xff0c;获取请求的URL、参数、响应数据等信息&#xff0c;对应用程序的行为进行…

JavaSE进阶--注解

文章目录 前言一、概念二、使用实例1、Junit测试中2、JDK内置注解 三、自定义注解1、注解声明2、注解配置参数2.1 配置参数的类型&#xff1a;2.2 注意2.3 两个概念 3、使用注解 四、元注解1、Retention1.1 RetentionPolicy.SOURCE1.2 RetentionPolicy.CLASS1.3 RetentionPolic…

千万不要在简历里写精通C++,没人能真正精通C++

任何说自己很懂C的人可能都是在夸大其词。 我想你可能已经注意到了&#xff0c;是的&#xff0c;今天的大多数程序员都在使用Python、Rust、Go或是其他新的编程语言。大部分人已经不再需要掌握C、C等古老的编程语言了&#xff0c;甚至很多程序员已经从手动编码开始向AI编码转型…

el-select 触底分页+远程搜索

文章目录 前言一、el-select 触底分页远程搜索1.封装触底自定义指令2.在 mian.js 引入封装好的自定义指令3.在组件中进行使用 总结 前言 大部分情况下使用 el-select 的时候&#xff0c;el-options 中 options 的值都是后端接口给的数据&#xff0c;直接赋值就可以了。但是有的…

(8版本)mysql数据库安装教程(自用保存)

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: mysql 参考csdn大神们的文章&#xff0c; 总结出来的详细用法~~~ 目录 文章目录 一、下载MySQL8.0.33 二、配置初始化文件my.ini(重点) 三、初始化MySQL 四、安装MySQL服务并启动 修改密码 4.1 安装…

akima 插值拟合算法 Python/C++版本

目录 前言Akima简介Akima优势 算法的代码实现python版C 版代码解析1代码解析2代码解析3 结果测试 前言 鉴于CSDN上Akima算法文章大部分要VIP观看或者下载&#xff0c;即使是付费也有质量不佳&#xff0c;浪费Money也浪费时间。 笔者更具查到的资料分享给大家。 Akima简介 Ak…

C++技能系列 ( 5 ) - 详解函数入参/返回参使用(值传递/引用传递/指针传递/智能指针传递)

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 期待动动小手&#xff0c;点击关注哦&#xff01;&#xff01;&#xff01; 当你休息的时候&#xff0c;一定要想到别人还在奔跑。 When you rest, we must thin…

数据库相关

1、主要考点思维导图 2、如何设计一个关系型数据库 存储管理&#xff1a;数据逻辑关系转为物理存储关系。 缓存机制&#xff1a;优化执行效率。 SQL解析&#xff1a;将Sql语句进行解析。 日志管理&#xff1a;记录操作。 权限划分&#xff1a;多用户管理。 容灾机制&…

2、瑞丽-伯纳德对流的拉格朗日拟序结构(FTLE场结果对比)

在上篇博客中&#xff0c;我简单比较了瑞丽伯纳德对流的FTLE场&#xff0c;但是因为粒子追踪采用的是欧拉方法&#xff0c;所以精度不是很高&#xff0c; 因此与文献中的结果还是有些差别。 下面放一张文献中的FTLE场&#xff0c;参数与上篇文章是一致的&#xff0c;Ra 1e8;Pr…