共计 5049 个字符,预计需要花费 13 分钟才能阅读完成。
今日分享开始啦,请大家多多指教~
MyBatis 面试题总结
前言:
明天给大家分享的是面试中会遇到的几点问题,心愿这次分享能够让大家面试更加顺利!
1.#{}与 ${}的区别?
2.Xml 映射文件中,除了常见的 select/Inserct/update/delete 标签之外,还有那些标签?
3. 最佳实际中,通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?Dao 接口里的办法,参数不同时,办法能重载吗?
4.Mybatis 是如何进行分页的?分页插件的原理是什么?
5.Mybatis 动静 sql 是做什么?都有哪些动静 sql? 能简述一下动静 sql 的执行原理不?
6.Mybatis 是如何将 sql 执行后果封装为指标对象并返回的?都有那些映射模式?
7.Mybatis 能执行一对一、一对多的关联查问吗?都有那些实现形式,以及他们之间的区别?
8.Mybatis 是否反对提早加载?如果反对,它的实现原理是什么?
9.Mybatis 的 XML 映射文件中,不同的 XML 映射文件,id 是否能够反复?
10.Mybatis 都有哪些 Executor 执行器?他们之间的区别是什么?
11.Mybatis 中如何制订应用哪一种 Executor 执行器?
12.Mybatis 是否能够映射 Enum 枚举类?
13.Mybatis 映射文件中,如果 A 标签通过 include 援用了 B 标签的内容,请问 B 标签的内容是否定义在 A 标签之后,还是必须定义为 A 之前?
14.Mybatis 与 Spring dataJpa 的区别?
话不多说,注释开始啦~
1.#{}与 ${}的区别
#{}:是 sql 的参数占位符,Mybatis 会将 sql 中的 #{}替换为?,按序给 sql 的? 占位符设置参数值。
这个是依据参数变动不是动静 sql(是有 if 语句之类的 sql)
${}: 是在数据库配置文件中的变量占位符,属于动态文本替换,比方 ${Driver}会被动态替换为 com.mysql.jdbc.Driver。
2.Xml 映射文件中,除了常见的 select/Inserct/update/delete 标签之外,还有那些标签?
还有 <resultMap>,<parameterMap>,<sql>,<include>,<selectKey>, 加上动静 sql 的 9 个标签等。<include> 是能够引入其余 sql 片段,<selectKey> 为不反对自增的主键生成策略标签。
3. 最佳实际中,通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?Dao 接口里的办法,参数不同时,办法能重载吗?
Dao 接口,就是人们常说的 Mapper 接口,接口的全限名,就是映射文件中的 namespace 的值,接口的办法名,就是映射文件中 MappedStatement 的 id 值,接口办法内的参数,就是传递给 sql 的参数。Mapper 接口是没有实现类的,当调用接口办法时,接口全限名 + 办法名拼接字符串作为 key 值,可惟一定位一个 MappedStatement。
Dao 接口里的办法,是不能重载的,因为是全限名 + 办法名的保留和寻找策略。
Dao 接口的工作原理是 JDK 动静代理,MyBatis 运行时会应用 JDK 动静代理为 Dao 接口生成代理 proxy 独享,代理对象 proxy 会拦挡接口办法,转而执行 MappedStatement 所代表的 sql,而后将 sql 执行后果返回。
4.Mybatis 是如何进行分页的?分页插件的原理是什么?
1.Mybatis 应用 RowBounds 对象进行分页,它是针对 ResultSet 后果集执行的内存拆散,而非物理分页;
RowBounds 分页(不应用 SQL),不再应用 SQL 实现分页
接口
List <User> getUserByRowBound();
mapper.xml
测试
2. 间接在 sql 内间接书写 limit 进行分页;
应用 Limit 分页
Select * from user limit 2;#[0,n]
【0,2】进去的时候第一个和第二个。所以 0 代表的第一个。
3. 应用分页插件来实现物理分页。
5.Mybatis 动静 sql 是做什么?都有哪些动静 sql? 能简述一下动静 sql 的执行原理不?
Mybatis 动静 sql 能够让咱们在 xml 映射文件内,以标签的模式编写动静 sql,实现逻辑判断和动静拼接 sql 的性能,Mybatis 提供了 9 种动静 sql 标签
其执行原理为,应用 OGNL 从 sql 参数对象中计算表达式的值,依据表达式的值动静拼接 sql,以此来实现动静 sql 的性能。
6.Mybatis 是如何将 sql 执行后果封装为指标对象并返回的?都有那些映射模式?
第一种是用 <resultMap> 标签,逐个定义列明和对象属性名之间的映射关系。
第二种是应用 sql 列的别名性能,将列名书写为对象属性名。
有了列名和属性名的映射关系后,Mybatis 通过反射创建对象,同时应用反射给对象的属性逐个赋值并返回,那些找不到映射关系的属性,是无奈实现赋值的。
7.Mybatis 能执行一对一、一对多的关联查问吗?都有那些实现形式,以及他们之间的区别?
Mybatis 不仅能够执行一对一、一对多的关联查问,还能够执行多对一,多对多的关联查问,多对一查问,其实就是一对一查问,只须要把 selectOne()批改为 selectList()即可;多对多查问,其实就是一对多查问,只须要把 selectOne()批改为 selectList()即可。
关联对象查问,有两种形式:
一种是独自发送一个 sql 去查问关联对象 resultMap,赋给主对象,而后返回主对象;
依照查问嵌套解决(子查问)
另一种是应用嵌套查问,嵌套查问的含意为应用 join 查问,一部分列是 A 对象的属性值,另外一部分是关联对象 B 的属性值,益处是只发一个 sql 查问,就能够把主对象和其关联对象查出来。
依照查问嵌套解决(联表查问)
8.Mybatis 是否反对提早加载?如果反对,它的实现原理是什么?
Mybatis 仅反对 association 关联对象和 collection 关联汇合对象的提早加载,association 指的是一对一,collection 值的就是一对多查问。在 Mybatis 配置文件中,能够配置是否启用提早加载 lazyLoadingEnabled=truefalse。
它的原理是,应用 CGLIB 创立指标的代理对象,当调用指标办法时,进入拦截器办法,比方调用 a.getB.getName(), 拦截器 invoke()办法 a.getB()是 null 值,那么就会独自发送当时保留好的查问关联 B 对象的 sql,把 B 查问上来,而后调用 a.setB(b),于是 a 的对象 b 属性就有值了,接着实现 a.getB().getName()办法的调用。这就是提早加载的基本原理。
9.Mybatis 的 XML 映射文件中,不同的 XML 映射文件,id 是否能够反复?
不同的 XML 映射文件,如果配置了 Namespace,那么 Id 能够反复;如果没有配置 namespace,那么 Id 不能反复;毕竟 Namespace 不是必须加的,只是最佳实际而已。
起因就是 namespace+id 是 Map<String.MappedStatement> 的 key 应用的,如果没有 Namespace,就剩下 Id, 那么 id 反复会导致数据相互笼罩。有了 namespace,天然 id 就能够反复,namespcae 不同,namespace+id 天然也就不同。
10.Mybatis 都有哪些 Executor 执行器?他们之间的区别是什么?
有三种:SimpleExecutor、ReuseExector、BatchExector。
SimpleExecutor: 每执行一次 update 或 select,就会开启 Statement 对象,用完立即敞开 Statement 对象。
ReuseExecutor: 执行 update 或 select,以 sql 作为 key 查找 Statement 对象,存在就应用,不存在就创立,用完后,不敞开 Statement 对象,而是搁置于 Map<String,Statement> 内,供一次应用。简言之,重复使用 Statement 对象。
BatchExecutor: 执行 Update(没有 select,JDBC 批处理不反对 select), 将所有 sql 都增加到批处理中 (addBatch),期待对立执行(executorBatch()),它缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch() 结束后,期待逐个执行 executeBatch()批处理,与 JDBC 批处理雷同。
11.Mybatis 中如何制订应用哪一种 Executor 执行器?
在 Mybatis 配置文件中,能够指定默认的 ExecutorType 执行器类型,也能够手动给 DefalutSqlSessionFactory 的创立 SqlSession 的办法传递 ExecutorType 类型参数。
12.Mybatis 是否能够映射 Enum 枚举类?
Mybatis 能够映射枚举类,岂但能够映射枚举类,Mybatis 能够映射任何对象到表的一列上。映射办法为自定义一个 TypeHandler,实现 TypeHandler 的 setParameter()和 getResult()接口办法。TypeHandler 有两个作用,一是实现从 javaType 至 jdbcType 的转换,二是实现 jdbcType 至 javaType 的转换,体现为 setParameter()和 getResult()两个办法,别离代表设置 sql 问好占位符参数和获取列查问后果。
13.Mybatis 映射文件中,如果 A 标签通过 include 援用了 B 标签的内容,请问 B 标签的内容是否定义在 A 标签之后,还是必须定义为 A 之前?
尽管 Mybatis 解析 Xml 映射文件是按程序接续的,然而,被援用的 B 标签仍然能够定义在任何中央,Mybatis 都能够正确辨认。
原理是,当我 A 蕴含了 B 的时候,Mybatis 解析到 A 的时候,发现 B 还没有,会将 A 设置为未解析状态,而后持续解析上面的标签,待所有标签都解析齐全后,再去解析一次未解析的标签。
14.Mybatis 与 Spring dataJpa 的区别
首先,SprigData JPA 能够了解为对 Jpa 标准再次封装形象,底层还是应用 hibernate 框架的 JPA 技术实现。
JPA 默认应用 Hibernate 技术实现,所以,个别应用 Springdata JPA 也就是 hibernate。
Hibernate 是一个凋谢源代码的对象关系映射框架,他对 JDBC 进行十分轻量级的对象封装。它将 POJO 与数据库表建设映射关系,是一个全自动的 orm 框架,hibernate 能够主动生成 SQL 语句,使得 Java 成员能够得心应手的应用对象编程思维来操纵数据库。
Mybatis 是一款优良的长久层框架,它反对定制化 SQL、贮存过程以及高级映射。Mybatis 防止了简直所有的 JDBC 代码和手动设置参数以及获取后果集。Mybatis 能够应用简略的 XML 或者注解来配置和映射原生信息,将接口和 Java 的 entity 对象映射成数据库中的记录。
所以,咱们说 jpa 和 mybatis 的区别也就说 hibernate 和 mybatis 的区别。
Hibernate 对象 / 关系映射能力强,数据库无关性好,对于关系模型要求高的软件 (例如需要固定的定制化软件),用 Hibernate 开发能够节俭很多代码,提高效率。然而学习门槛高,要精通门槛更高,而且还要满足设计 O /R(Object/Relation) 映射, 在性能和对象模型之间如何衡量,我实习中看 powerdesigner 中的数据模型,确实挺多表。多对多的表中,两头又有一个关联表,因而我这边写代码 pojo 的时候也会多一个类。
总的来说,Mybatis 能够进行更粗疏的 SQL 优化,查问必要的字段,然而须要保护 SQL 和查问后果集的映射。数据库的移植性较差,针对不同的数据库编写不同的 SQL。
Hibernate 对数据库提供了较为残缺的封装,封装了根本的 DAO 层操作,有较好的数据库移植性,然而学习周期长,开发难度大于 Mybatis。
小结:
Mybatis 学习门槛低,简略易学,程序员间接编写 sql,可严格控制 sql 执行性能,灵便度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业经营类软件等,因为这类软件需要变动频繁,一但需要变动要求成绩输入迅速。
今日份分享已完结,请大家多多包涵和指导!