JAVA开发工程师SpringMVC面试题


SSM

Mybatis

一、MyBatis是什么?

MyBatis 是一个半自动ORM 框架,其本质是对 JDBC 的封装。使用 MyBatis重点需要程序员编写 SQL 命令,不需要写一行 JDBC 代码。

二、JDBC 的缺点?

需要手动的完成面向对象的 Java 语言、面向关系数据库之间数据的转换,代码繁琐无技术含量,影响了开发效率。

三、什么是ORM?

ORM,Object-Relationl Mapping,对象关系映射,它的作用是在关系型数据库和对象之间作一个映射处理。

四、MyBatis与 Hibernate 的比较?

Hibernate 是一个全自动的 ORM 框架。因为 Hibernate 创建了 Java 对象和数据库表之间的完整映射,可以完全以面向对象的思想来操作数据库,程序员不需要手写 SQL 语句, 而 MyBatis 中还需要手写 SQL 语句,所以是半自动化的,工作量要大于 Hibernate。但是也正是由于自定义SQL 语句,所以其灵活性、可优化性就超过了 Hibernate。

五、MyBatis核心API?

1、SqlSessionFactoryBuilder
SqlSessionFactoryBuilder 的作用是使用构建者模式创建 SqlSessionFactory 接口对象。
2、SqlSessionFactory
SqlSessionFactory 可以被认为是一个数据库连接池,它的作用是创建 SqlSession 接口对象。
3、SqlSession
如果说 SqlSessionFactory 相当于数据库连接池,那么 SqlSession 就相当于一个数据库连接(Connection 对象),你可以在一个事务里面执行多条 SQL,然后通过它的commit、rollback 方法提交或者回滚事务。
4、Mapper
映射器。由一个 Java 接口和 XML 文件(或者注解)构成,需要给出对应的 SQL 和映射规则,负责发送 SQL 去执行并返回结果。

六、#{ } 和 ${ }的区别

#{ } 解析为一个 JDBC 预编译语句(PreparedStatement)的参数标记符占位符 ?。使用该方式可避免 SQL 注入。
$ { } 仅仅为一个纯粹的 String 替换,在 Mybatis 的动态 SQL 解析阶段将会进行变量替换。$ { } 在预编译之前已经被变量替换了,这会存在 SQL 注入问题。

七、当实体类中的属性名和表中的字段名不一样 ,怎么办 ??

1、 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
2、通过来映射字段名和实体类属性名的一一对应关系。

八、 模糊查询like语句该怎么写?

1、在Java代码中添加sql通配符。like #{}
2、在sql语句中拼接通配符,会引起sql注入 like “%”${}"%"

九、基于Mybatis 的Dao 层设计?

在 Mybatis 中对于 Dao 层的设计提供了两种方式:
1、Dao 层不使用Mapper 动态代理
所谓不使用动态代理是指在 Dao 层需要我们自己来创建 Dao 层的接口与接口实现类。在接口实现类的方法中我们自己通过调用 SqlSession 对象的方法完成数据库的操作。
目前我们的入门案例就是通过这种方式完成了对 users 表的 CRUD 操作。
Dao 层不使用 Mapper 动态代理缺点:
1.在 SqlSession 对象的常用方法中只能向 SQL 语句中传递一个参数。如果要多个参数, 需要封装到 POJO 或者 Map 中。
2.调用 SqlSession 对象的方法时会有硬编码现象 namespace + id。
2、Dao 层使用Mapper 动态代理
在 MyBatis 中提供了另外一种 Dao 层的实现方式,既:Mapper 动态代理(或称为接口绑定)的操作方式。这种方式下程序员只需要写 Dao 接口,不需要创建 Dao 的接口实现类, Mybatis 会自动生成接口实现类的代理对象。在 Dao 层我们只要创建接口与映射配置文件即可。这种方式可以大大简化 Dao 层的代码结构,是在开发中最常见的使用方式。

十、Mapper 动态代理规范?

1、接口名称需要与映射配置文件名称相同
2、映射配置文件中 namespace 必须是接口的全名。
3、接口中的方法名和映射配置文件中的标签的 id 一致。
4、接口中的返回值类型和映射配置文件中的 resultType 的指定的类型一致。

