Java面试题10

1.MyBatis 中 #{}和 ${}的区别是什么?

        #{} 是预编译的占位符,MyBatis会将其转化为一个占位符参数,安全性较高,可以防止 SQL注入; ${} 是字符串替换,直接将内容替换到SQL语句中,不会进行参数处理,潜在风险是 SQL注入

在 MyBatis 中,#{} 和 ${} 都被用作参数绑定,但它们在处理参数的方式和安全性上有很大的区别:

  1. ${}:这是一个基本的字符串替换操作。比如你在 SQL 语句中写${column},MyBatis 就会直接把这个${column}替换成参数的值。由于它的这种直接替换特性,它可能会引起 SQL 注入问题。比如,如果用户恶意设置参数的值为一个 SQL 语句片段,那么他就可以通过这种方式执行任意的 SQL 语句,这就造成了严重的安全问题。因此,我们需要非常小心地使用${},尽量避免在不受信任的输入或用户控制的输入上使用它。
  2. #{}: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 中,一级缓存和二级缓存是两个重要的概念。

  1. 一级缓存:也称为 SqlSession 级别的缓存。每一个新的 SqlSession 有自己的一级缓存,当 SqlSession 进行查询时,会先从一级缓存中查找是否已经存在相应的查询结果,如果存在,则直接返回;如果不存在,再去数据库进行查询,并将查询结果存入一级缓存。一级缓存的生命周期和 SqlSession 保持一致,当 SqlSession 被关闭或清空,那么一级缓存就会消失。
  2. 二级缓存:也称为 Mapper 级别的缓存。二级缓存是多个 SqlSession 共享的,因此,不同的 SqlSession 可以访问、修改和更新二级缓存中的数据。二级缓存的数据会持久化到磁盘中,因此可以跨多个 SqlSession 和多个会话对象进行共享。

MyBatis 的二级缓存可以跨多个 SqlSession,因此它可以在多个数据库之间进行数据共享。然而,需要注意的是,由于二级缓存的数据是共享的,因此如果一个 SqlSession 对数据进行修改,那么这个修改会反映到其他所有的 SqlSession 中。为了避免这种情况,可以在进行修改操作时关闭二级缓存。

总的来说,一级缓存和二级缓存都是 MyBatis 中非常重要的特性,它们可以提高数据库查询的效率,减少对数据库的访问次数。然而,在使用它们时需要注意数据的共享性和一致性问题。

7.MyBatis 和 Hibernate 的区别有哪些?

        MyBatis是基于SQL和映射配置的持久化框架,需要手写SQL,更加灵活;Hibernate是 ORM框架,将Java对象映射到数据库,不需要写SQL,更加面向对象。

MyBatis和Hibernate是两种广泛使用的Java持久化框架,它们的主要区别体现在以下方面:

  1. 原理不同:MyBatis是一种基于SQL语句的持久化框架,通过预编译SQL语句并执行来实现数据库访问。而Hibernate是一种基于对象的持久化框架,通过将Java对象映射到数据库表来实现数据库访问。
  2. 使用方式不同:MyBatis的使用方式更加灵活,允许用户编写自己的SQL语句并执行,支持多种数据库查询方式(如普通查询、存储过程等)。Hibernate也有自己的SQL书写方式,但相较于MyBatis,Hibernate更加注重映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。
  3. 开发难度不同:总体来说,Hibernate的开发难度要大于Mybatis。这主要是因为Hibernate比较复杂、庞大,学习周期较长。而Mybatis相对简单一些,并且Mybatis主要依赖于sql的书写,让开发者感觉更熟悉。
  4. 日志统计和数据库扩展性:Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。不过没有自己的日志统计,所以要借助log4j来记录日志。Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。不过Hibernate具有自己的日志统计。另外,Mybatis由于所有SQL都是依赖数据库书写的,所以扩展性、迁移性比较差。

综上所述,MyBatis和Hibernate各有其优点和缺点。在选择使用时,需要根据具体的项目需求和个人经验进行判断。

8.MyBatis有哪些执行器(Executor)?

        MyBatis有三种执行器,分别是 SimpleExecutor 、 ReuseExecutor 和 BatchExecutor , 用于控制SQL语句的执行。

