【Java超高频面试题&数据库优化&mybatis】数据库优化和mybatis相关高频面试题汇总

简介:

本期文章将汇总数据库优化和mybatis相关的高频面试题,给最近需要找工作的朋友们总结一波,帮助大家全面掌握数据库和mybatis的核心知识点,提升竞争力,为你的面试之旅保驾护航!


MyBatis中${}取值和#{}取值的区别(高频)

#{}能够防止SQL注入,因为底层使用PreparedStatement对象,预编译,性能较高

${}不能防止SQL注入,因为底层使用Statement对象,不会预编译而是拼接字符串,性能较低。

如果需要动态传入表名或者字段名需要用${}比如,像ORDER BY 时只能使用${}

MyBatis对象关联查询和集合关联查询怎么做

单个关联对象用associate,适用于多对一的关联查询,使用javaType来定义实体类型

集合用collection,适用于一对多的关联查询,使用ofType来定义集合的泛型类型

MyBatis一级缓存和二级缓存的区别

缓存,是指将从数据库查询出的数据存放在缓存中,下次使用相同查询时不必再从数据库查询,而是直接从缓存中读取,从而减轻数据库查询的压力,提高性能

mybaits中的一级缓存,是SqlSession级别,默认开启,使用同一个SqlSession发送相同的SQL时命中;它的生命周期和SqlSession一致,当调用SqlSession.close()方法时会释放缓存

mybatis中的二级缓存,是namespace(应用)级别,默认不开启,执行同一个namespace的相同statement(Mapper),发送相同的SQL时命中;它的生命周期是程序结束

当SQL中执行了update()、delete()、insert() 增删改操作,则缓存中的数据都会清空

MyBaitsMapper接口没有实现类为什么可以用@Autowired直接注入

因为动态代理赋值给mapper接口引用的对象其实是一个代理对象,这个代理对象是由 JDK 动态代理创建的。在解析mapper的时候,mybatis会通过java反射,获取到接口所有的方法

当调用接口中方法时,将通过接口全限定名+方法名对应找到映射文件中namespace和id匹配的sql,然后将执行结果返回

MyBatis如何动态修改SQL

使用Mybatis的拦截器可以做到,

Mybatis拦截请求, 拿到sql 动态修改再发送给数据库

MyBaits插入数据后返回主键ID

在定义xml映射器时设置属性useGeneratedKeys值为true,并分别指定属性keyPropertykeyColumn为对应的数据库记录主键字段与Java对象的主键属性。

两个相同列的结果集求并集用什么

union 并集 , union all(允许重复并集)

SELECT column1, column2  FROM table1  WHERE condition1  UNION  
SELECT column1, column2  FROM table2  WHERE condition2;
SELECT column1, column2  FROM table1  WHERE condition1  UNION ALL  
SELECT column1, column2  FROM table2  WHERE condition2;

完整查询SQL中的关键字的定义顺序

SELECT 列名 FROM 表1 JOIN 表2 ON 条件 WHERE 条件 GROUP BY 列名 HAVING 分组条件 ORDER BY 列名 LIMIT

完整的多表JOIN查询,SQL中关键字的执行顺序

FROM --> ON --> JOIN --> WHERE --> GROUP BY --> HAVING --> ORDER BY --> LIMIT

MySQL 中内连接、左连接、右连接有什么区别?

在MySQL中,内连接(Inner Join)、左连接(Left Join)和右连接(Right Join)是用于连接多个表的查询操作,它们之间有以下区别:

1. 内连接(Inner Join):内连接返回两个表中匹配的行,即只返回在连接条件下两个表中都存在的匹配行。如果一行在一个表中没有匹配行,则不会包含在结果中。

2. 左连接(Left Join):左连接返回左表中的所有行以及与右表匹配的行。如果右表中没有匹配的行,则返回NULL值。

3. 右连接(Right Join):右连接返回右表中的所有行以及与左表匹配的行。如果左表中没有匹配的行,则返回NULL值。

MySql的InnoDB是如何保证原子性的

利用了undo log实现的

undo log记录了这些回滚需要的信息,当事务执行失败或调用了rollback,导致事务需要回滚,就可以利用undo log中的信息将数据回滚到修改之前的样子