十一、Mapper 动态代理模式下的多参数处理?

1、顺序传参法
在映射文件中,SQL 语句中的参数需要使用 arg0,arg1…或者 param1,param2…表示参数的顺序。此方法可读性低,且要求参数的顺序不能出错,在开发中不建议使用
2、@Param 注解传参法
在接口方法的参数列表中通过@Param 注解来定义参数名称,在 SQL 语句中通过注解中所定义的参数名称完成参数位置的指定。
此方式在参数不多的情况还是比较直观的,推荐使用。
3、POJO 传参法
在 Mapper 动态代理中也可以使用 POJO 作为传递参数的载体,在 SQL 语句中绑定参数时使用 POJO 的属性名作为参数名即可。此方式推荐使用。
4、Map 传参法
在 Mapper 动态代理中也可以使用 Map 作为传递参数的载体,在 SQL 语句中绑定参数时使用 Map 的 Key 作为参数名即可。此方法适合在传递多参数时,如果没有 POJO 能与参数匹配,可以使用该方式传递参数。推荐使用。
MyBatis 传递 map 参数时,如果传递参数中没有对应的 key 值,在执行 sql 语句时默认取的是 null。

十二、Mybatis 的分页查询?

1、使用RowBounds
RowBounds 是 Mybatis 提供的一个专门处理分页的对象。在 RowBounds 对象中有两个成员变量:
offset:偏移量,从 0 开始计数
limit:限制条数
使用 RowBounds 进行分页,非常方便,不需要在 SQL 语句中写 limit,即可完成分页功能。但是由于它是在 SQL 查询出所有结果的基础上截取数据的,所以在数据量大的 SQL 中并不适用,它更适合在返回数据结果较少的查询中使用。
2、使用SQL 语句分页
在分页查询时,如果返回的结果较多,那么需要使用特定的 SQL 语句来实现分页处理。在 MySQL 数据库中我们可以使用 limit 实现分页。

十三、主键值回填?

在数据库中插入数据时,有时我们是需要获取新数据的主键值。在 Mybatis 中支持主键值回填,可以让我们更够更方便的获取新添加数据的主键值。
Mybatis 中支持两种方法获取主键:
获取自增主键的值。如:MySQL、SqlServer 获取非自增主键的值。如 Oracle
1、获取自增主键值
自动生成的键值在 insert 方法执行完后可以被设置到传入的参数对象中。
2、获取非自增主键值
在MySQL 数据库中获取插入数据的主键的值: SELECT LAST_INSERT_ID(),SELECT @@Identity 是 SELECT LAST_INSERT_ID() 的同义词。作用是相同的。

十四、动态SQL以及标签?

在 MyBatis 中提供了动态 SQL 功能。将使用 Java 代码拼接 SQL 语句,改变为在 XML 映射文件中使用标签拼接 SQL 语句。
MyBatis 中动态 SQL 是编写在 mapper.xml 中的,其语法和 JSTL 类似,但是却是基于强大的 OGNL 表达式实现的。
标签:if、choose、when、otherwise、where、bind、set、foreach

十五、Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式??

第一种是使用resultMap标签,逐一定义数据库列名和对象属性名之间的映射关系。
第二种是使用sql列的别名功能,将列的别名书写为对象属性名。
有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

十六、Mybatis 缓存?

缓存是一般的 ORM 框架都会提供的功能,目的就是提升查询的效率和减少数据库的压力,缓存的重要性是不言而喻的。Mybatis 会将相同查询条件的 SQL 语句的查询结果存储在内存或者某种缓存介质当中,当下次遇到相同的查询 SQL 时候不在执行该 SQL,而是直接从缓存中获取结果,减少服务器的压力,尤其是在查询越多、缓存命中率越高的情况下,使用缓存对性能的提高更明显。
MyBatis 缓存方式分为一级缓存和二级缓存,同时也可配置关于缓存设置。
一级缓存是将结果缓存在 SqlSession 对象中,二级缓存是存储在 SqlSessionFactory 对象中。默认情况下,MyBatis 开启一级缓存,没有开启二级缓存。
当数据量大的时候可以借助一些第三方缓存技术来协助保存 Mybatis 的二级缓存数据。

