Mybatis面试专题及答案
1.什么是Mybatis?
Mybatis是一个可以自定义sql、存储过程和高级映射的持久层框架。
2.讲一下Mybatis的缓存
Mybatis的缓存分为一级缓存和二级缓存,一级缓存放在session里面,默认就有。二级缓存放在它的命名空间里,默认是打不开的,使用二级缓存属性需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件里中配置<cache/>
3.Mybatis是如何进行分页的?分页插件的原理是什么?
1)Mybatis使用RowBounds对象进行分页,也可以直接表写sql实现分页,也可以使用mybatis的分页插件。
2)分页插件的原理:实现mybatis提供的接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql。
举例:select * from student, 拦截sql后重写为:select t.* from (select * from student ) t limit 0,10
4.Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql 的执行原理不?
1)Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。
5.#{}和${}的区别是什么?
6.为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而 Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。
7.Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?
1,Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载, association指的就是一对一, collection 指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载LazyLoadingEnabled=true|false。
2.他的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送实现保存好的查询关联B对象的SQL,把B查询上来,然后调用a.setB(b),于是a的对象b熟悉就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。
8.MyBatis 与 Hibernate 有哪些不同?
1) Mybatis 和 hibernate 不同,它不完全是一个 ORM 框架,因为 MyBatis 需要程序员自己编写 Sql 语句,不过 mybatis 可以通过 XML 或注解方式灵活配置要运行的 sql 语句,并将java 对象和 sql 语句映射生成最终执行的 sql,最后将 sql 执行的结果再映射生成 java 对象。
2) Mybatis 学习门槛低,简单易学,程序员直接编写原生态 sql,可严格控制 sql 执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是 mybatis 无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套 sql 映射文件,工作量大。
3) Hibernate 对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用 hibernate 开发可以节省很多代码,提高效率。但是Hibernate 的缺点是学习门槛高,要精通门槛更高,而且怎么设计 O/R 映射,在性能和对象模型之间如何权衡,以及怎样用好 Hibernate 需要具有很强的经验和能力才行。总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。
9.MyBatis 的好处是什么?
1) MyBatis 把 sql 语句从 Java 源程序中独立出来,放在单独的 XML 文件中编写,给程序的维护带来了很大便利。
2) MyBatis 封装了底层 JDBC API 的调用细节,并能自动将结果集转换成 Java Bean 对象,大大简化了 Java 数据库编程的重复工作。
3)因为 MyBatis 需要程序员自己去编写 sql 语句,程序员可以结合数据库自身的特点灵活控制 sql 语句,因此能够实现比 Hibernate 等全自动 orm 框架更高的查询效率,能够完成复杂查询。
10.简述 Mybatis 的 Xml 映射文件和 Mybatis 内部数据结构之间的映射关系?
在Mybatis将所有的XML配置信息都封装到ALL-IN-One重量级Configuration内部,在XML映射文件中, <parameterMap>标签会被解析为ParameterMapping对象,<resultMap>标签会被解析为ResultMap对象, 其每个子元素会被解析为ResultMapping对象。每一个select,insert,update,delete,标签会被解析为MappedStatement对象, 标签内的sql会被解析为BoundSql对象。
11.什么是 MyBatis 的接口绑定,有什么好处 ?
接口映射就是在Mybatis中任意定义接口,然后把接口里面的方法和sql语句绑定,我们直接调用接口方法就可以,这样比原来的SqlSession提高的方法我们可以有更加灵活的选择和设置。
12.接口绑定有几种实现方式,分别是怎么实现的?
接口绑定有两种实现方式,一种是通过注解绑定,就是子接口的方法上面加@select,@update等注解里面包含Sql语句来绑定,另外一种就是通过xml里面写sql来绑定,在这种情况下,要指定xml文件里面的namespace必须为接口的全路径名字。
13.什么情景下使用注解绑定,什么情况下使用xml绑定?
当 Sql 语句比较简单时候,用注解绑定;当 SQL 语句比较复杂时候,用 xml 绑定,一般用xml 绑定的比较多
14.MyBatis 实现一对一有几种方式?具体怎么操作的?
15.Mybatis 能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别?
16.MyBatis 里面的动态 Sql 是怎么设定的?用什么语法?
17.Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式?
第一种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系。
第二种是.通过sql的列别名功能,使列别名与对象属性名之间对应,比如:T—NAME AS name,列别名通常不区分大小写,属性名通常小写,mybatis通常会忽略大小写智能的对应。
18.Xml 映射文件中,除了常见的 select|insert|updae|delete 标签之外,还有哪些标签?
19.当实体类中的属性名和表中的字段名不一样,如果将查询的结果封装到指定 ?
20.模糊查询 like 语句该怎么写
21.通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应, Dao 的工作原理,是否可以重载?
22.Mybatis 映射文件中,如果 A 标签通过 include 引用了 B 标签的内容,请问,B 标签能否定义在 A 标签的后面,还是说必须定义在 A 标签的前面?
虽然 Mybatis 解析 Xml 映射文件是按照顺序解析的,但是,被引用的 B 标签依然可以定义在任何地方,Mybatis 都可以正确识别。原理是,Mybatis 解析 A 标签,发现 A 标签引用了 B 标签,但是 B 标签尚未解析到,尚不存在,此时,Mybatis 会将 A 标签标记为未解析状态,然后继续解析余下的标签,包含 B 标签,待所有标签解析完毕,Mybatis 会重新解析那些被标记为未解析的标签,此时再解析 A 标签时,B 标签已经存在,A 标签也就可以正常解析完成了。
23.Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?
24.Mybatis 是否可以映射 Enum 枚举类?
Mybatis 可以映射枚举类,不单可以映射枚举类,Mybatis 可以映射任何对象到表的一列上。映射方式为自定义一个 TypeHandler,实现 TypeHandler 的 setParameter()和getResult()接口方法。TypeHandler 有两个作用,一是完成从 javaType 至 jdbcType 的转换,二是完成 jdbcType 至 javaType 的转换,体现为 setParameter()和 getResult()两个方法,分别代表设置 sql 问号占位符参数和获取列查询结果
25.在 mapper 中如何传递多个参数?
1)顺序传参法
#{}里面的数字代表你传入参数的顺序。这种方法不建议使用,sql层表达不直观,且一旦顺序调整容易出错。
2)@Param注解传参法
26.resultType resultMap 的区别?
mybatis中select元素有两个属性resultType和resultMap,工作中总是使用到他们,但是他们有什么区别呢?就我的使用经验来说,对于单表查询映射或多表联合查询映射来说,他们都能达到要求,例如
package com.someapp.model;
public class User {
private int id;
private String username;
private String hashedPassword;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getHashedPassword() {
return hashedPassword;
}
public void setHashedPassword(String hashedPassword) {
this.hashedPassword = hashedPassword;
}
}
<!-- In mybatis-config.xml file -->
<typeAlias type="com.someapp.model.User" alias="User"/>
使用resultType
<select id="selectUsers" parameterType="int" resultType="com.someapp.model.User">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
这些情况下,MyBatis 会在幕后自动创建一个 ResultMap,基于属性名来映射列到 JavaBean 的属性上。如果列名没有精确匹配,你可以在列名上使用 select 字句的别名(一个 基本的 SQL 特性)来匹配标签。比如:
<select id="selectUsers" parameterType="int" resultType="User">
select
user_id as "id",
user_name as "userName",
hashed_password as "hashedPassword"
from some_table
where id = #{id}
</select>
使用resultMap
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="username"/>
<result property="password" column="password"/>
</resultMap>
<select id="selectUsers" parameterType="int" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>
看出来了吧,resultType和resultMap都映射到了User对象中
不同点:resultType 和restltMap
restulyType:
1.对应的是java对象中的属性,大小写不敏感,
2.如果放的是java.lang.Map,key是查询语句的列名,value是查询的值,大小写敏感
3.resultMap:指的是定义好了的id的,是定义好的resyltType的引用
注意:用resultType的时候,要保证结果集的列名与java对象的属性相同,而resultMap则不用,而且resultMap可以用typeHander转换
4.type:java 对象对应的类,id:在本文件要唯一 column :数据库的列名或别名, property:对应java对象的属性,jdbcType:java.sql.Types查询语句中,resultMap属性指向上面那个属性的标签的id parameterType:参数类型,只能传一个参数,如果有多个参数要封装,如封装成一个类,要写包名加类名,基本数据类型则可以省略
5.一对一、一对多时,若有表的字段相同必须写别名,不然查询结果无法正常映射,出现某属性为空或者返回的结果与想象中的不同,而这往往是没有报错的。
6.若有意外中的错误,反复检查以上几点,和认真核查自己的sql语句,mapper.xml文件是否配置正确。
另外还有resultMap 元素,它是 MyBatis 中最重要最强大的元素,它能提供级联查询,缓存等功能
POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。
27.resultType resultMap 的区别?
一、对象不同
1、resultmap:resultMap如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。
2、resulttype:resultType使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
二、描述不同
1、resultmap:resultMap对于一对一表连接的处理方式通常为在主表的pojo中添加嵌套另一个表的pojo,然后在mapper.xml中采用association节点元素进行对另一个表的连接处理。
三、类型适用不同
1、resultmap:mybatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap。
2、resulttype:resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,但是resultType跟resultMap不能同时存在。
28.使用 MyBatis 的 mapper 接口调用时有哪些要求?
1)Mapper 接口方法名和 mapper.xml 中定义的每个 sql 的 id 相同
2)Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类型相同
3)Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相同
4)Mapper.xml 文件中的 namespace 即是 mapper 接口的类路径。
本文地址:https://blog.csdn.net/qq_38533842/article/details/109603140