MyBatis常见面试题和答案

MyBatis是什么?

MyBatis 是一款持久层框架,一个半 ORM(对象关系映射)框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎全部的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。java

ORM是什么

ORM(Object Relational Mapping),对象关系映射,是一种为了解决关系型数据库数据与简单Java对象(POJO)的映射关系的技术。简单的说,ORM是经过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系型数据库中。spring

**为何说Mybatis是半自动ORM映射工具?**它与全自动的区别在哪里?

Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,能够根据对象关系模型直接获取,因此它是全自动的。sql

而Mybatis在查询关联对象或关联集合对象时,须要手动编写sql来完成,因此,称之为半自动ORM映射工具。数据库

JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?

一、数据库连接建立、释放频繁形成系统资源浪费从而影响系统性能,若是使用数据库链接池可解决此问题。编程

解决:在mybatis-config.xml中配置数据连接池,使用链接池管理数据库链接。缓存

二、Sql语句写在代码中形成代码不易维护,实际应用sql变化的可能较大,sql变更须要改变java代码。安全

解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。session

三、向sql语句传参数麻烦,由于sql语句的where条件不必定,可能多也可能少,占位符须要和参数一一对应。mybatis

解决:Mybatis自动将java对象映射至sql语句。架构

四、对结果集解析麻烦,sql变化致使解析代码变化,且解析前须要遍历,若是能将数据库记录封装成pojo对象解析比较方便。

解决:Mybatis自动将sql执行结果映射至java对象。

Mybatis优缺点

优势:

  • 基于SQL语句编程,至关灵活,不会对应用程序或者数据库的现有设计形成任何影响,SQL写在XML里,解耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,可重用

  • 与JDBC相比,减小了50%以上的代码量,消除了JDBC大量冗余的代码,不须要手动开关链接

  • 很好的与各类数据库兼容(由于MyBatis使用JDBC来链接数据库,因此只要JDBC支持的数据库MyBatis都支持)

  • 提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护

  • 可以与Spring很好的集成

缺点:

  • SQL语句的编写工做量较大,尤为当字段多、关联表多时,对开发人员编写SQL语句的功底有必定要求

  • SQL语句依赖于数据库,致使数据库移植性差,不能随意更换数据库

MyBatis框架适用场景

MyBatis专一于SQL自己,对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis将是不错的选择。

Hibernate 和 MyBatis 的区别

相同点:

  • 都是对jdbc的封装,都是持久层的框架,都用于Dao层的开发。

不一样点:

  • MyBatis 是一个半自动映射的框架,配置Java对象与sql语句执行结果的对应关系,多表关联关系配置简单Hibernate 是一个全表映射的框架,配置Java对象与数据库表的对应关系,多表关联关系配置复杂

  • Hibernate 对SQL语句封装,提供了日志、缓存、级联等特性,但会多消耗性能。代码开发量少,但SQL语句优化困难。

  • MyBatis 须要手动编写 SQL,支持动态 SQL、处理列表、动态生成表名、支持存储过程。开发工做量相对大些。直接使用SQL语句操做数据库,不支持数据库无关性,但sql语句优化容易。

  • Hibernate 是重量级框架,学习使用门槛高,适合于需求相对稳定,中小型的项目,好比:办公自动化系统MyBatis 是轻量级框架,学习使用门槛低,适合于需求变化频繁,大型的项目,好比:互联网电子商务系统

总结

MyBatis 是一个小巧、方便、高效、简单、直接、半自动化的持久层框架,

Hibernate 是一个强大、方便、高效、复杂、间接、全自动化的持久层框架。

MyBatis编程步骤是什么样的?

一、 建立SqlSessionFactory

二、 经过SqlSessionFactory建立SqlSession

三、 经过sqlsession执行数据库操做

四、 调用session.commit()提交事务

五、 调用session.close()关闭会话

请说说MyBatis的工做原理

1)读取 MyBatis 配置文件

2)加载映射文件。

3)构造会话工厂

4)建立会话对象

5)Executor 执行器操做数据库

6)MappedStatement 对象存储要映射的 SQL 语句的 id、参数

7)输入参数映射

8)输出结果映射

MyBatis的功能架构是怎样的

img

咱们把Mybatis的功能架构分为三层:

API接口层:提供给外部使用的接口API,开发人员经过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操做。

基础支撑层:负责最基础的功能支撑,包括链接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来做为最基础的组件。为上层的数据处理层提供最基础的支撑。

**Mybatis都有哪些Executor执行器?**它们之间的区别是什么?

Mybatis有三种基本的Executor执行器,SimpleExecutor、ReuseExecutor、BatchExecutor。

SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完马上关闭Statement对象。

ReuseExecutor:执行update或select,以sql做为key查找Statement对象,存在就使用,不存在就建立,用完后,不关闭Statement对象,而是放置于Map<String, Statement>内,供下一次使用。简言之,就是重复使用Statement对象。

BatchExecutor:执行update(没有select,JDBC批处理不支持select),将全部sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每一个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。

做用范围:Executor的这些特色,都严格限制在SqlSession生命周期范围内。

