欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Mybatis面试专题及答案

程序员文章站 2022-03-19 16:07:07
1.什么是Mybatis?Mybatis是一个可以自定义sql、存储过程和高级映射的持久层框架。2.讲一下Mybatis的缓存 Mybatis的缓存分为一级缓存和二级缓存,一级缓存放在session里面,默认就有。二级缓存放在它的命名空间里,默认是打不开的,使用二级缓存属性需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件里中配置3.Mybatis是如何进行分页的?分页插件的原理是什么? 1)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 的功能。

     2)  Mybatis 提供了 9 种动态 sql 标签:trim|where|set|foreach|if|choose|when|otherwise|bind。
 
     3)其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。

5.#{}${}的区别是什么?

       #把传入的数据都当成一个字符串,会自动对传入数据加上一个双引号,很大程度上能防止sql注入。
       
       $将传入的数据直接显示生产在sql中,无法防止sql注入。
 

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 实现一对一有几种方式?具体怎么操作的?

      有联合查询和嵌套查询 , 联合查询是几个表联合查询 , 只查询一次 , 通过在 resultMap 里面 配置 association 节点配置一对一的类就可以完成 ; 嵌套查询是先查一个表 , 根据这个表里面的结果的外键 id, 去再另外一个表里面查询数据 , 也是通过 association 配置 , 但另外一个表的查询通过 select 属性配置。
 
 

15.Mybatis 能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别?

     能, Mybatis 不仅可以执行一对一、一对多的关联查询,还可以执行多对一,多对多的关联查询,多对一查询,其实就是一对一查询,只需要把 selectOne() 修改为 selectList()即可;多对多查询,其实就是一对多查询,只需要把 selectOne() 修改为 selectList() 即可。
     关联对象查询,有两种实现方式,一种是单独发送一个 sql 去查询关联对象,赋给主对象,然后返回主对象。另一种是使用嵌套查询,嵌套查询的含义为使用 join 查询,一部分列是 A 对象的属性值,另外一部分列是关联对象 B 的属性值,好处是只发一个 sql 查询,就可以把主对象和其关联对象查出来。
 
 

16.MyBatis 里面的动态 Sql 是怎么设定的?用什么语法?

       MyBatis 里面的动态 Sql 一般是通过 if 节点来实现 , 通过 OGNL 语法来实现 , 但是如果要写的完整, 必须配合 where,trim 节点 ,where 节点是判断包含节点有内容就插入 where, 否则不插入,trim 节点是用来判断如果动态语句是以 and or 开始 , 那么会自动把这个 and 或者 or 取掉。
 

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

       第一种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系。

       Mybatis面试专题及答案

       第二种是.通过sql的列别名功能,使列别名与对象属性名之间对应,比如:T—NAME AS name,列别名通常不区分大小写,属性名通常小写,mybatis通常会忽略大小写智能的对应。

18.Xml 映射文件中,除了常见的 select|insert|updae|delete 标签之外,还有哪些标签?

        还有很多其他的标签, <resultMap> <parameterMap> <sql> <include> 、<selectKey>,加上动态 sql 9 个标签, trim|where|set|foreach|if|choose|when|otherwise|bind 等,其中 <sql> sql 片段标签,通过<include> 标签引入 sql 片段, <selectKey> 为不支持自增的主键生成策略标签。
 

19.当实体类中的属性名和表中的字段名不一样,如果将查询的结果封装到指定

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

20.模糊查询 like 语句该怎么写

       1 )在 java 中拼接通配符,通过 #{} 赋值
       2 )在 Sql 语句中拼接通配符 (不安全 会引起 Sql 注入)

21.通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应, Dao 的工作原理,是否可以重载?

       不能重载,因为通过 Dao 寻找 Xml 对应的 sql 的时候全限名 + 方法名的保存和寻找策略。接口工作原理为 jdk 动态代理原理,运行时会为 dao 生成 proxy ,代理对象会拦截接口方法,去执行对应的 sql 返回数据。
 

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 是否可以重复?

      不同的 Xml 映射文件,如果配置了 namespace ,那么 id 可以重复;如果没有配置namespace,那么 id 不能重复;毕竟 namespace 不是必须的,只是最佳实践而已。原因就 是 namespace+id 是作为 Map<String, MappedStatement>的 key 使用的,如果没有namespace,就剩下 id ,那么, id 重复会导致数据互相覆盖。有了 namespace ,自然 id 就可以重复,namespace 不同, namespace+id 自然也就不同。
 

24.Mybatis 是否可以映射 Enum 枚举类?

Mybatis 可以映射枚举类,不单可以映射枚举类,Mybatis 可以映射任何对象到表的一列上。映射方式为自定义一个 TypeHandler,实现 TypeHandler setParameter()和getResult()接口方法。TypeHandler 有两个作用,一是完成从 javaType jdbcType 的转换,二是完成 jdbcType javaType 的转换,体现为 setParameter()getResult()两个方法,分别代表设置 sql 问号占位符参数和获取列查询结果

25.在 mapper 中如何传递多个参数?

        1)顺序传参法

             Mybatis面试专题及答案

         #{}里面的数字代表你传入参数的顺序。这种方法不建议使用,sql层表达不直观,且一旦顺序调整容易出错。

        2)@Param注解传参法

        Mybatis面试专题及答案

          #{}里面的名称对应的是注解 @Param括号里面修饰的名称。 这种方法在参数不多的情况还是比较直观的,推荐使用。
 
        3)  Map传参法
    
            Mybatis面试专题及答案
  
             #{}里面的名称对应的是 Map里面的key名称。 这种方法适合传递多个参数,且参数易变能灵活传递的情况。
       
          4) Java Bean传参法
          
            Mybatis面试专题及答案
             #{}里面的名称对应的是 User类里面的成员属性。 这种方法很直观,但需要建一个实体类,扩展不容易,需要加属性,看情况使用。
 

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 的区别?

       resultmap与resulttype的区别为:对象不同、描bai述不同、类型适用不du同
 
       

       一、对象不同

             1、resultmap:resultMap如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。

             2、resulttype:resultType使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。

     

      二、描述不同

            1、resultmap:resultMap对于一对一表连接的处理方式通常为在主表的pojo中添加嵌套另一个表的pojo,然后在mapper.xml中采用association节点元素进行对另一个表的连接处理。

              Mybatis面试专题及答案
           
          2、resulttype:resultType无法查询结果映射到pojo对象的pojo属性中,根据对结构集查询遍历的需要选择使用resultType还是resultMap。
 

     三、类型适用不同

         1、resultmap:mybatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap。

         2、resulttype:resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,但是resultType跟resultMap不能同时存在。

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

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

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

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

4Mapper.xml 文件中的 namespace 即是 mapper 接口的类路径。

 
 
 
 

本文地址:https://blog.csdn.net/qq_38533842/article/details/109603140

相关标签: mybatis