MyBatis 面试题(六)

1. MyBatis 有几种分页方式?

MyBatis 的分页方式主要可以分为两大类:逻辑分页和物理分页。

逻辑分页是一次性把全部数据查询加载进内存,然后再进行分页。这种方式减少了IO次数,适合频繁访问、数据量少的情况,但不适合大数据量,容易造成内存溢出。

物理分页则是利用数据库的特性进行分页,例如使用 LIMIT 语法。这种方式适合分页大数据量数据。

具体来说,MyBatis 的分页方式包括:

  1. 借助数组进行分页:首先查询出全部数据,然后在内存中通过数组或List进行截取,获取需要的部分。这种方式属于逻辑分页。
  2. 借助SQL语句进行分页:在SQL语句后面添加LIMIT分页语句,利用数据库的特性进行物理分页。这种方式直接在数据库层面进行操作,效率和性能都相对较高。
  3. 利用拦截器分页:通过拦截器给SQL语句末尾加上LIMIT语句来分页查询,实现物理分页。
  4. 利用RowBounds实现分页:需要一次获取所有符合条件的数据,然后在内存中对大数据进行操作即可实现分页效果。这种方式也属于逻辑分页,对于大数据量可能不太适用。
  5. 使用分页插件:例如PageHelper等分页插件,它们通过拦截MyBatis的SQL语句,自动添加分页相关的SQL片段,从而实现对查询结果的分页。这种方式既方便又灵活,是目前比较常用的分页方式。

在选择分页方式时,应根据具体的业务场景和需求来决定。对于数据量小、频繁访问的场景,可以选择逻辑分页;对于大数据量、需要高效分页的场景,则建议选择物理分页或使用分页插件。

2. MyBatis 逻辑分页和物理分页的区别是什么?

MyBatis的逻辑分页和物理分页在分页的实现方式和数据库负担方面存在显著的区别。

逻辑分页主要依赖于代码,如MyBatis自带的RowBounds插件就是逻辑分页的一个例子。逻辑分页首先会一次性查询出所有的数据,然后再根据代码块的需要(例如需要获取第几页的数据,每页包含多少条数据)来筛选出合适的数据进行分页。这种方式在内存中操作数据,对数据库的访问次数相对较少,但由于需要一次性加载所有数据,如果数据量很大,可能会对内存造成较大的压力。

相比之下,物理分页则更侧重于数据库操作,依赖于数据库提供的分页功能。例如,MySQL数据库提供了“limit”关键字来实现分页,程序员只需要编写带有这些关键字的SQL语句,数据库返回的数据就是分页结果。物理分页每次分页都需要访问数据库,因此它对数据库的负担较大,但由于每次只处理一部分数据,对内存的压力相对较小。

总结来说,逻辑分页和物理分页的主要区别在于:逻辑分页在内存中操作数据,对数据库访问次数少但可能消耗大量内存;而物理分页直接在数据库层面实现分页,每次分页都需要访问数据库但对内存压力较小。在实际应用中,应根据具体需求和场景选择合适的分页方式。

3. MyBatis 流式查询有什么用?

MyBatis 流式查询是一种优化查询的方法,主要用于处理大量数据,以降低内存占用和提高查询速度。在流式查询模式下,查询结果不是一次性加载到内存中,而是逐条从数据库服务器传输到客户端。这意味着应用可以从迭代器中每次取一条查询结果,而不是一次性处理整个结果集。这种方式的优点在于,它允许在内存不足以容纳全部结果集的情况下,仍然能够处理大量数据。

具体来说,流式查询的好处主要体现在以下几个方面:

  1. 降低内存使用:通过流式查询,应用程序不需要一次性加载整个结果集到内存中,从而减少了内存的使用。这在处理海量数据时尤为重要,可以有效避免内存溢出等问题。
  2. 提高查询效率:对于大数据量的查询,一次性加载整个结果集可能会消耗大量的时间和资源。而流式查询允许应用程序逐步处理查询结果,从而提高了查询效率。
  3. 适用于特定场景:流式查询特别适用于需要处理大量数据但不需要同时访问所有数据的情况,例如数据导出、日志分析等。