MyBatis 在其内部实现中使用了三种类型的执行器(Executor),分别是 SimpleExecutor,ReuseExecutor 和 BatchExecutor。

  1. SimpleExecutor:这是一个简单的执行器,每次SQL语句都会重新生成SQL,并且会创建新的结果映射器(Mapper)对象,对于一些非常简单不需要映射的操作比较有用。
  2. ReuseExecutor:这是MyBatis默认的执行器,它会重用预处理语句(PreparedStatement)和结果映射器(Mapper)对象,减少了创建和销毁对象的次数,提高了性能。
  3. 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 自定义插件的示例:

  1. 首先创建一个新的 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) {  // 可以设置自定义的属性  // ...  }  
    }

  2. 在 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();  
}

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

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

相关文章

【腾讯云 HAI域探秘】基于高性能应用服务器HAI部署的 ChatGLM2-6B模型,我开发了AI办公助手,公司行政小姐姐用了都说好!

目录 前言 一、腾讯云HAI介绍&#xff1a; 1、即插即用 轻松上手 2、横向对比 青出于蓝 3、多种高性能应用部署场景 二、腾讯云HAI一键部署并使用ChatGLM2-6B快速实现开发者所需的相关API服务 1、登录 高性能应用服务 HAI 控制台 2、点击 新建 选择 AI模型&#xff0c;…

【C/C++】如何不使用 sizeof 求数据类型占用的字节数

实现代码&#xff1a; #include <stdio.h>#define GET_TYPE_SIZE(TYPE) ((char *)(&TYPE 1) - (char *) & TYPE)int main(void) {char a a;short b 0;int c 0;long d 0;long long e 0;float f 0.0;double g 0.0;long double h 0.0;char* i NULL;print…

Docker 镜像使用

当运行容器时&#xff0c;使用的镜像如果在本地中不存在&#xff0c;docker 就会自动从 docker 镜像仓库中下载&#xff0c;默认是从 Docker Hub 公共镜像源下载。 创建镜像 列出镜像列表 我们可以使用 docker images 来列出本地主机上的镜像。 runoobrunoob:~$ docker imag…

如何在gitlab上使用hooks

参考链接&#xff1a;gitlab git hooks 1. Git Hook 介绍 与许多其他版本控制系统一样&#xff0c;Git 有一种方法可以在发生某些重要操作时&#xff0c;触发自定义脚本&#xff0c;即 Git Hook&#xff08;Git 钩子&#xff09;。 当我们初始化一个项目之后&#xff0c;.git…

Qt 样式表

QLabel&#xff0c;应用于Widget&#xff1a; .QLabel {background-color:pink; }.QLabel[warnlevel_1] {border:5px solid yellow; }.QLabel[warnlevel_2] {border:5px solid red; } QWidget{background-color:rgb(54,54,54); }QLineEdit{border: 1px solid #ABCDA0; /…

《golang设计模式》第三部分·行为型模式-08-状态模式(State)

文章目录 1. 概念1.1 作用1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概念 1.1 作用 状态&#xff08;State&#xff09;指状态对象&#xff0c;用于封装上下文对象的特定状态行为&#xff0c;使得上下文对象在内部状态改变时能够改变其自身的行为。 1.1 角色…

Android设计模式--桥接模式

闻正言&#xff0c;行正道&#xff0c;左右前后皆正人 一&#xff0c;定义 将抽象部分与实现部分分离&#xff0c;使它们都可以独立地进行变化 二&#xff0c;使用场景 从模式的定义中&#xff0c;我们大致可以了解到&#xff0c;这里的桥接的作用其实就是连接抽象部分与实现…

PHP 针对mysql 自动生成数据字典

PHP 针对mysql 自动生成数据字典 确保php 可以正常使用mysqli 扩展 这里还需要注意 数据库密码 如果密码中有特殊字符 如&#xff1a; 首先&#xff0c;我们需要了解MySQL中的特殊字符包括哪些。MySQL中的特殊字符主要包括以下几类&#xff1a; 1. 单引号&#xff08;&a…

HandlerThread