十七、关联查询

一对一的关联查询association标签
一对多的关联查询collection标签
多对多的关联查询collection标签

十八、 查询的加载方式

1、立即加载
在一次查询中执行所有的 SQL 语句。
2、延迟加载
在一次查询中执行部分 SQL 语句,根据操作映射的关联对象触发其他查询。
1.在association、collection标签中通过 fetchType 属性开启延迟加载,仅针对当前标签生效。fectType:lazy 开启延迟加载,fectType:eager 开启立即加载。通过 select 属性指定需要执行的查询的 ID。通过 column 属性指定将封装查询结果对象的哪个属性的值作为下一个查询的查询条件。
2.在全局配置文件中的< settings>标签中开启延迟加载,所有的 association 和 collection 元素都生效。< setting name=“lazyLoadingEnabled” value=“true”/>
3。配置触发加载方法lazyLoadTriggerMethods:指定实体对象的哪个方法触发一次加载。

Spring

一、IOC思想

IOC (Inversion of Control) 是指在程序开发中,对象实例的创建不再由调用者管理,而是 由 Spring 容器创建。Spring 容器会负责控制程序之间的关系,而不是由程序代码直接控制, 因此,控制权由程序代码转移到了 Spring 容器中,控制权发生了反转,这就是 Spring 的IOC思想。

二、IOC 容器概念

IOC 容器就是具有依赖注入功能的容器,IOC 容器负责实例化、定位、配置应用程序中 的对象及建立这些对象间的依赖。应用程序无需直接在代码中 new 相关的对象,应用程序 由 IOC 容器进行组装。在 Spring 中 BeanFactory 是 IOC 容器的实际代表者。

三、Spring IOC 容器创建 Bean 对象的三种方式

1、通过构造方法创建 Bean 对象
2、通过静态工厂方法创建对象
3、通过动态工厂方法创建对象

四、Bean 对象的作用域

作用域:作用域限定了 Spring Bean 的作用范围,在 Spring 配置文件定义 Bean 时,通过 声明 scope 配置项,可以灵活定义 Bean 的作用范围。 scope 属性的值: singleton 和 prototype
singleton(单例) singleton 为 scope 属性的默认值。当 scope 属性的值为 singleton 时,Spring IOC 容器启动时会立即实例化一次 Bean 对象,并一直被 Spring IOC 容器所缓存,所以生命周期较长。
singleton 特点: 1、 Spring IOC 容器启动时会创建 Bean 对象
2、 每次调用 getBean 都返回 spring 容器中的唯一一个对象

prototype(多例) 当 scope 属性的值为 prototype 时,每次调用调用 getBean 方法时都会返回一个新的 Bean 对象,Spring IOC 容器并不会缓存该对象,所以就不再负责管理它的生命周期。
prototype 特点: 1、Spring IOC 容器启动时不会创建 Bean 对象。
2、 每次调用 getBean 都会创建一个新 Bean 对象。

五、DI 依赖注入

DI (Dependency Injection):依赖注入是指在 Spring IOC 容器创建对象的过程中,将所 依赖的对象通过配置进行注入。我们可以通过依赖注入的方式来降低对象间的耦合度。 在软件工程中,对象之间的耦合度就是对象之间的依赖性。对象之间的耦合越高,维护 成本越高,因此对象的设计应使对象之间的耦合越小越好。

六、依赖注入的方式

1、通过 Set 方法注入
2、通过构造方法注入
3、自动注入autowire

七、SqlSessionFactoryBean

SqlSessionFactoryBean 是初始化 Mybatis 框架的 Bean 对象。它是生产 SqlSessionFactory 的一种工厂 Bean。在 Spring 整合 Mybatis 中,我们可以不需要 Mybatis 的配置文件,在该 Bean 对象中可以完成对 Mybatis 框架的配置。 如果需要在 Mybatis 的配置文件中配置 Mybatis 框架时,仍然可以使用 Mybatis 的配置文件,但是需要在 SqlSessionFactoryBean 对象 的 configLocation 属性中指定 Mybatis 的配置文件的路径和名称。

八、什么是 AOP

