Spring、MyBatis、SpringMVC 框架 - 面试宝典
又到了
金三银四、金九银十
的时候了,是时候收藏一波面试题了,面试题可以不学,但不能没有!🥁🥁🥁
一个合格的计算机打工人
,收藏夹里必须有一份 SSM 框架 八股文 面试题 ,特别是即将找工作的计算机人,希望本篇博客对你有帮助!
祝各位计算机人都可以在就业季里,顺利通过面试,找到钱多事少离家近
的满意工作 😀😀😀
面试题系列
博客导航🚥🚥🚥:
- 🥬 JavaSE 八股文 面试宝典
- 🥕 MySQL 八股文 面试宝典
- 🥪 Spring、MyBatis、SpringMVC 八股文 面试宝典
⇦当前位置🪂
- 🍊 SpringBoot框架 八股文 面试宝典
- 🍒
未完待续 ...
- 🎨 如果有一天你 厌倦上班、厌倦996 ,想要
考研备考
的话:408 全套初复试笔记汇总 传送门 🏃🏃🏃
后续随着自己的学习,也会陆续补充新的面试题,如果对大家起到帮助的话,
求赞👍 、求收藏 👏、求关注!👀
1.1 Spring基本概念
01. 简述Spring框架以及主要模块
Spring是一个轻量级的控制反转和面向切面的开源容器框架
Spring有七大功能模块:
1.Core Core模块是Spring的核心类库,Core实现了IOC功能
2.AOP
Spring AOP模块是Spring的AOP库,提供了AOP(拦截器)机制,并提供了常见的拦截器,供用户自定义和配置
3.ORM
提供对常用ORM框架的管理和支持,Hibernate、MyBatis等
4.Dao
Spring提供对JDBC的支持,对JDBC进行封装
5.WEB
对Struts2的支持
6.Context
Context模块提供框架式的Bean的访问方式,其他程序可以通过Conetext访问Spring的Bean资源,相当于资源注入
7.MVC
MVC模块为Spring提供了一套轻量级的MVC实现,即Spring MVC
02. 使用Spring框架优点
1.轻量级框架、容器
Spring是一个容器,管理对象的生命周期和配置。
基于一个可配置原型prototype,你的bean可以是单例的,也可以每次需要时都生成一个新的实例。
2.控制反转IOC Spring的IOC减低了业务对象替换的复杂度,提高了组件之间的解耦。
3.支持AOP Spring提供对AOP的支持,它运行将一些通用任务,如安全、事务、日志等进行集中处理,从而提高程序的复用性。
4.方便测试 提供了JUnit4的支持,可以通过注解方便测试spring程序
5.集成了各种优秀框架和庞大生态圈
6.支持声明式事务处理 只需要通过配置就可以完成对事务的管理
03. 简述控制反转(IOC)、依赖注入
借助Spring实现具有依赖关系的对象之间的解耦:
对象A运行需要对象B,有主动创建变为IOC容器注入,这便是控制反转。
控制什么:在实现过程中所需要的对象及需要依赖的对象。
什么是反转:在没有IOC容器之前我们都是在对象中主动去创建依赖的对象,这是正转的;
而有了IOC之后,依赖的对象直接由IOC容器创建后注入到对象中,由主动创建变成了被动接受,这是反转。获得依赖对象的过程被反转了,获取依赖对象的过程 由自身创建变为由IOC容器注入,这便是依赖注入。
04. 简述下AOP
AOP全称叫做 Aspect Oriented Programming 面向切面编程。它是为解耦而生的,解耦是程序员编码开发过程中一直追求的境界,AOP在业务类的隔离上,绝对是做到了解耦,在这里面有几个核心的概念:
切面(Aspect): 指关注点模块化,这个关注点可能会横切多个对象。事务管理是企业级Java应用中有关横切关注点的例子。 在Spring AOP中,切面可以使用通用类基于模式的方式(schemabasedapproach)或者在普通类中以@Aspect 注解(@AspectJ 注解方式)来实现。
连接点(Join point): 在程序执行过程中某个特定的点,例如某个方法调用的时间点或者处理异常的时间点。在Spring AOP中,一个连接点总是代表一个方法的执行。
通知(Advice): 在切面的某个特定的连接点上执行的动作。通知有多种类型,包括“around”,“before” and “after”等等。通知的类型将在后面的章节进行讨论。 许多AOP框架,包括Spring在内,都是以拦截器做通知模型的,并维护着一个以连接点为中心的拦截器链。
切点(Pointcut): 匹配连接点的断言。通知和切点表达式相关联,并在满足这个切点的连接点上运行(例如,当执行某个特定名称的方法时)。切点表达式如何和连接点匹配是AOP的核心:Spring默认使用AspectJ切点语义。 引入(Introduction): 声明额外的方法或者某个类型的字段。Spring允许引入新的接口(以及一个对应的实现)到任何被通知的对象上。例如,可以使用引入来使bean实现 IsModified 接口, 以便简化缓存机制(在AspectJ社区,引入也被称为内部类型声明(inter))。
目标对象(Target object): 被一个或者多个切面所通知的对象。也被称作被通知(advised)对象。既然Spring AOP是通过运行时代理实现的,那么这个对象永远是一个被代理(proxied)的对象。
AOP代理(AOP proxy):AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。
织入(Weaving): 把切面连接到其它的应用程序类型或者对象上,并创建一个被被通知的对象的过程。这个过程可以在编译时(例如使用AspectJ编译器)、类加载时或运行时中完成。 Spring和其他纯Java AOP框架一样,是在运行时完成织入的。
大白话:
任何一个系统都是由不同的组件组成的,每个组件负责一块特定的功能,当然会存在很多组件是跟业务无关的,例如日志、事务、权限等核心服务组件,这些核心服务组件经常融入到具体的业务逻辑中,如果我们为每一个具体业务逻辑操作都添加这样的代码,很明显代码冗余太多,因此我们需要将这些公共的代码逻辑抽象出来变成一个切面,然后注入到目标对象(具体业务)中去,AOP正是基于这样的一个思路实现的,通过动态代理的方式,将需要注入切面的对象进行代理,在进行调用的时候,将公共的逻辑直接添加进去,而不需要修改原有业务的逻辑代码,只需要在原来的业务逻辑基础之上做一些增强功能即可。
05. 简述如何实现一个IOC容器
06. Spring是如何简化开发的?
- 基于POJO的轻量级和最小侵入性编程
- 基于依赖注入和面向接口实现松耦合
- 基于切面和惯例进行声明式编程
- 基于切面和模板减少样板式代码
07. 简述JavaConfig
JavaConfig是Spring3.0新增的概念,就是以注解的形式取代Spring中繁琐的xml文件。
JavaConfig结合了xml的解耦和java编译时检查的优点。
@Configuration,表示这个类是配置类;
@ComponentScan,相当于xml的<context:componentScan basepackage=>;
@Bean,相当于xml的< bean id=“student” class=“com.guor.entity”>;
@EnableWebMvc,相当于xml的< mvc:annotation-driven>;
@ImportResource,相当于xml的< import resource=“application-context-cache.xml”>;
@PropertySource,用于读取properties配置文件;
@Profile,一般用于多环境配置,激活时可用@ActiveProfile(“dev”)注解;
09. 简述Spring的配置方式
1.XML配置文件
2.基于注解的方式
项目越来越大,基于xml配置太麻烦,Spring 2.x时代提供了声明bean的注解。
(1)Bean的定义
// @Component、@Controller、@Service、@Repository
(2)Bean的注入
// @Autowire
3、基于Java的方式(关键)
Spring 3.x以后,可以通过Java代码装配Bean。
1.2 Spring框架原理
01. 简述BeanFactory和ApplicationContext区别
Spring提供了两种不同的IOC容器,BeanFactory和ApplicationContext(都是接口);
1.BeanFactory是Spring的最底层接口,包含bean的定义、管理bean的加载、实例化,控制bean的生命周期,特点是每次获取对
象时才创建对象。
2.ApplicationContext是BeanFactory的子接口,拥有BeanfFactory的全部功能,并且扩展了很多高级特性,每次容器启动时就创
建所有对象。
ApplicationContext
- ApplicationContext的额外功能:
- 继承MessageSource,支持国际化;
- 统一的资源文件访问方式;
- 提供在监听器中注册bean;
- 同时加载过个配置文件;
- 载入多个(有继承关系)上下文,使得每个上下文都专注于一个特定的层次,比如应用的web层;
BeanFactory 和 ApplicationContext都支持BeanPostProcessor,BeanFactoryPostProcessor;
但BeanFactory需要手动注册,ApplicationContext则是自动注册。
02. 简述Spring Bean的生命周期
1、解析类得到BeanDefinition
2、如果有多个构造方法,则要推断构造方法
3、确定好构造方法后,进行实例化得到一个对象
4、对对象中的加了@Autowired注解的属性进行属性填充
5、回调Aware方法,比如BeanNameAware,BeanFactoryAware
6、调用BeanPostProcessor的初始化前的方法
7、调用初始化方法
8、调用BeanPostProcessor的初始化后的方法,在这里会进行AOP
9、如果当前创建的bean是单例的则会把bean放入单例池
10、使用bean
11、Spring容器关闭时调用DisposableBean中destory()方法
03. 简述Spring支持的bean作用域
① singleton
单例模式
使用该属性定义Bean时,这种bean范围是默认的,这种范围确保不管接受多少请求,每个IOC容器中只有一个bean的实例
② prototype
使用该属性定义Bean时,IOC容器可以创建多个Bean实例,为每一个bean提供一个实例;
③ request
使用该属性定义Bean时,在请求bean范围内为每一个来自客户端的网络请求创建一个实例,适用于WebApplicationContext环
境。在请求完毕后,bean会失效并被垃圾回收器回收;
④ session
为每个session创建一个实例,session过期后,bean会随之消失;
⑤ global-session
所有的Session共享一个Bean实例
global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。
如果你想要声明让所有的portlet公用全局的存储变量的话,那么全局变量需要存储在global-session中。
⑥ application
bean被定义为在ServletContext的生命周期中复用一个单例对象。
04. 简述单例Bean是否线程安全
Spring中的Bean对象默认是单例的,框架并没有对bean进行多线程的封装处理。
如果Bean是有状态的,那么就需要开发人员自己来保证线程安全的保证,最简单的办法就是改变bean的作用域把singleton改成
prototype,这样每次请求bean对象就相当于是创建新的对象来保证线程的安全。
有状态就是有数据存储的功能,无状态就是不会存储数据。
我们的controller,service和dao本身并不是线程安全的,只是调用里面的方法,而且多线程调用一个实例的方法,会在内存中复
制遍历,这是自己线程的工作内存,是最安全的。
因此在进行使用的时候,不要在bean中声明任何有状态的实例变量或者类变量,如果必须如此,也推荐大家使用ThreadLocal把
变量变成线程私有,如果bean的实例变量或者类变量需要在多个线程之间共享,那么就只能使用synchronized,lock,cas等这些
实现线程同步的方法了。
05. 简述Bean的自动装配
Spring支持IOC,自动装配不用类实例化,直接从bean容器中取。
1、配置在xml中
<bean id="employeeDAO" class="com.guor.EmployeeDAOImpl" autowire="byName" />
2、@Autowired自动装配,可以在字段、setter方法、构造函数上使用。
bean的自动装配指的是bean的属性值在进行注入的时候通过某种特定的规则和方式去容器中查找,并设置到具体的对象属性中,主要有五种方式:
no – 缺省情况下,自动配置是通过“ref”属性手动设定,在项目中最常用
byName – 根据属性名称自动装配。如果一个bean的名称和其他bean属性的名称是一样的,将会自装配它。
byType – 按数据类型自动装配,如果bean的数据类型是用其它bean属性的数据类型,兼容并自动装配它。
constructor – 在构造函数参数的byType方式。
autodetect – 如果找到默认的构造函数,使用“自动装配用构造”; 否则,使用“按类型自动装配”。
15. Spring框架中使用了哪些设计模式及应用场景
① 简单工厂模式 ⭐
简单工厂模式的本质就是一个工厂类根据传入的参数,动态的决定实例化哪个类。
Spring的BeanFactory就是简单工厂模式的体现,根据传入一个唯一标识来获得bean对象。但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。
② 工厂方法模式 ⭐
实现了FactoryBean接口的bean是一类叫做factory的bean。
其特点是,spring会在使用getBean()调用获得该bean时,会自动调用该bean的getObject()方法,所以返回的不是factory这个bean,而是这个bean.getOjbect()方法的返回值。
③ 单例模式 ⭐
保证一个类仅有一个实例,并提供一个访问它的全局访问点
spring对单例的实现: spring中的单例模式完成了后半句话,即提供了全局的访问点BeanFactory。但没有从构造器级别去控制单例,这是因为spring管理的是任意的java对象。
④ 代理模式
Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术
⑤ 装饰器模式
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
Spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator
⑥ 观察者模式
spring的事件驱动模型使用的是 观察者模式 ,Spring中Observer模式常用的地方是listener的实现。
⑦ 适配器模式
Spring定义了一个适配接口,使得每一种Controller有一种对应的适配器实现类,让适配器代替controller执行相应的方法。这样在扩展Controller时,只需要增加一个适配器类就完成了SpringMVC的扩展了
⑧ 策略模式 ⭐
加载资源文件的方式,使用了不同的方法,比如:ClassPathResourece,FileSystemResource,ServletContextResource,UrlResource但他们都有共同的借口Resource;
在Aop的实现中,采用了两种不同的方式,JDK动态代理和CGLIB代理
Spring框架的资源访问Resource接口。该接口提供了更强的资源访问能力,Spring 框架本身大量使用了Resource 接口来访问底层资源。
⑨ 动态代理
切面在应用运行的时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象创建动态的创建一个代理对象。
SpringAOP就是以这种方式织入切面的。
织入:把切面应用到目标对象并创建新的代理对象的过程。
16. 简述Spring事务的实现方式原理
在使用Spring框架的时候,可以有两种事务的实现方式,一种是编程式事务,有用户自己通过代码来控制事务的处理逻辑,还有一种是声明式事务,通过@Transactional注解来实现。
其实事务的操作本来应该是由数据库来进行控制,但是为了方便用户进行业务逻辑的操作,spring对事务功能进行了扩展实现,一般我们很少会用编程式事务,更多的是通过添加@Transactional注解来进行实现,当添加此注解之后事务的自动功能就会关闭,有spring框架来帮助进行控制。
其实事务操作是AOP的一个核心体现,当一个方法添加@Transactional注解之后,spring会基于这个类生成一个代理对象,会将这个代理对象作为bean,当使用这个代理对象的方法的时候,如果有事务处理,那么会先把事务的自动提交给关系,然后去执行具体的业务逻辑,如果执行逻辑没有出现异常,那么代理逻辑就会直接提交,如果出现任何异常情况,那么直接进行回滚操作,当然用户可以控制对哪些异常进行回滚操作。
TransactionInterceptor
17. 简述Spring事务的隔离级别
spring中的事务隔离级别就是数据库的隔离级别,有以下几种:
read uncommitted(未提交读)
read committed(提交读、不可重复读)
repeatable read(可重复读)
serializable(可串行化) 数据库的配置隔离级别是Read Commited,而Spring配置的隔离级别是Repeatable Read,请问这时隔离级别是以哪一个为准?
答:以Spring配置的为准,如果spring设置的隔离级别数据库不支持,效果取决于数据库
18. 简述Spring事务的传播机制
多个事务方法相互调用时,事务如何在这些方法之间进行传播,spring中提供了7中不同的传播特性,来保证事务的正常执行:
REQUIRED:默认的传播特性,如果当前没有事务,则新建一个事务,如果当前存在事务,则加入这个事务
SUPPORTS:当前存在事务,则加入当前事务,如果当前没有事务,则以非事务的方式执行
MANDATORY:当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常
REQUIRED_NEW:创建一个新事务,如果存在当前事务,则挂起改事务
NOT_SUPPORTED:以非事务方式执行,如果存在当前事务,则挂起当前事务
NEVER:不使用事务,如果当前事务存在,则抛出异常
NESTED:如果当前事务存在,则在嵌套事务中执行,否则REQUIRED的操作一样
NESTED和REQUIRED_NEW的区别:
REQUIRED_NEW是新建一个事务并且新开始的这个事务与原有事务无关,而NESTED则是当前存在事务时会开启一个嵌套事务,在NESTED情况下,父事务回滚时,子事务也会回滚,而REQUIRED_NEW情况下,原有事务回滚,不会影响新开启的事务NESTED和REQUIRED的区别:
REQUIRED情况下,调用方存在事务时,则被调用方和调用方使用同一个事务,那么被调用方出现异常时,由于共用一个事务,所以无论是否catch异常,事务都会回滚,而在NESTED情况下,被调用方发生异常时,调用方可以catch其异常,这样只有子事务回滚,父事务不会回滚。
19. Spring事务什么时候会失效?
spring事务的原理是AOP,进行了切面增强,那么失效的根本原因是这个AOP不起作用了!常见情况:
1、bean对象没有被spring容器管理
2、方法的访问修饰符不是public
@Transactional 只能用于 public 的方法上,否则事务不会失效,如果要用在非 public 方法上,可以开启 AspectJ 代理模式。
3、自身调用问题,类里面使用this调用本类的方法(this通常省略),此时这个this对象不是代理类,而是UserService对象本身!
解决方法很简单,让那个this变成UserService的代理类即可! 4、数据源没有配置事务管理器
5、数据库不支持事务
6、异常被捕获,事务不会回滚(或者抛出的异常没有被定义,默认为RuntimeException)
7、异常类型错误或者配置错误
2.1 MyBatis的基本概念
01. 简述ORM框架
ORM(Object-relational mapping),对象关系映射
是为了解决面向对象与关系型数据库存在的不匹配问题。
ORM框架的优点
1.开发效率高
2.数据访问更抽象、轻便
3.支持面向对象封装
02. 简述MyBatis
03. 简述mybatis的优缺点
1、Mybait的优点:
(1)简单易学,容易上手(相比于Hibernate) 基于SQL编程;
(2)JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
(3)很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持,而JDBC提供了可扩展性,所以只要这个数据库有针对Java的jar包就可以就可以与MyBatis兼容),开发人员不需要考虑数据库的差异性。
(4)提供了很多第三方插件(分页插件 / 逆向工程);
(5)能够与Spring很好的集成;
(6)MyBatis相当灵活,不会对应用程序或者数据库的现有设计强加任何影响,SQL写在XML里,从程序代码中彻底分离,解除
sql与程序代码的耦合,便于统一管理和优化,并可重用。
(7)提供XML标签,支持编写动态SQL语句。
(8)提供映射标签,支持对象与数据库的ORM字段关系映射。
(9)提供对象关系映射标签,支持对象关系组建维护。
2、MyBatis框架的缺点:
(1)SQL语句的编写工作量较大,尤其是字段多、关联表多时,更是如此,对开发人员编写SQL语句的功底有一定要求。
(2)SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
04. 简述mybatis和hibernate的区别
Hibernate的优点:
1、hibernate是全自动,hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql。
2、功能强大,数据库无关性好,O/R映射能力强,需要写的代码很少,开发速度很快。
3、有更好的二级缓存机制,可以使用第三方缓存。
4、数据库移植性良好。
5、hibernate拥有完整的日志系统,hibernate日志系统非常健全,涉及广泛,包括sql记录、关系异常、优化警告、缓存提示、脏数据警告等
Hibernate的缺点:
1、学习门槛高,精通门槛更高,程序员如何设计O/R映射,在性能和对象模型之间如何取得平衡,以及怎样用好Hibernate方面需要的经验和能力都很强才行
2、hibernate的sql很多都是自动生成的,无法直接维护sql;虽然有hql查询,但功能还是不及sql强大,见到报表等变态需求时,hql查询要虚,也就是说hql查询是有局限的;hibernate虽然也支持原生sql查询,但开发模式上却与orm不同,需要转换思维,因此使用上有些不方便。总之写sql的灵活度上hibernate不及mybatis。
Mybatis的优点:
1、易于上手和掌握,提供了数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美。
2、sql写在xml里,便于统一管理和优化, 解除sql与程序代码的耦合。
3、提供映射标签,支持对象与数据库的orm字段关系映射
4、 提供对象关系映射标签,支持对象关系组建维护
5、提供xml标签,支持编写动态sql。
6、速度相对于Hibernate的速度较快
Mybatis的缺点:
1、关联表多时,字段多的时候,sql工作量很大。
2、sql依赖于数据库,导致数据库移植性差。
3、由于xml里标签id必须唯一,导致DAO中方法不支持方法重载。
4、对象关系映射标签和字段映射标签仅仅是对映射关系的描述,具体实现仍然依赖于sql。
5、DAO层过于简单,对象组装的工作量较大。
6、不支持级联更新、级联删除。
7、Mybatis的日志除了基本记录功能外,其它功能薄弱很多。
8、编写动态sql时,不方便调试,尤其逻辑复杂时。
9、提供的写动态sql的xml标签功能简单,编写动态sql仍然受限,且可读性低。
05. mybatis中#{}和${}的区别是什么?
a、#{}是预编译处理,$ {}是字符串替换。
b、Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的 set 方法来赋值;
c、Mybatis 在处理$ {}时,就是把{}里替换成变量的值。
d、使用#{}可以有效的防止 SQL 注入,提高系统安全性
2.2 MyBatis框架原理
01. 简述一下mybatis插件运行原理
mybatis只支持针对
ParameterHandler、ResultSetHandler、StatementHandler、Executor
这四种接口的插件,mybatis使用jdk的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这四种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke方法
,拦截那些你指定需要拦截的方法。 编写插件:实现Mybatis的Interceptor接口并复写intercept方法啊,然后给插件编写注解,指定要拦截哪一个接口的哪些方法,在配置文件中配置编写的插件即可。
@Intercepts({@Signature(type = StatementHandler.class,method = "parameterize",args = Statement.class)})
02. 属性名和字段名不一致,该怎么办
第1种:通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
<select id=”selectorder” parametertype=”int”
resultetype=”me.gacl.domain.order”>
select order_id id, order_no orderno ,order_price price form orders where
order_id=#{id};
</select>
第2种:通过来映射字段名和实体类属性名的——对应的关系。
<select id="getOrder" parameterType="int" resultMap="orderresultmap">
select * from orders where order_id=#{id}
</select>
<resultMap type=”me.gacl.domain.order” id=”orderresultmap”>
<!–用id属性来映射主键字段–>
<id property=”id” column=”order_id”>
<!–用result属性来映射非主键字段,property为实体类属性名,column为数据表中的属性–>
<result property = “orderno” column =”order_no”/>
<result property=”price” column=”order_price” />
</reslutMap>
03. 简述sql执行结果封装为目标对象并返回的映射关系
第—种是使用标签,逐一定义数据库列名和对象属性名之间的映射关系。
第二种是使用sql列的别名功能,将列的别名书写为对象属性名。
有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。
04. 简述Mybatis如何分页、分页插件的原理
Mybatis使用
RowBounds
对象进行分页,它是针对Resultset
结果集执行的内存分页,而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据
dialect
方言,添加对应的物理分页语句和物理分页参数。
05. 简述如何执行批量插入
首先,创建—个简单的insert语句
<insert id=”insertname”>
insert into names (name) values (#{value})
</insert>
Java代码批次处理插入
list<string> names = new arraylist();
names.add(“fred”);
names.add(“barney”);
names.add(“betty”);
names.add(“wilma”);
// 注意这里 executortype.batch
sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch);
try {
namemapper mapper = sqlsession.getmapper(namemapper.class);
for (string name : names) {
mapper.insertname(name);
}
sqlsession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}
finally {
sqlsession.close();
}
06. 简述MyBatis实现一对一的方式
有联合查询和嵌套查询,
- 联合查询是几个表联合查询,只查询一次,通过在resultMap里面配置association节点配置一对一的类就可以完成;
- 嵌套查询是先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表的查询通过select属性配置。
07. 简述Mybatis的延迟加载以及实现原理
Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,
- association指的就是一对一,collection指的就是一对多查询。
在Mybatis配置文件中,可以配置是否启用延迟加载
lazyLoadingEnabled=true|false
。 它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,
比如调用
a.getB().getName()
,拦截器invoke()
方法发现a.getB()
是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b)
,于是a的对象b属性就有值了,接着完成a.getB( ) .getName()
方法的调用。这就是延迟加载的基本原理。 当然了,不光是Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的
08. Mybatis的一级、二级缓存
1) 一级缓存:基于
PerpetualCache
的 HashMap本地缓存,其存储作用域为Session,当Session flush或close 之后,该Session中的所有Cache就将清空,默认打开—级缓存。 2) 二级缓存与一级缓存其机制相同,默认也是采用
Perpetualcache
,HashMap存储,不同在于其存储作用域为
Napper(Namespace),并且可自定义存储源,如Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置; 3) 对于缓存数据更新机制,当某一个作用域(一级缓存Sessionl二级缓存Namespaces)的进行了CIU/D操作后,默认该作用域下所有select 中的缓存将被clear掉并重新更新,如果开启了二级缓存,则只根据配置判断是否刷新
3.1 SpringMVC
01. 简述springmvc工作流程
02. 简述springmvc的九大组件有哪些?
1.HandlerMapping
根据request找到相应的处理器。因为Handler(Controller)有两种形式,一种是基于类的Handler,
另一种是基于Method的Handler(也就是我们常用的)2.HandlerAdapter
调用Handler的适配器。如果把Handler(Controller)当做工具的话,那么HandlerAdapter就相当于干活的工人
3.HandlerExceptionResolver
对异常的处理
4.ViewResolver
用来将String类型的视图名和Locale解析为View类型的视图
5.RequestToViewNameTranslator
有的Handler(Controller)处理完后没有设置返回类型,比如是void方法,这是就需要从request中获取viewName
6.LocaleResolver
从request中解析出Locale。Locale表示一个区域,比如zh-cn,对不同的区域的用户,显示不同的结果,这就是i18n(SpringMVC中有具体的拦截器LocaleChangeInterceptor)
7.ThemeResolver
主题解析,这种类似于我们手机更换主题,不同的UI,css等
8.MultipartResolver
处理上传请求,将普通的request封装成MultipartHttpServletRequest
9.FlashMapManager
用于管理FlashMap,FlashMap用于在redirect重定向中传递参数