Java面试题10
1.MyBatis 中 #{}和 ${}的区别是什么?
#{} 是预编译的占位符,MyBatis会将其转化为一个占位符参数,安全性较高,可以防止 SQL注入; ${} 是字符串替换,直接将内容替换到SQL语句中,不会进行参数处理,潜在风险是 SQL注入
在 MyBatis 中,#{} 和 ${} 都被用作参数绑定,但它们在处理参数的方式和安全性上有很大的区别:
${}:这是一个基本的字符串替换操作。比如你在 SQL 语句中写${column},MyBatis 就会直接把这个${column}替换成参数的值。由于它的这种直接替换特性,它可能会引起 SQL 注入问题。比如,如果用户恶意设置参数的值为一个 SQL 语句片段,那么他就可以通过这种方式执行任意的 SQL 语句,这就造成了严重的安全问题。因此,我们需要非常小心地使用${},尽量避免在不受信任的输入或用户控制的输入上使用它。#{}:MyBatis 会使用预编译语句(PreparedStatement)的方式,通过在 SQL 中构建一个参数占位符?并设值参数来防止 SQL 注入,来安全地处理#{}中的值。这也是 MyBatis 推荐的方式来处理动态参数。你可以在查询中写#{userId},然后在你的参数映射中有一个userId的字段,MyBatis 就会安全地为你的 SQL 语句设值。
总结一下,#{}比${}更安全,因为它通过预编译的方式处理参数,可以防止 SQL 注入。除非在你完全确定没有 SQL 注入风险的情况下,一般情况下我们更推荐使用#{}。
2.MyBatis 有几种分页方式?
MyBatis有两种分页方式,一种是使用 RowBounds 进行内存分页,另一种是使用插件进行物理分页。
RowBounds 是 MyBatis 中的一个分页对象,它可以将所有符合条件的数据全都查询到内存中,然后在内存中对数据进行分页。然而,这种分页操作是对 ResultSet 结果集进行分页,也就是人们常说的逻辑分页,而非物理分页,效率低下,不建议使用。
3.RowBounds 是一次性查询全部结果吗?为什么?
是的, RowBounds 方式是一次性查询全部结果,MyBatis会将整个结果集读取到内存中, 然后进行分页操作。
Mybatis可以通过传递RowBounds对象,来进行数据库数据的分页操作,然而遗憾的是,该分页操作是对ResultSet结果集进行分页,也就是人们常说的逻辑分页,而非物理分页(物理分页当然就是我们在sql语句中指定limit和offset值)。
4.MyBatis 逻辑分页和物理分页的区别是什么?
逻辑分页是在数据库中查询所有结果,然后在应用层进行分页;物理分页是通过数据库的特 定语法(如 LIMIT 、 OFFSET )进行分页,只查询所需数据。
逻辑分页是在应用程序层面进行的,它首先从数据库查询出所有的结果,然后在应用程序中对这些结果进行分页显示。这种方法的优点是简单易用,适用于数据量较小的情况。然而,如果数据量很大,查询所有的数据可能会消耗大量的内存和时间。
物理分页是利用数据库的特定语法(如SQL中的LIMIT和OFFSET)进行的,这意味着数据库直接返回所需的数据记录,而不是所有的数据。这种方法的优点是效率高,适用于处理大量数据。然而,使用不同的数据库系统可能会对LIMIT和OFFSET等关键字的支持程度不同,因此可能需要进行一些调整。
5.MyBatis 是否支持延迟加载?延迟加载的原理是什么?
是的,MyBatis支持延迟加载。延迟加载是指在需要时才真正查询关联对象,原理是在查询 主对象时只查询主对象的数据,当访问关联对象属性时,再根据需要进行关联查询。
MyBatis 支持延迟加载。延迟加载(Lazy Loading)是一种常用的优化技术,用于在需要时才加载数据。在 MyBatis 中,可以通过配置来实现延迟加载。
延迟加载的原理是,在初始加载时,只加载必要的少量数据,然后在需要的时候才加载更多的数据。这样可以减少初始加载的时间和内存消耗,提高应用的启动速度和响应速度。
在 MyBatis 中,可以通过配置 fetchType 属性来实现延迟加载。例如,可以将 fetchType 设置为 lazy 来实现延迟加载。当设置为 lazy 时,MyBatis 只会加载与当前查询结果相关的数据,而不是一次性加载所有数据。
延迟加载的原理是基于对象代理实现的。在 MyBatis 中,可以通过配置 <association> 和 <collection> 元素来实现对象代理。当配置了这些元素后,MyBatis 会为相关对象生成代理对象,从而实现在需要时才加载数据的效果。
需要注意的是,延迟加载可能会增加数据库的查询次数,从而影响应用的性能。因此,在使用延迟加载时,需要根据实际情况进行权衡和优化。
6.说一下 MyBatis 的一级缓存和二级缓存?
一级缓存是指在同一个SqlSession中,查询的结果会被缓存起来,以提高性能;二级缓存是 指多个SqlSession之间共享缓存,可以跨Session共享数据。
MyBatis 是一个优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 消除了几乎所有的 JDBC 代码和参数的手动设置以及结果集的检索。
在 MyBatis 中,一级缓存和二级缓存是两个重要的概念。
- 一级缓存:也称为 SqlSession 级别的缓存。每一个新的 SqlSession 有自己的一级缓存,当 SqlSession 进行查询时,会先从一级缓存中查找是否已经存在相应的查询结果,如果存在,则直接返回;如果不存在,再去数据库进行查询,并将查询结果存入一级缓存。一级缓存的生命周期和 SqlSession 保持一致,当 SqlSession 被关闭或清空,那么一级缓存就会消失。
- 二级缓存:也称为 Mapper 级别的缓存。二级缓存是多个 SqlSession 共享的,因此,不同的 SqlSession 可以访问、修改和更新二级缓存中的数据。二级缓存的数据会持久化到磁盘中,因此可以跨多个 SqlSession 和多个会话对象进行共享。
MyBatis 的二级缓存可以跨多个 SqlSession,因此它可以在多个数据库之间进行数据共享。然而,需要注意的是,由于二级缓存的数据是共享的,因此如果一个 SqlSession 对数据进行修改,那么这个修改会反映到其他所有的 SqlSession 中。为了避免这种情况,可以在进行修改操作时关闭二级缓存。
总的来说,一级缓存和二级缓存都是 MyBatis 中非常重要的特性,它们可以提高数据库查询的效率,减少对数据库的访问次数。然而,在使用它们时需要注意数据的共享性和一致性问题。
7.MyBatis 和 Hibernate 的区别有哪些?
MyBatis是基于SQL和映射配置的持久化框架,需要手写SQL,更加灵活;Hibernate是 ORM框架,将Java对象映射到数据库,不需要写SQL,更加面向对象。
MyBatis和Hibernate是两种广泛使用的Java持久化框架,它们的主要区别体现在以下方面:
- 原理不同:MyBatis是一种基于SQL语句的持久化框架,通过预编译SQL语句并执行来实现数据库访问。而Hibernate是一种基于对象的持久化框架,通过将Java对象映射到数据库表来实现数据库访问。
- 使用方式不同:MyBatis的使用方式更加灵活,允许用户编写自己的SQL语句并执行,支持多种数据库查询方式(如普通查询、存储过程等)。Hibernate也有自己的SQL书写方式,但相较于MyBatis,Hibernate更加注重映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。
- 开发难度不同:总体来说,Hibernate的开发难度要大于Mybatis。这主要是因为Hibernate比较复杂、庞大,学习周期较长。而Mybatis相对简单一些,并且Mybatis主要依赖于sql的书写,让开发者感觉更熟悉。
- 日志统计和数据库扩展性:Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。不过没有自己的日志统计,所以要借助log4j来记录日志。Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。不过Hibernate具有自己的日志统计。另外,Mybatis由于所有SQL都是依赖数据库书写的,所以扩展性、迁移性比较差。
综上所述,MyBatis和Hibernate各有其优点和缺点。在选择使用时,需要根据具体的项目需求和个人经验进行判断。
8.MyBatis有哪些执行器(Executor)?
MyBatis有三种执行器,分别是 SimpleExecutor 、 ReuseExecutor 和 BatchExecutor , 用于控制SQL语句的执行。
MyBatis 在其内部实现中使用了三种类型的执行器(Executor),分别是 SimpleExecutor,ReuseExecutor 和 BatchExecutor。
- SimpleExecutor:这是一个简单的执行器,每次SQL语句都会重新生成SQL,并且会创建新的结果映射器(Mapper)对象,对于一些非常简单不需要映射的操作比较有用。
- ReuseExecutor:这是MyBatis默认的执行器,它会重用预处理语句(PreparedStatement)和结果映射器(Mapper)对象,减少了创建和销毁对象的次数,提高了性能。
- BatchExecutor:这是批量执行器,它主要用于执行批量操作,可以一次执行多条SQL语句。
9.MyBatis 分页插件的实现原理是什么?
MyBatis分页插件通过拦截SQL执行,将原始SQL改写为带有分页参数的SQL,然后执行修改后的SQL,最终返回分页结果。
MyBatis 分页插件的实现原理主要是利用了 MyBatis 的插件机制。分页插件通过拦截 MyBatis 的执行语句,在 SQL 执行前后进行相应的操作,以达到分页的效果。
具体来说,分页插件首先通过实现 MyBatis 的插件接口,如 Interceptor,来拦截待执行的 SQL 语句。在拦截到 SQL 语句后,插件会根据 SQL 语句的内容和参数,生成对应的物理分页语句和物理分页参数。然后,插件会将这些物理分页语句和参数插入到原始 SQL 语句中,并继续执行 SQL 语句。
在执行物理分页语句时,插件会根据数据库方言(dialect)的不同,使用不同的物理分页语法。例如,对于 MySQL 数据库,可以使用 LIMIT 和 OFFSET 关键字;对于 Oracle 数据库,可以使用 ROWNUM 关键字等。
另外,为了提高性能,分页插件通常会缓存已经执行过的 SQL 语句和对应的物理分页语句和参数。这样,在下次执行相同 SQL 语句时,可以直接使用缓存的物理分页语句和参数,避免了重复的生成和执行过程。
需要注意的是,虽然物理分页可以提高查询效率,但也可能会增加数据库的负载。因此,在使用物理分页时,需要根据具体的应用场景和数据库性能来权衡选择。
10.MyBatis 如何编写一个自定义插件?
编写MyBatis自定义插件需要实现 Interceptor 接口,然后通过在MyBatis配置文件中配置 插件,使其生效。插件可以在SQL执行前后进行拦截,实现自定义的功能。
MyBatis 允许用户编写自定义的插件,以便对 SQL 语句进行更细粒度的控制和扩展。以下是一个简单的 MyBatis 自定义插件的示例:
-
首先创建一个新的 Java 类,并让它实现
Interceptor接口:import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.plugin.*; import java.sql.Connection; import java.util.Properties; @Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}) }) public class MyInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); // 这里可以对 SQL 语句进行修改或扩展 // ... // 继续执行原始操作 return invocation.proceed(); } @Override public Object plugin(Object target) { if (target instanceof StatementHandler) { return Plugin.wrap(target, this); } else { return target; } } @Override public void setProperties(Properties properties) { // 可以设置自定义的属性 // ... } } -
在
intercept方法中,你可以通过StatementHandler对象获取到 SQL 语句,然后对 SQL 语句进行修改或扩展。这里是一个简单的示例,它将 SQL 语句中的所有SELECT关键字替换为SELECT * FROM:
@Override
public Object intercept(Invocation invocation) throws Throwable { StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); String sql = statementHandler.getBoundSql().getSql(); String newSql = sql.replace("SELECT", "SELECT * FROM"); // 设置新的 SQL 语句到 StatementHandler 中,以便后续执行 ((BoundSql) statementHandler.getBoundSql()).setSql(newSql); // 继续执行原始操作 return invocation.proceed();
}
相关文章:
Java面试题10
1.MyBatis 中 #{}和 ${}的区别是什么? #{} 是预编译的占位符,MyBatis会将其转化为一个占位符参数,安全性较高,可以防止 SQL注入; ${} 是字符串替换,直接将内容替换到SQL语句中,不会进行参数处理…...
DBeaver连接MySQL提示“Public Key Retrieval is not allowed“问题解决方式
更新时间:2023年10月31日 11:37:53 作者:产品人小柒 dbeaver数据库连接工具,可以支持几乎所有的主流数据库.mysql,oracle.sqlserver,db2 等等,这篇文章主要给大家介绍了关于DBeaver连接MySQL提示"Public Key Retrieval is not allowed"问…...
振弦式轴力计和振弦采集仪组成的安全监测解决方案
振弦式轴力计和振弦采集仪组成的安全监测解决方案 振弦式轴力计和振弦采集仪是一种常用的结构安全监测工具,可以用于评估建筑物、桥梁、隧道或其他结构的结构健康状态和安全性能。这种监测方案较为先进、精确,并且能够监测长期的结构反应,因此…...
卡尔曼滤波
通过 Eigen 矩阵运算实现线性卡尔曼滤波。模拟的是一辆带火箭发动机的汽车,一开始沿着X轴匀速运动,到X轴中间开启火箭发动机匀加速向Y轴起飞。同理可以仿真(x,y,z,yaw,pitch,raw) 6自由度的真实飞行情况 #include <iostream&g…...
不受平台限制,Sketch 网页版震撼登场
Sketch 是一种基于 Mac 的矢量图形编辑器,可用于数字设计。其主要功能包括无损矢量编辑、完美像素精度和数百个插件同步功能,可导出预设和代码。它是目前流行的页面交互协作设计工具。但是 Sketch 最大的缺点是对 Windows/PC 用户不友好。严格来说&#…...
如何使用.pth训练模型
一.使用.pth训练模型的步骤如下: 1.导入必要的库和模型 import torch import torchvision.models as models# 加载预训练模型 model models.resnet50(pretrainedTrue) 2.定义数据集和数据加载器 # 定义数据集和数据加载器 dataset MyDataset() dataloader to…...
C++11线程以及线程同步
C11中提供的线程类std::thread,基于此类创建一个新的线程相对简单,只需要提供线程函数和线程对象即可 一.命名空间 this_thread C11 添加一个关于线程的命名空间std::this_pthread ,此命名空间中提供四个公共的成员函数; 1.1 get_id() 调用命名空间s…...
深度学习之基于YoloV3杂草识别系统
欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 深度学习在图像识别领域已经取得了显著的成果,其中基于YOLO(You Only Look Once)…...
Linux 命令vim(编辑器)
(一)vim编辑器的介绍 vim是文件编辑器,是vi的升级版本,兼容vi的所有指令,同时做了优化和延伸。vim有多种模式,其中常用的模式有命令模式、插入模式、末行模式:。 (二)vim编辑器基本操作 1 进入vim编辑文件 1 vim …...
轻松配置PPPoE连接:路由器设置和步骤详解
在家庭网络环境中,我们经常使用PPPoE(点对点协议过夜)连接来接入宽带互联网。然而,对于一些没有网络专业知识的人来说,配置PPPoE连接可能会有些困难。在本文中,我将详细介绍如何轻松配置PPPoE连接ÿ…...
电源控制系统架构(PCSA)之系统分区电源域
目录 4.2 电源域 4.2.1 电源模式 4.2.2 电源域的选择 4.2.3 系统逻辑 4.2.4 Always-On域 4.2.5 处理器Clusters 4.2.6 CoreSight逻辑 4.2.7 图像处理器 4.2.8 显示处理器 4.2.9 其他功能 4.2.10 电源域层次结构要求 4.2.11 SOC域示例 4.2 电源域 电源域在这里被定…...
Linux:docker基础操作(3)
docker的介绍 Linux:Docker的介绍(1)-CSDN博客https://blog.csdn.net/w14768855/article/details/134146721?spm1001.2014.3001.5502 通过yum安装docker Linux:Docker-yum安装(2)-CSDN博客https://blog.…...
【Axure教程】用中继器制作卡片多条件搜索效果
卡片设计通过提供清晰的信息结构、可视化吸引力、易扩展性和强大的交互性,为用户界面设计带来了许多优势,使得用户能够更轻松地浏览、理解和互动。 那今天就教大家如何用中继器制作卡片的模板,以及完成多条件搜索的效果,我们会以…...
Linux中vi常用命令-批量替换
在日常服务器日志查看中常用到的命令有grep、tail等,有时想查看详细日志,用到vi命令,记录下来,方便查看。 操作文件:test.properites 一、查看与编辑 查看命令:vi 文件名 编辑命令:按键 i&…...
logback-spring.xml的内容格式
目录 一、logback-spring.xml 二、Logback 中的三种日志文件类型 一、logback-spring.xml <?xml version"1.0" encoding"UTF-8"?> <configuration scan"true" scanPeriod"10 seconds" ><!-- <statusListener…...
nodejs+vue+elementui+express青少年编程课程在线考试系统
针对传统线下考试存在的老师阅卷工作量较大,统计成绩数据时间长等问题,实现一套高效、灵活、功能强大的管理系统是非常必要的。该系统可以迅速完成随机组卷,及时阅卷、统计考试成绩排名的效果。该考试系统要求:该系统将采用B/S结构…...
Navicat 技术指引 | GaussDB 数据查看器
Navicat Premium(16.2.8 Windows版或以上) 已支持对GaussDB 主备版的管理和开发功能。它不仅具备轻松、便捷的可视化数据查看和编辑功能,还提供强大的高阶功能(如模型、结构同步、协同合作、数据迁移等),这…...
Docker的registry
简介 地址:https://hub.docker.com/_/registry Dcoker registry是存储Dcoker image的仓库,运行push,pull,search时,是通过Dcoker daemon与docker registry通信。有时候会用Dcoker Hub这样的公共仓库可能不方便&#x…...
【vue_3】关于超链接的问题
1、需求2、修改前的代码3、修改之后(1)第一次(2)第二次(3)第三次(4)第四次(5)第五次 1、需求 需求:要给没有超链接的列表添加软超链接 2、修改前…...
redis优化秒杀和消息队列
redis优化秒杀 1. 异步秒杀思路1.1 在redis存入库存和订单信息1.2 具体流程图 2. 实现2.1 总结 3. Redis的消息队列3.1 基于list实现消息队列3.2 基于PubSub实现消息队列3.3 基于stream实现消息队列3.3.1 stream的单消费模式3.3.2 stream的消费者组模式 3.4 基于stream消息队列…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...
DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...