AOP 的全称是 Aspect Oriented Programming,即面向切面编程,它将业务逻辑的各个部 分进行隔离,使开发人员在编写业务逻辑时可以专心于核心业务,从而提高了开发效率。 AOP 采取横向抽取机制,取代了传统纵向继承体系的重复性代码,其应用主要体现在 事务处理、日志管理、权限控制、异常处理等方面。 目前最流行的 AOP 技术有两个,分别为 Spring 框架的 AOP 和 AspectJ 框架。

九、AOP 术语

名称说明
Joinpoint(连接点)指那些被拦截到的点。是指应用在执行过程中能够插入切面的一个点
Pointcut(切入点)指要对哪些 Joinpoint 进行拦截,即被拦截的连接点
Advice(通知)指拦截到 Joinpoint 之后要做的事情,即对切入点增强的内容
Target(目标)指代理的目标对象
Weaving(织入)指把增强代码应用到目标上,生成代理对象的过程
Proxy(代理)指生成的代理对象
Aspect(切面)切入点和通知的结合

十、SpringAOP 模块中的通知类型

名称说明
org.springframework.aop.MethodBeforeAdvice(前置通知)在调用目标方法之前自动执行的通知称为前置通 知,可以应用于权限管理等功能。
org.springframework.aop.AfterReturningAdvice(后置通知)在调用目标方法之后自动执行的通知称为后置通 知,可以应用于关闭流、上传文件、删除临时文件等功 能。
org.aopalliance.intercept.MethodInterceptor(环绕通知)在调用目标方法前后自动执行的通知称为环绕通 知,可以应用于日志、事务管理等功能。
org.springframework.aop.ThrowsAdvice(异常通知)在方法抛出异常时自动执行的通知称为异常通知, 可以应用于处理异常记录日志等功能。

十一、AspectJ 框架常用注解

注解名称注解说明
@Before前置通知
@AfterReturning后置通知
@Around环绕通知
@After最终通知

十二、 Spring 事务管理简介

在 Spring 框架中事务管理有两种方式:一种是传统的编程式事务管理,即通过编写代 码实现的事务管理;另一种是基于 AOP 技术实现的声明式事务管理。由于在 Spring 框架中, 编程式事务管理很少使用,所以我们只对 Spring 的声明式事务管理进行详细讲解。 Spring 的声明式事务管理在底层采用了 AOP 技术,其最大的优点在于无须通过编程的 方式管理事务,只需要在配置文件中进行相关的规则声明,就可以将事务规则应用到业务逻 辑中。

十三、什么是事务

事务是作为一个逻辑单元执行的一系列操作。一个事务工作单元必须有四个特性:原子 性、一致性、隔离性、持久性。只有这样才能成为一个事务。

十四、事务的 ACID 特性

原子性(Atomicity):事务中的所有操作作为一个整体像原子一样不可分割,要么全部成功, 要么全部失败。
一致性(Consistency):事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执 行之前和执行之后,数据库都必须处于一致性状态。如果数据库系统在运行过程中发生故障,有些事务尚未完成就被迫中断,这些未完成的事务对数据库所作的修改有一部分已写入物理 数据库,这时数据库就处于一种不正确的状态,也就是不一致的状态 。
隔离性(Isolation):并发执行的事务不会相互影响,其对数据库的影响和它们串行执行时 一样。比如多个用户同时往一个账户转账,最后账户的结果应该和他们按先后次序转账的结 果一样。
持久性(Durability):事务一旦提交,其对数据库的更新就是持久的。任何事务或系统故障 都不会导致数据丢失。

十五、事务的隔离性

1、脏读:脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。

时间转账事务A转账事务 B
T1开始事务
T2开始事务
T3查询账户余额为 1000 元
T4取出 500 元,把余额改为 500 元
T5查询账户余额为 500 元(脏读)
T6撤销事务,余额恢复 1000 元
T7汇入 100 元,把余额改为 600 元
T8提交事务

2、不可重复读:是指 A 事务读取到了 B 事务已经提交的更改数据,在同个时间段内, 两次查询的结果不一致。

时间转账事务A转账事务 B
T1开始事务
T2开始事务
T3查询账户余额为 1000 元
T4查询账户余额为 1000 元
T5取出 100 元,把余额改为 900
T6提交事务
T7查询账户余额为 900 元(和 T4 读取不一致)