需要注意的是,在使用流式查询时,数据库连接通常保持打开状态,因此应用需要在取完数据后自己关闭数据库连接,因为数据库访问框架不再负责关闭连接。此外,使用流式查询时,ResultSet对象的一些方法可能会失效,比如absolute()、last()、previous()、beforeFirst()等方法。

总的来说,MyBatis 流式查询是一个数据库访问框架必须具备的功能,它能够在处理大量数据时提供高效的解决方案,降低内存使用并提高查询速度。

4. MyBatis 模糊查询 like 语该怎么写?

在 MyBatis 中进行模糊查询时,通常使用 SQL 的 LIKE 语句配合通配符 % 来实现。通配符 %LIKE 语句中表示任意长度的字符序列(包括零个字符)。

下面是一个在 MyBatis 中使用 LIKE 进行模糊查询的示例:

首先,假设你有一个名为 User 的实体类,它有一个属性 name。你希望根据 name 的部分值来查询用户。

  1. Mapper XML 文件

在 MyBatis 的 Mapper XML 文件中,你可以这样写 SQL 语句:

<select id="findUsersByName" resultType="User">SELECT * FROM userWHERE name LIKE CONCAT('%', #{name}, '%')
</select>

这里使用了 CONCAT 函数来拼接 % 和传入的参数 #{name}。这样,无论传入的 name 是什么,它都会被包裹在 % 之间,从而实现模糊查询。

  1. Mapper 接口

对应的 Mapper 接口方法可能如下:

public interface UserMapper {List<User> findUsersByName(String name);
}
  1. 在 Service 或 Controller 中调用

然后,在你的 Service 或 Controller 中,你可以调用这个 Mapper 方法来进行查询:

@Autowired
private UserMapper userMapper;public List<User> searchUsers(String searchTerm) {return userMapper.findUsersByName(searchTerm);
}

注意:在实际应用中,为了防止 SQL 注入攻击,你应该始终使用预编译的 SQL 语句(即使用 #{} 来绑定参数),而不是直接将参数拼接到 SQL 语句中(即使用 ${})。在上面的示例中,我们使用了 #{} 来绑定 name 参数,这是安全的做法。

5. MyBatis 如何防止 SQL 注入?

MyBatis 通过预编译(PreparedStatement)的方式来防止 SQL 注入。预编译的 SQL 语句在执行时会将参数值作为数据而不是 SQL 的一部分来处理,从而避免了 SQL 注入的风险。

具体来说,MyBatis 在处理 SQL 语句时,会将 SQL 语句中的参数用占位符(通常是 #{})替代,然后在执行 SQL 语句之前,通过 PreparedStatement 对象设置参数值。由于 PreparedStatement 对象会对参数值进行转义和处理,因此即使参数值中包含 SQL 注入攻击的代码,也不会被解析为 SQL 语句的一部分,从而避免了 SQL 注入。

例如,在 MyBatis 的 Mapper XML 文件中,我们可以这样写 SQL 语句:

<select id="selectUserById" resultType="User">SELECT * FROM user WHERE id = #{id}
</select>

在这个例子中,#{id} 是一个占位符,MyBatis 会将它替换为实际的参数值,并使用 PreparedStatement 来设置这个参数。这样,即使 id 的值是一个恶意构造的 SQL 语句片段,它也不会被解析为 SQL 的一部分,因此无法执行 SQL 注入攻击。

需要注意的是,虽然 MyBatis 本身已经提供了防止 SQL 注入的机制,但是在编写 SQL 语句时仍然需要谨慎。特别是当使用 ${} 来直接插入字符串时,需要特别小心,因为这种方式不会进行预编译,如果插入的字符串中包含恶意 SQL 代码,就可能导致 SQL 注入。因此,除非有特别的需求,否则一般推荐使用 #{} 来插入参数。

6. MyBatis 如何获取自动生成的主键id?

在 MyBatis 中,当你插入一条记录到数据库,并且这条记录有一个自动生成的主键(例如,使用 MySQL 的 AUTO_INCREMENT 或者其他数据库的类似机制),你可以通过几种不同的方式来获取这个自动生成的主键 ID。

以下是几种常见的方法:

1. 使用 useGeneratedKeyskeyProperty

你可以在 MyBatis 的 <insert> 标签中使用 useGeneratedKeyskeyProperty 属性来告诉 MyBatis 你想要获取自动生成的主键。

<insert id="insertUser" parameterType="com.example.User" useGeneratedKeys="true" keyProperty="id">INSERT INTO user (name, email) VALUES (#{name}, #{email})
</insert>

在这个例子中,useGeneratedKeys="true" 告诉 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来获取自动生成的主键。keyProperty="id" 指定了哪个属性应该被用来接收这个主键值。在这个例子中,idUser 类的一个属性。

执行插入操作后,你可以直接从传入的 User 对象中获取这个 ID:

User user = new User();
user.setName("John Doe");
user.setEmail("johndoe@example.com");
userMapper.insertUser(user);
Long generatedId = user.getId(); // 这里就是自动生成的主键 ID
2. 使用 selectKey

另一种方法是使用 <selectKey> 标签。这通常在你需要执行一个额外的查询来获取主键时使用,例如在非自增主键的场景中。

<insert id="insertUser" parameterType="com.example.User"><selectKey keyProperty="id" resultType="java.lang.Long" order="AFTER">SELECT LAST_INSERT_ID()</selectKey>INSERT INTO user (name, email) VALUES (#{name}, #{email})
</insert>

在这个例子中,<selectKey> 标签执行了一个查询来获取最后一个插入的 ID(这里假设你使用的是 MySQL)。order="AFTER" 表示在插入操作之后执行这个查询。查询的结果将被设置到 User 对象的 id 属性中。

注意事项:
  • 确保你的数据库驱动和 JDBC 版本支持获取自动生成的主键。大多数现代驱动和 JDBC 版本都支持这个功能。
  • 如果你的数据库表使用了复合主键或者没有使用自动生成的主键机制,那么你可能需要采用其他策略来获取主键。
  • 在某些情况下,你可能需要根据你的数据库和 JDBC 驱动的具体行为来调整这些设置。

7. MyBatis 中jdbcType 和javaType 的区别?

在 MyBatis 中,jdbcTypejavaType 是两个重要的属性,用于指定参数或结果集中字段的数据库类型和 Java 类型。它们的主要区别体现在它们所代表的类型层面和用途上。

jdbcType

jdbcType 是 JDBC 的类型,它表示数据库中的数据类型。当执行 SQL 语句时,MyBatis 会使用 jdbcType 来告诉 JDBC 驱动如何正确地设置或获取参数值或结果集字段的值。jdbcType 是数据库层面上的数据类型,例如 VARCHARINTEGERDATE 等。

在 MyBatis 的映射文件或注解中,你可能会在 <parameterMap><resultMap><insert><update><select> 等标签中看到 jdbcType 属性。它确保 MyBatis 能够正确地将 Java 对象转换为对应的数据库类型,或者将数据库字段的值转换为 Java 对象。

javaType

javaType 是 Java 的类型,它表示 Java 程序中使用的数据类型。在 MyBatis 中,javaType 用于指定 Java 对象的类型,以便 MyBatis 能够正确地将数据库字段的值映射到 Java 对象的属性上,或者将 Java 对象的属性值映射到 SQL 语句的参数中。

javaType 通常用于指定 Java 的基本类型(如 intString)或自定义的 Java 类型(如自定义的实体类)。在 MyBatis 的映射文件或注解中,javaType 常常与 resultMapparameterType 一起使用,以确保数据在 Java 和数据库之间能够正确地转换。

示例

假设你有一个 Java 实体类 User,其中有一个 id 属性,该属性在数据库中是一个整数类型。在 MyBatis 的映射文件中,你可能会这样指定 jdbcTypejavaType

<resultMap id="UserResult" type="com.example.User"><result property="id" column="user_id" jdbcType="INTEGER" javaType="java.lang.Integer"/>
</resultMap>

在这个示例中,jdbcType="INTEGER" 告诉 MyBatis 数据库中的 user_id 字段是一个整数类型,而 javaType="java.lang.Integer" 则告诉 MyBatis 在 Java 中应该将这个字段的值映射到 Integer 类型的属性上。

总结

jdbcTypejavaType 的主要区别在于它们分别代表了数据库层面和 Java 层面的数据类型。在 MyBatis 中,正确设置这两个属性对于确保数据能够正确地在 Java 程序和数据库之间转换是非常重要的。

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

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

相关文章

weblogic反序列化漏洞(CVE-2017-10271)复现

直接用vuluhub搭建现成的靶场做 访问靶场 打开是这样表示成功 想反弹shell 就先开启kali1的nc监听&#xff0c;这就监听2233端口吧 linux&#xff1a;nc -l -p 2233 抓包修改为攻击数据包 ip和端口可以任意修改 反弹的shell 还可以写入文件shell 只需要把提供的poc POS…

【代码随想录】day44

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、完全背包理论基础二、518零钱兑换 II三、377组合总和 Ⅳ总结 一、完全背包理论基础 完全背包&#xff1a;每个物品可以使用无数次。 二、518零钱兑换 II cla…

修复Windows搜索不工作的几种方法,总有一种适合你

序言 Windows搜索是Windows 10中一个非常有用的功能,它允许你搜索特定的程序、应用程序、文档、图片、文件、设置等,以便快速访问它们。但有时Windows搜索找不到我们预期的结果,甚至没有响应,这会给Windows用户带来很多不便。如果Windows 10中的搜索栏不工作,该怎么办?你…

【MySQL】SQL优化

SQL优化 插入数据 insert 一次插入数据和批量插入数据 insert into tb_test (id, name) values (1,Tom); insert into tb_test (id, name) values (1,Tom),(2,Jack),(3,Jerry);优化方案&#xff1a; 手动控制事务&#xff0c;且按主键顺序插入。start transaction; insert …

机器人实验室LAAS-CNRS介绍

一、LAAS-CNRS介绍 1、缩写介绍 同样的&#xff0c;给出英文缩写的全称&#xff0c;以便理解。这里的LAAS&#xff08;Laboratory for Analysis and Architecture of Systems&#xff09;指法国的系统分析与架构实验室&#xff0c;CNRS&#xff08;Centre National de la Rec…

[leetcode]jump-game-iv

. - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组 arr &#xff0c;你一开始在数组的第一个元素处&#xff08;下标为 0&#xff09;。 每一步&#xff0c;你可以从下标 i 跳到下标 i 1 、i - 1 或者 j &#xff1a; i 1 需满足&#xff1a;i 1 < arr.lengt…

oracle存储过程—游标

游标 CURSOR --隐式游标 select into--只能返回一行数据 --显示游标 :处理多行数据,一行一行去处理数据的循环 语法1: DECLAREcursor c_emp ISselect ename,sal from emp;---把查询到的emp表的数据放到游标c_emp中v_row c_emp%rowtype; --引用数据库中的一行(所有字段)作…

C# 十进制数转换为十六进制

在C#中&#xff0c;将十进制数转换为十六进制可以通过以下几种方式实现&#xff1a; 方法一&#xff1a;使用 ToString() 方法 对于整数类型的十进制数&#xff0c;可以直接调用其 ToString() 方法&#xff0c;并传入格式字符串 "X" 或 "x" 来表示转换为…

OpenHarmony实战开发-提升应用响应速度。

应用对用户的输入需要快速反馈&#xff0c;以提升交互体验&#xff0c;因此本文提供了以下方法来提升应用响应速度。 避免主线程被非UI任务阻塞减少组件刷新的数量 避免主线程被非UI任务阻塞 在应用响应用户输入期间&#xff0c;应用主线程应尽可能只执行UI任务&#xff08;…

【电控笔记6.3】采样-Z转换-零阶保持器

本质 数字转模拟:零阶保持器 采样 z-1所描述的物理意义即为延迟T时间的拉氏转换e-sT 信号采样延时

Python --- 新手小白自己动手安装Anaconda+Jupyter Notebook全记录(Windows平台)

新手小白自己动手安装AnacondaJupyter Notebook全记录 这两天在家学Pythonmathine learning&#xff0c;在我刚刚入手python的时候&#xff0c;我写了一篇新手的入手文章&#xff0c;是基于Vs code编译器的入手指南&#xff0c;里面包括如何安装python&#xff0c;以及如何在Vs…

【通信原理笔记】【四】数字基带传输——4.1 数字基带信号

文章目录 前言一、数字信号二、数字基带信号波形2.1 码元波形2.2 相对码2.3 多电平码 总结 前言 从这一节开始介绍数字通信系统中的数字基带传输部分。与模拟通信系统相比&#xff0c;数字通信系统传输的对象是数字的离散信号而非连续的模拟信号&#xff0c;本节先学习什么是数…

bfs解答迷宫

bfs解答迷宫问题 #include<bits/stdc.h> using namespace std; int dir[4][2]{-1,0,0,-1,0,1,1,0};//方向数组规律去记忆&#xff08;有对称规律&#xff09; int bfs(vector<vector<char> >& maze,vector<vector<bool> >& vis,int sx…

在传统云安全失败时提供帮助的六种策略

随着基于内存的攻击的激增继续挑战传统的云安全防御&#xff0c;对主动和全面的安全措施的需求变得至关重要。采用结合端点检测和响应、内存完整性保护和定期更新的多层方法可以加强对这些难以捉摸的威胁的防御。 随着云计算技术在各行各业的迅速普及&#xff0c;数据保护和安全…

linux系统安全与应用【下】

目录 1.开关机安全控制 1.1GRUB限制 2.终端登录安全控制 2.1 限制root只在安全终端登录 2.2 禁止普通用户登录 3.弱口令检测 3.1 Joth the Ripper&#xff08;JR&#xff09; 4.网络端口扫描 4.1 nmap命令 1.开关机安全控制 1.1GRUB限制 通常情况下在系统开机进入GRU…

详解:老阳说的temu电商项目怎么做才更赚钱?

近年来&#xff0c;电商行业蓬勃发展&#xff0c;temu电商项目作为其中的一员&#xff0c;也受到了广泛关注。老阳作为行业内的资深人士&#xff0c;对于temu电商项目有着独到的见解。那么&#xff0c;如何才能做好temu电商项目呢? 首先&#xff0c;要明确temu电商项目的定位和…

Day39 网络编程(一):计算机网络,网络编程,网络模型,网络编程三要素

Day39 网络编程&#xff08;一&#xff09;&#xff1a;计算机网络&#xff0c;网络编程&#xff0c;网络模型&#xff0c;网络编程三要素 文章目录 Day39 网络编程&#xff08;一&#xff09;&#xff1a;计算机网络&#xff0c;网络编程&#xff0c;网络模型&#xff0c;网络…

基于Spring6的文件上传与下载

基于Spring6的文件上传与下载 1、文件上传1.1表单准备web.xml中配置 1.2 控制器代码 2. 文件下载2.1 下载链接2.1 对应控制器 1、文件上传 从浏览器向客户端上传的过程 1.1表单准备 <form th:action"{/fileup}" method"post" enctype"multipart…

day07 51单片机-串口通信

51 单片机-串口通信 1 串口通信 1.1 需求描述 本案例讲解如何通过串口和PC以9600波特率,无校验位、1停止位通信。最终实现PC向单片机发送字符串,单片机回复PC。本案例中采用串口1通信。 1.2 硬件设计 1.2.1 串口工作原理 串口是将数据按照比特逐一发送的通信接口。在串…

Python 开发实现登陆和注册模块

Python 开发实现登陆和注册模块 一、案例介绍 本例设计一个用户登录和注册模块&#xff0c;使用Tkinter框架构建界面&#xff0c;主要用到画布、文本框、按钮等组件。涉及知识点&#xff1a;Python Tkinter界面编程、pickle数据存储。本例实现了基本的用户登录和注册互动界面…