写在前面
这是Spring-Mybatis核心知识篇,可用于八股文复习宝典,也可用于加深知识,建议大家以闯关的模式进行阅读,然后根据内容查漏补缺,欢迎提问相互学习交流。
之前已经完成了
相关每篇文章有最新学习收获,都会做出相应更新修改
后续还将更新最后一篇
- 分布式缓存核心知识点
Spring-Mybatis核心知识篇知识速览
什么是Spring框架的DI和IOC
Spring里面 bean的scope作用域有哪些
什么是AOP, 使用场景有哪些
AOP里面常见的概念
什么是静态代理
什么是动态代理,spring aop是用什么代理
JDK动态代理和CGLib动态代理的区别
JDBC连接数据库的开发步骤
#{ }和${}的区别是什么?
Mybatis一级缓存
Mybatis二级缓存
一级缓存和二级缓存同时启用,查询顺序是怎样的
什么是Mybatis3.X的懒加载
什么是Spring框架的DI和IOC
IOC 控制反转,指将对象的创建权,反转到Spring容器
DI 依赖注入,指Spring创建对象的过程中,将对象依赖属性通过配置进行注入,不能单独存在,需要在IOC的基础上完成操作
依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。
Spring里面 bean的scope作用域有哪些
singleton:单例, 默认值,调用getBean方法返回是同一个对象,实例会被缓存起来,效率比较高 当一个bean被标识为singleton时候,spring的IOC容器中只会存在一个该bean
prototype: 多例,调用getBean方法创建不同的对象,会频繁的创建和销毁对象造成很大的开销
其他少用 (作用域 只在 WebApplicationContext)
request :每个Http请求都会创建一个新的bean
session: 每个Http Session请求都会创建一个新的bean
global session(基本不用)
什么是AOP, 使用场景有哪些
Aspect Oriented Program 面向切面编程, 在不改变原有逻辑上增加额外的功能
AOP思想把功能分两个部分,分离系统中的各种关注点
核心关注点
业务的主要功能
横切关注点
非核心、额外增加的功能
用户下单为例子
核心关注点:创建订单
横切关注点:记录日志、控制事务
好处
减少代码侵入,解耦
可以统一处理横切逻辑
方便添加和删除横切逻辑
AOP里面常见的概念
横切关注点
对哪些方法进行拦截,拦截后怎么处理,这些就叫横切关注点
比如 权限认证、日志、事物
通知 Advice
在特定的切入点上执行的增强处理
做啥? 比如你需要记录日志,控制事务 ,提前编写好通用的模块,需要的地方直接调用
连接点 JointPoint
要用通知的地方,业务流程在运行过程中需要插入切面的具体位置,
一般是方法的调用前后,全部方法都可以是连接点
只是概念,没啥特殊
切入点 Pointcut
不能全部方法都是连接点,通过特定的规则来筛选连接点, 就是Pointcut,选中那几个你想要的方法
在程序中主要体现为书写切入点表达式(通过通配、正则表达式)过滤出特定的一组 JointPoint连接点
过滤出相应的 Advice 将要发生的joinpoint地方
切面 Aspect
通常是一个类,里面定义 切入点+通知 , 定义在什么地方; 什么时间点、做什么事情
通知 advice指明了时间和做的事情(前置、后置等)
切入点 pointcut 指定在什么地方干这个事情
web接口设计中,web层->网关层->服务层->数据层,每一层之间也是一个切面,对象和对象,方法和方法之间都是一个个切面
目标 target
目标类,真正的业务逻辑,可以在目标类不知情的条件下,增加新的功能到目标类的链路上
织入 Weaving
把切面(某个类)应用到目标函数的过程称为织入
什么是静态代理
由程序创建或特定工具自动生成源代码,在程序运行前,代理类的.class文件就已经存在
通过将目标类与代理类实现同一个接口,让代理类持有真实类对象,然后在代理类方法中调用真实类方法,在调用真实类方法的前后添加我们所需要的功能扩展代码来达到增强的目的
A -> B -> C
优点
代理使客户端不需要知道实现类是什么,怎么做的,而客户端只需知道代理即可
方便增加功能,拓展业务逻辑
缺点
代理类中出现大量冗余的代码,非常不利于扩展和维护
如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度
什么是动态代理,spring aop是用什么代理
在程序运行时,运用反射机制动态创建而成,无需手动编写代码
SpringAOP里面常用的是 JDK动态代理、CGLIB动态代理
JDK动态代理和CGLib动态代理的区别
JDK动态代理,要求目标对象实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候就可以用CGLib动态代理
JDK动态代理是自带的,CGlib需要引入第三方包
CGLib动态代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展
CGLib动态代理基于继承来实现代理,所以无法对final类、private方法和static方法实现代理
Spring AOP中的代理使用的默认策略
如果目标对象实现了接口,则默认采用JDK动态代理
如果目标对象没有实现接口,则采用CgLib进行动态代理
如果目标对象实现了接口,程序里面依旧可以指定使用CGlib动态代理
JDBC连接数据库的开发步骤
加载数据库驱动
获取数据连接对象
获取语句对象
会话对象有两种Statement和PreparedStatement执行语句,他们区别是?
PreparedStatement在执行之前会进行预编译
效率高于Statement,且能够有效防止SQL注入
PreparedStatement支持?占位符而不是直接拼接,提高可读性
处理结果集
关闭资源
关闭的时候先关闭ResultSet,再关闭Statement,最后关闭Connection注意关闭顺序以及处理异常
#{ }和${}的区别是什么?
#{}是预编译处理,${}是字符串替换。
Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
Mybatis在处理${}时,就是把${}替换成变量的值。
使用#{}可以有效的防止SQL注入,提高系统安全性
Mybatis一级缓存
简介:一级缓存的作用域是SQLSession,同一个SqlSession中执行相同的SQL查询(相同的SQL和参数),第一次会去查询数据库并写在缓存中,第二次会直接从缓存中取
基于PerpetualCache 的 HashMap本地缓存,默认开启一级缓存
失效策略:当执行SQL时候两次查询中间发生了增删改的操作,即insert、update、delete等操作commit后会清空该SQLSession缓存; 比如sqlsession关闭,或者清空等
Mybatis二级缓存
二级缓存是namespace级别的,多个SqlSession去操作同一个namespace下的Mapper的sql语句,多个SqlSession可以共用二级缓存,如果两个mapper的namespace相同,(即使是两个mapper,那么这两个mapper中执行sql查询到的数据也将存在相同的二级缓存区域中,但是最后是每个Mapper单独的名称空间)
基于PerpetualCache 的 HashMap本地缓存,可自定义存储源,如 Ehcache/Redis等
默认是没有开启二级缓存
操作流程:
第一次调用某个namespace下的SQL去查询信息,查询到的信息会存放该mapper对应的二级缓存区域。
第二次调用同个namespace下的mapper映射文件中,相同的sql去查询信息,会去对应的二级缓存内取结果
失效策略:执行同个namespace下的mapepr映射文件中增删改sql,并执行了commit操作,会清空该二级缓存
注意:实现二级缓存的时候,MyBatis建议返回的POJO是可序列化的, 也就是建议实现Serializable接口
缓存淘汰策略:会使用默认的 LRU 算法来收回(最近最少使用的)
一级缓存和二级缓存同时启用,查询顺序是怎样的
优先查询二级缓存-》查询一级缓存-》数据库
什么是Mybatis3.X的懒加载
按需加载,先从单表查询,需要时再从关联表去关联查询,能大大提高数据库性能, 并不是所有场景下使用懒加载都能提高效率
哪些查询配置支持懒加载
resultMap里面的association、collection有延迟加载功能