3、幻读(虚读):A 事务读取到 B 事务提交的新增数据,幻象读一般发生在数据统计 事务中。

时间转账事务A转账事务 B
T1开始事务
T2开始事务
T3统计总存款数为 10000
T4新增一个存款账户,存款为 100 元
T5提交事务
T6再次统计总存款数为 10100(幻读)

十六、解决办法(四种隔离级别)

1、Read Uncommited(读取未提交内容)
读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。但是,读未提 交产生了脏读,采用 Read Commited 可以解决脏读问题
2、Read Commited(读取提交内容)
读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。读提交,若有 事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能 读取数据,可以解决脏读问题。但是,读提交两次查询会产生不同的查询结果,就会造成不 可重复读问题,采用 Repeatable Read 可以解决此问题。
3、Repeatable Read(重复读)
重复读,就是在开始读取数据(事务开启)时,不再允许修改操作。重复读可以解决不 可重复读问题。应该明白的一点就是,不可重复读对应的是修改,即 UPDATE 操作。但是可 能还会有幻读问题。因为幻读问题对应的是插入 INSERT 操作,而不是 UPDATE 操作。采用 Serializable 可以解决幻读问题
4、Serializable(可串行化)
Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏 读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
注:
1、大多数数据库默认的事务隔离级别是 Read committed,比如 Sql Server , Oracle。
2、Mysql 的默认隔离级别是 Repeatable read。
3、 隔离级别的设置只对当前链接有效。对于使用 MySQL 命令窗口而言,一个窗口就 相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于 JDBC 操作数据库来说,一个 Connection 对象相当于一个链接,而对于Connection 对象 设置的隔离级别只对该 Connection 对象有效,与其他链接 Connection对象无关。

十七、事务的传播行为

描述
REQUIRED支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行。
MANDATORY支持当前事务,如果当前没有事务,就抛出异常。
REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起。
NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
NEVER以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED必须在事务状态下执行.如果没有事务,新建事务,如果当前有事务,创建一个嵌套事务

十八、MVC 架构模式简介

MVC 是 Model、View 和 Controller 的缩写,分别代表 Web 应用程序中的 3 种职责。
模型:用于存储数据以及处理用户请求的业务逻辑。
视图:向控制器提交数据,显示模型中的数据。
控制器:根据视图提出的请求判断将请求和数据交给哪个模型处理,将处理后的有 关结果交给哪个视图更新显示。

十九、什么是 SpringMVC

SpringMVC是一个基于MVC模式的Web框架,是Spring框架的一个模块 。它以SpringIOC3容器为基础,并利用容器的特性来简化它的配置,所以 SpringMVC 和 Spring 可直接整合使 用。SpringMVC 对 MVC 流程进行了封装,屏蔽掉很多底层代码,让开发者可以更加轻松快 捷的完成基于 MVC 模式的 Web 开发。

二十、Spring MVC 的工作流程

1、客户端请求提交到 DispatcherServlet。
2、 由 DispatcherServlet 控制器通过 HandlerMapping,找到处理请求的 Controller。
3、DispatcherServlet 将请求提交到 Controller。
4、Controller 调用业务逻辑处理后返回 ModelAndView。
5、DispatcherServlet 通过 ViewResolver 视图解析器,找到 ModelAndView 指定的视 图。
6、视图负责渲染并将结果显示到客户端。

二十一、SpringMVC 作用域传值

对象名称作用范围
application整个应用都有效
session在当前会话中有效
request在当前请求中有效
page在当前页面有效

二十二、重定向和转发的区别

区别转发forward()重定向redirect()
根目录包含项目访问地址没有项目访问地址
地址栏不变
请求次数12
跳转服务器端跳转客户端进行
请求域中数据不会丢失会丢失

二十三、拦截器和过滤器的区别

1、拦截器 SpringMVC 组件,而过滤器是 Servlet 组件。
2、 拦截器不依赖容器,过滤器依赖容器。
3、 拦截器只能对控制器请求起作用,而过滤器则可以对所有的请求起作用。
4、 拦截器可以获取 IOC 容器中的各个 bean,而过滤器就不太方便。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值