1.HandlerThread 首先它是Thread&#xff0c;继承自Thread public class HandlerThread extends Thread {} 2.与Thread不同的地方 在Thread的run方法里面 调用Looper.prepare()创建Looper调用Looper.loop()&#xff0c;可循环处理消息 public class HandlerThread extends…

嵌入式硬件电路·电平

目录 1. 电平的概念 1.1 高电平 1.2 低电平 2. 电平的使用场景 2.1 高电平使能 2.2 低电平使能 2.3 失能 1. 电平的概念 电平是指电信号电压的大小或高低状态。在数字电子学中&#xff0c;电平有两种状态&#xff0c;高电平和低电平&#xff0c;用来表示二进制中…

ChatGPT初体验:注册、API Key获取与ChatAPI调用详解

自从2022年10月&#xff0c;ChatGPT诞生以后&#xff0c;实际上已经改变了很多&#xff01;其火爆程度简直超乎想象&#xff0c;一周的时间用户过百万&#xff0c;两个月的时间用户过亿。 目前ChatGPT4已经把2023年4月以前的人类的知识都学习到了&#xff0c;在软件工程里面&am…

Matplotlib不规则子图_Python数据分析与可视化

除了网格子图&#xff0c;matplotlib还支持不规则的多行多列子图网格。 plt.GridSpec()对象本事不能直接创建一个图形&#xff0c;他只是 plt.subplot()命令可以识别的简易接口。 这里创建了一个带行列间距的23网格&#xff1a; grid plt.GridSpec(2, 3, wspace0.4, hspace0…

mac VScode 添加PHP debug

在VScode里面添加PHP Debug 插件,根据debug描述内容操作 1: 随意在index里面写个方法,然后用浏览器访问你的hello 方法,正常会进入下边的内容 class IndexController {public function index(){return 您好&#xff01;这是一个[api]示例应用;}public function hello() {phpin…

group by

引入 日常开发中&#xff0c;我们经常会使用到group by。你是否知道group by的工作原理呢&#xff1f;group by和having有什么区别呢&#xff1f;group by的优化思路是怎样的呢&#xff1f;使用group by有哪些需要注意的问题呢&#xff1f; 使用group by的简单例子group by 工…

java学习part12多态

99-面向对象(进阶)-面向对象的特征三&#xff1a;多态性_哔哩哔哩_bilibili 1.多态&#xff08;仅限方法&#xff09; 父类引用指向子类对象。 调用重写的方法&#xff0c;就会执行子类重写的方法。 编译看引用表面类型&#xff0c;执行看实际变量类型。 2.父子同名属性是否…

力扣226. 翻转二叉树

递归 思路&#xff1a; 从根开始递归遍历二叉树&#xff0c;叶节点开始翻转&#xff1b;如果遍历到的当前的 root 节点左右两棵子树已经翻转&#xff0c;交换左右子树即可&#xff1b; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeN…

数组与链表

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 除了HashMap&#xff0…

计算机服务器中了mallox勒索病毒如何处理,mallox勒索病毒解密文件恢复

科技技术的发展推动了企业的生产运营&#xff0c;网络技术的不断应用&#xff0c;极大地方便了企业日常生产生活&#xff0c;但网络毕竟是一把双刃剑&#xff0c;网络安全威胁一直存在&#xff0c;近期&#xff0c;云天数据恢复中心接到很多企业的求助&#xff0c;企业的计算机…

耶鲁博弈论笔记

编辑记录&#xff1a; 1126&#xff1a;开个新坑&#xff0c;耶鲁大学的博弈论课程&#xff0c; 和专业相关不大&#xff0c;纯兴趣&#xff0c;尽量写好一点吧 1. 首先指出博弈论是一种研究策略形式的方法&#xff0c;对于经济学中&#xff0c;完全竞争市场只能被动接受均衡…

合入代码引起的一些问题记录

合入时莫名导致代码丢失 先回退代码&#xff0c;待创个测试分支来看看是什么导致的 远端分支代码还原 通过 git reset 回滚到指定 commit id&#xff1b; git reset --hard <commit_id>远程仓库代码回滚 将本地回滚的代码推送到远程仓库&#xff0c;这里需要加强制的选…