Mybatis中如何指定使用哪种Executor执行器?

在Mybatis配置文件中,在设置(settings)能够指定默认的ExecutorType执行器类型,也能够手动给DefaultSqlSessionFactory的建立SqlSession的方法传递ExecutorType类型参数,如SqlSession openSession(ExecutorType execType)。

配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements);BATCH 执行器将重用语句并执行批量更新。

**Mybatis是否支持延迟加载?**若是支持,它的实现原理是什么?

Mybatis仅支持association关联对象和collection关联集合对象的延迟加载。

association指的就是一对一,collection指的就是一对多查询。

在Mybatis配置文件中,能够配置是否启用延迟加载lazyLoadingEnabled=true|false。

#{}和${}的区别

  • #{}是占位符,预编译处理

  • ${}是拼接符,字符串替换,没有预编译处理。

  • Mybatis在处理#{}时,#{}传入参数是以字符串传入,会将SQL中的#{}替换为?号,调用PreparedStatement的set方法来赋值。Mybatis在处理时,是原值传入,就是把{}时,是原值传入,就是把时,是原值传入,就是把{}替换成变量的值,至关于JDBC中的Statement编译

  • 变量替换后,#{} 对应的变量自动加上单引号 ‘’;${} 对应的变量不会加上单引号 ‘’

  • #{} 能够有效的防止SQL注入,提升系统安全性;${} 不能防止SQL 注入

Mapper 编写有哪几种方式?

第一种:接口实现类继承 SqlSessionDaoSupport:使用此种方法须要编写mapper 接口,mapper 接口实现类、mapper.xml 文件。

(1)在 sqlMapConfig.xml 中配置 mapper.xml 的位置

(2)定义 mapper 接口

(3)实现类集成 SqlSessionDaoSupport

mapper 方法中能够 this.getSqlSession()进行数据增删改查。

(4)spring 配置

**什么是MyBatis的接口绑定?**有哪些实现方式?

接口绑定,就是在MyBatis中任意定义接口,而后把接口里面的方法和SQL语句绑定,咱们直接调用接口方法就能够,这样比起原来了SqlSession提供的方法咱们能够有更加灵活的选择和设置。

接口绑定有两种实现方式

经过注解绑定,就是在接口的方法上面加上 @Select、@Update等注解,里面包含Sql语句来绑定;

经过xml里面写SQL来绑定, 在这种状况下,要指定xml映射文件里面的namespace必须为接口的全路径名。当Sql语句比较简单时候,用注解绑定, 当SQL语句比较复杂时候,用xml绑定,通常用xml绑定的比较多。

使用MyBatis的mapper接口调用时有哪些要求?

一、Mapper接口方法名和mapper.xml中定义的每一个sql的id相同。

二、Mapper接口方法的输入参数类型和mapper.xml中定义的每一个sql 的parameterType的类型相同。

三、Mapper接口方法的输出参数类型和mapper.xml中定义的每一个sql的resultType的类型相同。

四、Mapper.xml文件中的namespace便是mapper接口的类路径。

**最佳实践中,一般一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工做原理是什么?**Dao接口里的方法,参数不一样时,方法能重载吗

Dao接口,就是人们常说的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串做为key值,可惟必定位一个MappedStatement,

举例:com.mybatis3.mappers.StudentDao.findStudentById,

能够惟一找到namespace为com.mybatis3.mappers.StudentDao

下面id = findStudentById的MappedStatement。

在Mybatis中,每个<select>、<insert>、<update>、<delete>标签,都会被解析为一个MappedStatement对象。

Dao接口里的方法,是不能重载的,由于是全限名+方法名的保存和寻找策略。

Dao接口的工做原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所表明的sql,而后将sql执行结果返回。

**Mybatis动态sql是作什么的?**都有哪些动态sql?能简述一下动态sql的执行原理不?

Mybatis动态sql可让咱们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能,Mybatis提供了9种动态sql标签trim|where|set|foreach|if|choose|when|otherwise|bind。

其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。

**Mybatis是如何进行分页的?**分页插件的原理是什么?

Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,能够在sql内直接书写带有物理分页的参数来完成物理分页功能,也可使用分页插件来完成物理分页。

分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,而后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

举例:select * from student,拦截sql后重写为:select t.* from (select * from student) t limit 0, 10

简述Mybatis的插件运行原理,以及如何编写一个插件。

Mybatis仅能够编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件,Mybatis使用JDK的动态代理,为须要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,固然,只会拦截那些你指定须要拦截的方法。

实现Mybatis的Interceptor接口并复写intercept()方法,而后在给插件编写注解,指定要拦截哪个接口的哪些方法便可,记住,别忘了在配置文件中配置你编写的插件。

缓存Mybatis的一级、二级缓存

1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储做用域为 Session,当 Session flush 或 close 以后,该 Session 中的全部 Cache 就将清空,默认打开一级缓存。

2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不一样在于其存储做用域为 Mapper(Namespace),而且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类须要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/> ;

3)对于缓存数据更新机制,当某一个做用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操做后,默认该做用域下全部 select 中的缓存将被 clear。

相关文章
相关标签/搜索