MySql的InnoDB是如何保证持久性的

利用了redo log实现的

redo log记录的是新数据的备份,在事务提交前,需要将Redo Log持久化,当系统崩溃时,可以根据redo Log的内容,将所有数据恢复到最新的状态

如何去定位慢SQL(高频)

通过druid连接池的内置监控来定位慢SQL

通过MySQL的慢查询日志查看慢SQL

通过show processlist,查看当前数据库SQL执行情况来定位慢SQL

页面上发起的一个查询很慢,你怎么去优化(高频)

首先看一下硬件和网络层面,有没有什么异常

然后分析代码有没有什么问题,算法有没有什么缺陷,比如多层嵌套循环

最后我们再定位到慢SQL,比如

通过druid连接池的内置监控来定位慢SQL

通过MySQL的慢查询日志查看慢SQL

通过show processlist,查看当前数据库SQL执行情况来定位慢SQL

定位到慢SQL再考虑优化该SQL,比如说

不需要的字段就不要查询出来

小结果集驱动大结果集,将能过率更多数据的条件写到前面

in和not in尽量不要用,会导致索引失效

避免在where中使用or链接条件,这会导致索引失效

考虑如果不需要事务,并且主要查询的化,可以考虑使用MyISAM存储引擎

如果优化SQL后还是很慢,可以考虑给查询字段建索引来提升效率

如果建立索引了还是慢,看一下是不是数据量太庞大了,应该考虑分表了

你如何看SQL有没有命中索引(高频)

在SQL语句前加上explain,结果中的key就是实际用到的索引

mysql存储引擎有哪些,有什么区别,如何选择

主要有innodb,memory,myisam

innodb支持事务,速度相对较慢,支持外键,不支持全文索引

myisam 速度相对较快,支持全文索引,不支持外键,不支持事务,

memory不支持事务,基于内存读写,速度快,支持全文索引

如果对事务要求不高,而且是查询为主,考虑用myisam

如果对事务要求高,保存的都是重要的数据,建议使用innodb,它也是默认的存储引擎

如果数据频繁变化的,不需要持久化,可以使用memory

索引失效因素

  • 模糊查询 like “%keyword%” 不会使用到索引,like “keyword%”可以
  • 列是字符串类型,无论是不是字符串数字就一定要用 ‘’ 把它包括起来,否则索引失效
  • 注意:not in 、not exist、!=、< >、like "%_",以及in(select子句) 会导致索引失效
  • 查询的条件列进行过运算或处理,不会走索引,因为不确定计算后的值是什么,如: where DATE_FORMART(start_time,’%y-%m-%d’) = “21-2-23” 不会走索引
  • 查询null值如: where name is null 不会走索引,可以去null设定为 0 来代替。
  • or会导致索引失效
  • 如果mysql估计使用全表扫描要比使用索引快,则不使用索引,比如表里面只有一条记录

Mysql如果想要进行数据还原怎么办?

我们知道redo_log可以对idb的数据进行还原数据,但是redo_log file 体积小,且会循环覆盖,更早的操作就没有办法还原了。这时候我们可以通过binlog来进行数据的还原,binlog是二进制文件,全称是binary_log。像是redis的AOF操作,记录的不是数据,记录的是命令操作,且只有修改操作。若mysql停止,也可以通过bin_log进行还原。

但是开启binlog对性能是有影响的,但是从数据安全性和主从备份方面考虑,是可以选择的。

BinLog刷盘也有三种模式,通过 sync_binlog = 0来设置

sync_binlog = 0 (默认) : 把数据写入page cache,由系统决定什么时候刷盘,Mysql宕机page cache里面的 binlog 会丢失

sync_binlog = 1 : 表示每次提交事务都会执行 fsync 写入磁盘,这种方式最安全。

sync_binlog = 5 :当值大于0表示:数据写入到page cache,累积5个事务后再刷盘,又有数据丢失风险。

需要注意的是,如果主从数据库中从数据库没有备份且binlog中的数据超过自动删除时间就会删除,就无法恢复数据了。


 


结语

🔥如果文章对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论,支持一下小老弟,蟹蟹大咖们~ 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值