JavaWeb编程面试题——MyBatis
引言
面试题==知识点,这里所记录的面试题并不针对于面试者,而是将这些面试题作为技能知识点来看待。不以刷题进大厂为目的,而是以学习为目的。这里的知识点会持续更新,目录也会随时进行调整。
关注公众号:编程火箭车。在【粉丝福利】中点击【面题大全】,其中的Java面试题在线实时更新、查看。
一、面试题导航
点这里进入JavaWeb编程面试题——导航
面试题持续更新中......
二、面试题目
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 很好的集成(MyBatis 官方提供与 Spring 的整合包);
(5)提供映射标签,支持对象与数据库的 ORM 字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
缺点:
(1)SQL 语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写 SQL 语句的功底有一定要求。
(2)SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
3.MyBatis框架适用场合?
MyBatis 专注于 SQL 自身,是一个足够灵活的 DAO 层解决方案。对性能的要求很高,或者需求变化较多的项目,例如 Web 项目,互联网项目等等, MyBatis 都是不错的选择。
4.MyBatis框架原理?
MyBatis 配置:SqlMapConfig.xml,此文件作为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息。mapper.xml 文件即 SQL 映射文件,文件中配置了操作数据库的 SQL 语句。此文件需要在 SqlMapConfig.xml 中加载。
通过 MyBatis 环境等配置信息构造 SqlSessionFactory 即会话工厂。
由会话工厂创建 sqlSession 即会话,操作数据库需要通过 sqlSession 进行。
MyBatis 底层自定义了 Executor 执行器接口操作数据库,Executor 接口有两个实现,一个是基本执行器、一个是缓存执行器。
Mapped Statement 也是 MyBatis 一个底层封装对象,它包装了 MyBatis 配置信息及 SQL 映射信息等。mapper.xml 文件中一个 SQL 对应一个 Mapped Statement 对象,SQL 的 id 即是 Mapped statement 的 id。
Mapped Statement 对 SQL 执行输入参数进行定义,包括 HashMap、基本类型、POJO,Executor 通过 Mapped Statement 在执行 SQL 前将输入的 Java 对象映射至 SQL 中,输入参数映射就是 JDBC 编程中对 preparedStatement 设置参数。
Mapped Statement 对 SQL 执行输出结果进行定义,包括 HashMap、基本类型、POJO,Executor 通过 Mapped Statement 在执行 SQL 后将输出结果映射至 Java 对象中,输出结果映射过程相当于 JDBC 编程中对结果的解析处理过程。
5.MyBatis和Hibernate的区别?
(1)MyBatis 和 Hibernate 不同,它不是一个完全的 ORM 框架,因为 MyBatis 需要程序员自己编写 SQL 语句;
(2)MyBatis 直接编写原生态 SQL,可以严格控制 SQL 执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一旦有需求变化可以迅速输出成果。但是灵活的前提是 MyBatis 无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套 SQL 映射文件,工作量大。
(3)Hibernate 对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用 Hibernate 开发可以节省很多代码,提高效率。
6.MyBatis有哪些动态标签?
if 标签:判断是否符合条件
foreach 标签:对一个集合进行遍历
where 标签:补充响应的 where 的 SQL 语句
sql 标签:定义可重用的 SQL 代码段,可以包含在其他语句中。
......
7.MyBatis中一对一如何实现?
在映射文件中 resultMap
元素里配置 association
节点,配置一对一的类就可以完成。
8.MyBatis中一对多如何实现?
在映射文件中 resultMap
里面配置 collection
节点,配置一对多的类就可以完成。
9.MyBatis编程步骤?
创建
SqlSessionFactory
会话工厂通过
SqlSessionFactory
创建SqlSession
会话通过
sqlSession
执行数据库操作通过 `session.commit()`` 提交事务
调用 `session.close()`` 关闭会话
10.MyBatis的一级缓存和二级缓存?
Mybatis 首先会到缓存中查询结果集,如果没有则查询数据库,如果有则直接从缓存取出结果集。Mybatis 内部存储缓存使用一个 HashMap,key 为 hashCode+sqlId+Sql 语句。value 为从查询出来映射生成的 Java 对象。
Mybatis 的一级缓存即本地缓存,它的作用域是一个 sqlSession 会话,即在同一个 sqlSession 中两次执行相同的 SQL 语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。
Mybatis 的二级缓存即查询缓存,它的作用域是一个 mapper 的 namespace,即在同一个 namespace 中查询相同的 SQL 可以从缓存中获取数据。二级缓存是可以跨 SqlSession 的。
11.#{} 和 ${} 区别?
#{}
表示一个占位符号,可以有效防止sql注入。${}
表示拼接sql串,在低版本中括号中只能是value。#{}
表示一个占位符号,通过#{}
可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}
可以有效防止sql注入。#{}
可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}
括号中可以是value或其它名称。${}
表示拼接sql串,通过${}
可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换。${}
可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,低版本中${}
括号中只能是value。
12.Mybatis的mapper.xml文件中常用标签有哪些?
<select>、<insert>、<update>、<delete>、<sql>、<resultMap>、<set>、<where>...
13.Mybatis的xml映射文件中,不同的xml映射文件,id是否可以重复?
不同的xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复;原因就是namespace+id是作为Map<String, MapperStatement>的key使用的,如果没有namespace,就剩下id,那么,id重复会导致数据互相覆盖。有了namespace,自然id就可以重复,namespace不同,namespace+id自然也就不同。
备注:在旧版本的Mybatis中,namespace是可选的,不过新版本的namespace已经是必须的了。
14.MyBatis 分页如何处理?
mybatis分页查询有两种方案:
可以通过limit关键字拼接SQL语句,需要两个参数,第一个参数为开始条数,第二个参数为查询个数。
可以通过 pageHelper 插件实现:
在sqlMapConfig 文件中配置 mybatis的插件(plugins)
在查询数据前通过 PageHelper.start() 方法,调用 PageHelper 插件,参数为当前页和每页显示条数
查询结果会封装到一个page对象中,包含分页查询记录、总记录数、总页数等
从page对象中获取需要的数据
15.Mybatis是如何进行分页的?分页插件的原理是什么?
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
16.如何获取自动生成的主键?
自增主键返回
mysql 自增主键,执行 insert 提交之前自动生成一个自增主键。可以通过 mysql 函数获取刚插入记录的自增主键:LAST_INSERT_ID(),是在insert之后去调用。
<insert id="insertTeacher" parameterType="Teacher" >
<selectKey keyProperty="id" resultType="java.lang.Integer" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO teacher (name,idcard,sex) VALUES (#{name},#{idcard},#{sex})
</insert>
设置insert属性获取自增id
<insert id="insertTeacher" parameterType="Teacher" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO teacher (name,idcard,sex) VALUES (#{name},#{idcard},#{sex})
</insert>
非自增主键返回
mysql 使用 uuid 实现主键,需要修改表中 id 字段类型为 varchar,长度至少36位。
执行思路:先通过 uuid() 查询到主键,将主键输入到 SQL 语句中。执行 uuid() 语句顺序相对于 insert语句在之前。<!-- 使用mysql的uuid()生成主键
执行过程:
首先通过uuid()得到主键,将主键设置到teacher对象的id属性中
其次在insert执行时,从teacher对象中取出id属性值
-->
<insert id="insertTeacher" parameterType="Teacher">
<selectKey keyProperty="id" resultType="java.lang.String" order="BEFORE">
SELECT UUID()
</selectKey>
INSERT INTO teacher (id,name,idcard) VALUES (#{id},#{name},#{idcard})
</insert>
17.在mapper中如何传递多个参数?
第一种:直接多个参数
// DAO层 接口
User listUsers(String name, String sex);
<!-- mapper映射文件
#{0}代表接收dao层方法中的第一个参数,#{1}代表接收第二个参数,更多参数一直往后加即可
-->
<select id="listUsers" resulType="User">
select * from user where name=#{0} and sex=#{1}
</select>
第二种:使用@param注解
// DAO层 接口
User listUsers(@param("uname") String name, @param("usex") String sex);
<!-- mapper映射文件 -->
<select id="listUsers" resulType="User">
select * from user where name=#{uname} and sex=#{usex}
</select>
第三种:多个参数封装成map集合
// 映射文件的命名空间.sql片段的id,就可以调用对应的映射文件的SQL
// 由于参数超过了两个,而方法中只有一个Object参数收集,因此我们使用Map集合来封装参数
Map<String, Object> map = new HashMap<>();
map.put("uname", "张三");
map.put("usex", "男");
sqlSession.selectList("user.listUsers", map);
<!-- mapper映射文件 -->
<select id="listUsers" resulType="User">
select * from user where name=#{uname} and sex=#{usex}
</select>
18.使用mapper接口开发DAO时有哪些要求?
Mapper.xml 文件中的 namespace 与 mapper 接口的类路径相同。
Mapper 接口方法名和 Mapper.xml 中定义的每个 statement 的 id 相同
Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类型相同
Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相同
19.MyBatis的配置文件sqlMapConfig.xml中有哪些内容?
配置内容和顺序如下:
- configuration(配置)
- properties(属性)
- settings(全局配置参数)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
20.MyBatis中有哪些重要组件?
MyBatis是一个开源的Java持久化框架,它可以轻松访问关系数据库,将SQL语句和数据映射到Java对象中,并提供了很多高级特性。下面是MyBatis中的几个重要组件:
SqlSession:SqlSession是MyBatis的核心接口之一,其作用相当于对JDBC操作的封装。SqlSession提供了执行SQL语句、提交事务、获取Mapper映射器等操作。
Configuration:Configuration是MyBatis的全局配置类,它负责解析和管理MyBatis的配置文件,并提供了许多高级特性,如缓存配置、类型别名配置、插件配置等。
Mapper映射器:Mapper映射器是MyBatis中用于映射Java方法与SQL语句的方法。通过Mapper映射器,可以将Java方法和SQL语句绑定在一起,从而轻松地在Java中执行SQL语句。
Executor:Executor是MyBatis中用于执行SQL语句的核心接口,它负责从SqlSession中接收SQL语句并执行它们,同时还负责缓存结果、处理事务等操作。
TypeHandler:TypeHandler是MyBatis中的重要组件之一。它负责将Java对象和数据库中的数据进行转换。MyBatis中默认提供了很多TypeHandler,同时也支持自定义TypeHandler。
这些组件构成了MyBatis框架的核心,并提供了许多高效、易用、可扩展的特性,使开发人员可以轻松地进行数据访问和持久化操作。
关注公众号:编程火箭车
我们定期发布编程相关的文章、资讯、活动等内容。帮助编程爱好者、初学者或初级程序员快速入门、打牢基础。欢迎大家关注,和我们一起探索编程的精彩世界。
JavaWeb编程面试题——MyBatis的更多相关文章
- Javaweb编程中的乱码问题
程序中的乱码问题,主要出现在我们处理中文数据的过程中出现.从浏览器向服务器请求数据,服务器返回的数据在浏览器中显示为乱码.或者是服务器中的java文件用到中文,也有可能会出现乱码.数据库在处理数据的时 ...
- [手把手教程][JavaWeb]优雅的SpringMvc+Mybatis整合之路
来源于:http://www.jianshu.com/p/5124eef40bf0 [手把手教程][JavaWeb]优雅的SpringMvc+Mybatis整合之路 手把手教你整合最优雅SSM框架:S ...
- C语言编程规范试题(标准答案)
C语言编程规范试题(标准答案) 一.单选题(每小题3分,共20小题60分) 1.1-1.5 B D A C B 1.6-1.10 C A D B C 1.11 ...
- C语言编程规范试题
C语言编程规范试题 [说明]: 1.本试题中不考虑头文件引用问题(假定已经包含正确的头文件),C语言的标准函数都可用: 2.如果不特别说明,假定程序运行环境为:操作系统Windows 2000, VC ...
- Java 并发编程面试题
并发编程面试题-内存模型说下内存模型定义为什么要有内存模型为什么要重排序,重排序在什么时候排如何约束重排序规则happens-before什么是顺序一致性CAS 实现的原理,是阻塞还是非阻塞方式?什么 ...
- C++ 高质量编程附录试题
附录B :C++/C试题 本试题仅用于考查C++/C程序员的基本编程技能.内容限于C++/C常用语法,不涉及数据结构.算法以及深奥的语法.考试成绩能反映出考生的编程质量以及对C++/C的理解程度,但不 ...
- Java并发编程面试题 Top 50 整理版
本文在 Java线程面试题 Top 50的基础上,对部分答案进行进行了整理和补充,问题答案主要来自<Java编程思想(第四版)>,<Java并发编程实战>和一些优秀的博客,当然 ...
- 合格linux运维人员必会的30道shell编程面试题及讲解
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://oldboy.blog.51cto.com/2561410/1632876 超深度 ...
- (转)合格linux运维人员必会的30道shell编程面试题及讲解
超深度讲解shell高级编程实战,截至目前shell编程课程国内培训机构最细的课程,不信请看学员表现的水平. 课程牛不牛,不是看老师.课表,而是看培养的的学生水平,目前全免费中伙伴们赶紧看啊. htt ...
- Linux运维必会的实战编程笔试题(19题)
以下Linux运维笔试面试编程题,汇总整理自老男孩.马哥等培训机构,由运维派根据实战需求,略有调整: 企业面试题1:(生产实战案例):监控MySQL主从同步是否异常,如果异常,则发送短信或者邮件给管理 ...
随机推荐
- .net core 自定义授权策略提供程序进行权限验证
.net core 自定义授权策略提供程序进行权限验证 在这之前先了解一下鉴权和授权的概念: 鉴权 鉴权可以说是身份验证,身份验证是确定用户身份的过程: 在ASP.NET Core 中身份验证是由身份 ...
- Teamcenter_SOA开发:使用SOA登录Teamcenter
本文Teamcenter SOA使用C++参考SOA的例子进行编写,以下代码为登录Teamcenter,代码工程在Teamcenter四层环境下运行. SOA的库文件.样例文件.帮助文件在Teamce ...
- odoo 开发入门教程系列-计算的字段和变更(Computed Fields And Onchanges)
计算的字段和变更(Computed Fields And Onchanges) 模型之间的关系是任何Odoo模块的关键组成部分.它们对于任何业务案例的建模都是必要的.然而,我们可能需要给定模型中字段之 ...
- Linux 端口及防火墙常用命令
Linux 端口及防火墙操作 查看端口操作 一. netstat命令 -t (tcp) 仅显示tcp相关选项 -u (udp)仅显示udp相关选项 -n 拒绝显示别名,能显示数字的全部转化为数字 -l ...
- 教程 - 在 Vue3+Ts 中引入 CesiumJS 的最佳实践@2023
目录 1. 本篇适用范围与目的 1.1. 适用范围 1.2. 目的 2. 牛刀小试 - 先看到地球 2.1. 创建 Vue3 - TypeScript 工程并安装 cesium 2.2. 清理不必要的 ...
- Springboot一些常用注解
Springboot启动注解 @SpringbootApplication 这个注解是Springboot最核心的注解,用在Springboot的主类上,标识这是一个Springboot应用,用来开启 ...
- SpringBoot应用集成微服务组件Nacos
目录 springboot与微服务组件nacos Nacos服务快速启动 STS4 开发工具 Maven 环境配置 STS4开发工具引入Maven配置 Maven Repo配置阿里云镜像源 Sprin ...
- 通过重构来加深理解——DDD
上部分模型驱动设计的构造块为维护模型和实现之间的关系打下了基础.在开发过程中使用一系列成熟的基本构造块并运用一致的语言,能够使开发工作更加清晰而有条理. 我们面临的真正挑战是找到深层次的模型,这个模型 ...
- python字符串集合面试笔试题
python字符串面试笔试题 以下代码的输出是? s = 'foo' t = 'bar' print('barf' in 2 * (s + t)) A.True B.Fasle +运算符连接字符串,而 ...
- JS Bom(window)对象
window 是客户端浏览器对象模型的基类,window 对象是客户端 JavaScript 的全局对象.一个 window 对象实际上就是一个独立的窗口,对于框架页面来说,浏览器窗口每个框架都包含一 ...