1、MyBatis结果集映射,单个关联对象用什么映射,一个集合用什么映射
单个对象:使用association标签,javaType定义实体类类型。
集合对象:使用collection标签,ofType定义集合泛型。
2、多表查询,join查询和额外SQL方式查询区别
额外SQL:在查询一个主对象时,使用单表查询,在resultmap中额外发送一个子SQL查询关联对象,然后映射给主对象。
join:查询时一次查出管理数据,用resultMap映射结果。
区别:join查询只需一条SQL就可以查询出数据,而额外SQL会涉及N+1问题,每查询出一条主表数据,就需要发送一条SQL查询管理的数据。
3、MyBatis中#{}和${}的区别
#:以预编译的形式将参数于SQL语句中,相当于原生JDBC的PreparedStatement,防止SQL注入。
$:直接以拼接的方式拼接到SQL中,会有安全问题。在原生JDBC不支持占位符的地方可以使用,比如表名、排序。
4、MyBatis关联查询,延迟加载和饥饿加载的区别
延迟加载:先从单表查询,只有需要使用关联数据时才发起查询。
饥饿加载:在查询时立即将关联数据查询出,不管用不用。
5、MyBatis一级缓存和二级缓存
一级缓存:基于SqlSesion,默认开启,在操作数据库时需要构造一个SqlSession对象,在对象中有一个hashmap用于存储数据,不同的SqlSesion之间的缓存数据相互不影响。作用是SqlSesion范围,在同一个SqlSesion中执行两次相同的SQL,第一次会将数据缓存到内存中,第二次直接拿内存中的数据。当关闭SqlSesion时(会话),一级缓存也随之消失。
二级缓存:基于SqlSesionFactory,默认不开启,不管是不是相同的SqlSesion,只要mapper的namespace相同就可以共享缓存,生命周期是程序结束。
在执行了增删改提交到数据库后,一二级缓存会被清空,为了数据的准确性。
6、Mybatis的Mapper接口没有实现类为什么可以@Autowire直接注入
JDK动态代理会创建一个对象给mapper的引用对象。在解析mapper时,mybaits会通过反射获取mapper中的方法,通过全限定名、方法名去对比映射文件中的namespace和id,获取到对应SQL后,执行返回结果。
7、PreparedStatement和statement的区别
PreparedStatement:对象的开销比较大,多次操作的效率高。它是预编译的,支持一次编译多次操作,同时可以防止SQL注入。
Statement:每次执行SQL都需要数据库进行编译。
8、连接池的作用,数据库连接池的原理。
作用:不使用连接池会直接去访问数据库非常耗时耗力,直接连接的话会经历建立物理通道,服务器对链接身份验证等。连接池中存放了一定量的链接,当访问数据库时只需要获取空闲的链接。这样减少了数据库的开销,提高程序的性能。
原理:连接池建立:系统初始化时,连接池会根据系统配置建立连接对象。
连接池使用:连接池管理策略是连接池机制的核心。
1、如果连接池有空闲链接,放回该链接。
2、没有空闲连接则新建一个链接。
3、如果超过最大连接数量,则进行最大等待时间排队。
4、如果超过最大等待时间则抛异常。
连接池的关闭:当应用程序退出时,关闭连接池中的所有连接。
9、MyBaits中mapper如何传递多个参数
通过参数列表中的@Param。
10、事务
数据库的最小工作单元;这些操作作为一个整体一起向系统提交,要么都执行、要么都不
执行
11、事务的四大特性
原子性:事务是数据库的逻辑工作单位,事务包含的各种操作要么都做,要么都不做。
一致性:数据库从一个一致性状态转变到另一个一致性状态。它与原子性密切相关。
隔离性:事务执行不能被其他事务干扰。即事务内部使用操作的数据不能被其他线程使用。
持久性:事务一旦提交,他对数据的更改就是永久性的。
12、InnoDB如何保证原子性和持久性
原子性是利用undo log,回滚日志。,记录执行前的数据。当事务执行失败或rollback时,就会调用undolog中的信息将数据回滚成修改前的样子。
持久性是利用redolog,他由两部分组成:重做日志缓存(redo log buffer)、重做日志文件(redo log file)。事务进行的时候会将信息放到缓存中, 在按照一定的频率刷新到文件中。
13、事务并发问题
脏读:一个事务访问数据并做修改,还未提交,此时另一个事务也会访问这个数据,并使用了这个数据。
不可重复读:一个事务两次读到不同的数据。另一个事务在这个事务两次读取间更改导致
幻读,也叫虚读:事务A两次读取相同条件的数据,两次查询到的数据条数不一致,是由
于事务B再这两次查询中插入或删除了数据造成的
不可重复读重点在于update,而幻读的重点在于insert,delete
第一类丢失更新:也叫回滚丢失,事务A和事务B更新同一条数据,事务B先完成了修改,此时事务A异常终止,回滚后造成事务B的更新也丢失了
第二类丢失更新:也叫覆盖丢失,事务A和事务B更新同一条数据,事务B先完成了修改,事务A再次修改并提交,把事务B提交的数据给覆盖了
14、事务隔离级别有哪些,分别能解决什么问题
串行化:使用表级锁,让事务一个一个的按顺序执行,可避免事务的所有并发问题。
可重复读:事务读会阻塞其他事务的写但不阻塞读,事务写会阻塞其他事务读和写,防止脏读、不可重复度读、一二类丢失更新。
读已提交:事务读不会阻塞其他事务读和写,事务写会阻塞其他事务的读和写,能解决第一类丢失更新,脏读的问题
读未提交:事务读不阻塞其他事务的读和写,事务写阻塞其他事务的写但不阻塞读,能解决第一类丢失更新的问题。
15、事务执行流程
数据更改的时候,会将原来的数据保存到undolog,将要更改的数据保存的到redolog,在将要更改的数据通过redolog写入磁盘。
16、事务并发丢失更新问题概念,如何解决
第一类丢失更新:也叫回滚丢失,事务A和事务B更新同一条数据,事务B先完成了修改,此时事务A异常终止,回滚后造成事务B的更新也丢失了
第二类丢失更新:也叫覆盖丢失,事务A和事务B更新同一条数据,事务B先完成了修改,事务A再次修改并提交,把事务B提交的数据给覆盖了
SQL标准中的四种隔离级别,读未提交,读已提交,可重复读,串行化,都能解决第一类数据更新丢失问题
第二类丢失更新:悲观锁也就是串行化来解决;使用乐观锁,比如加版本号管理来解决
17、InnoDB事务隔离实现的原理
隔离的实现主要利用了读写锁和MVCC机制
读写锁,要求在每次读操作时需要获取一个共享锁,写操作时需要获取一个写锁。共享锁之间不会产生互斥,共享锁和写锁,写锁与写锁之间会产生互斥。当产生锁竞争时,需要等一个操作的锁释放,另一个操作才能获得锁
MVCC,多版本并发控制,它是在读取数据时通过一种类似快照的方式将数据保存下来,不同的事务看到的快照版本是不一样的,即使其他事务修改了数据,但是对本事务仍然是不可见的,它只会看到第一次查询到的数据
可重复读是只在事务开始的时候生成一个当前事务全局性的快照,而读提交则是每次执行语句的时候都重新生成一次快照
18、为什么不用select *
1、不需要的列会增加数据传输的时间和开销
2、对于无用的字段会增加磁盘的IO。针对大字段varchar、text等
3、可能会失去“覆盖索引”。
覆盖索引:查询的时候只要查询的字段有索引,且没有其他无索引字段。
覆盖索引不会进行回表操作。
19、索引失效
MySql 索引失效、回表解析_mysql is null_小目标青年的博客-CSDN博客
1、建索引的字段类型为varchar,但是查询的时候没有使用‘’,没有加引号。(涉及隐式转换)
2、使用like进行左模糊匹配(“%XXX”)。
3、索引字段作为查询条件,使用了计算或函数。
4、使用OR,条件字段中包含未有设索引的字段。只有设置唯一索引才行。
5、不满做最佳左前缀原则。建立的联合索引最左边的存在查询 条件中才会命中索引。
6、is not null 和is null。is null不一定会,当执行SQL时,MySQL认为全表扫描比使用索引快的时候,那么索引失效。
20、SQL优化一般步骤
1、尽量避免使用子查询
2、用IN来替换OR
3、读取适当的记录LIMIT M,N,而不要读多余的记录
4、禁止不必要的Order By排序
5、总和查询可以禁止排重用union all
6、避免随机取记录
7、将多次插入换成批量Insert插入
8、只返回必要的列,用具体的字段列表代替 select * 语句
9、区分in和exists
10、优化Group By语句
11、尽量使用数字型字段
12、优化Join语句
21、大数据量的情况下使用limit怎么优化
1、使用子查询。
select * from table where id in
(
select id from (select id from table where type = 1 limit 10000,10 ) childtable
)
2、分页的时候把上页最后的id作为条件
select id from table where id > 100000 limit 10
22、MySQL的执行流程
客户端发起SQL查询,首先通过连接器,他会检查用户的身份,包括校验密码权限等
然后查询缓存,如果缓存命中直接返回,没有命中在执行后续操作,MySQL8后删除缓存功能
接下来到达分析器,进行语法检查,比如SQL错误,中共的关键字,要查询那些东西
优化器,MySQL以自己的方式优化执行的SQL语句
执行器,调用存储引擎执行SQL返回结果
23、如何查看SQL是否用到了索引
在SQL语句前加上explain。
24、mysql存储引擎有哪些,有什么区别,如何选择
INNODB:支持事务、速度较慢、不支持全文索引、支持外键。对事务要求高、保存重要数据,默认
MyISAM:不支持事务、速度较快、支持全文索引、不支持外键。事务要求不高、查询为主
Memory;不支持事务、基于内存,速度贼快,支持全文索引。数据变化频繁,不要持久化
25、Mysql索引有哪些类型?索引方式有哪些
普通索引normal:允许空值,可在如何字段上添加
唯一索引Unique:不能有重复值,其他和普通索引一样
主键索引:当把某个列设为主键时,数据库自动为它创建索引,数据唯一且不能为空
全文索引:针对MyISAM有用。对文本进行索引。其他引擎用ES
26、Mysql的索引结构原理?为什么用B+tree
底层采用的是B+树:
1、数据值存放叶子节点,非叶子节点存储更多key,整体能存储更多数据
2、叶子节点是双向链表,进行区间查询只需要顺着叶子节点的指针查询即可
3、MySQL查询是按页查询,没加载一页就一次IO操作,在磁盘中一个磁盘页就对应
一个B+ 树节点,所以可以减少IO次数
不用:数组、链表:增删、查询慢
普通二叉树:极端情况树会退化为链表
红黑树:相对于B树性能稍差,IO次数较多
Hash:虽然精确查找速度快、但是大量哈希碰撞下速度还是慢、不支持排序、分组、
范围查找等
27、InnoDB的索引结构和MyIsam的索引结构有什么区别
他们都是用的B+树,不同的是
innodb的叶子节点存放的是数据,myisam的叶子节点存放的是数据的地址
innodb中辅助索引的叶子节点存放的是主键索引的键值,myisam中辅助索引的叶子节点存放的也是数据的地址
innodb的索引和数据都存放到一个文件中,myisam的索引和数据分别存放到不同的文件中
(辅助索引:叶子节点保存主键值)
28、那些列不适合创建索引
不经常查询的列不适合创建索引
不出现在where中的字段不适合创建索引
离散度太低的字段不适合创建索引,比如性别
更新非常频繁的字段不适合创建索引
29、组合索引的匹配原则 , 你优选使用单列索引和是组合索引,为什么
优先选择组合索引,因为对覆盖索引命中率更高,查询性能更高
但是应该考虑列的顺序,因为组合索引会向左匹配(左右两个列,只使用右边列不会进行索引)