史上最全MyBatis面试题目

MyBatis介绍
MyBatis是什么

MyBatis 是一款优秀的持久层框架,一个半 ORM(对象关系映射)框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录
MyBatis是让你写的java程序对数据库进行增删改查的一个工具。java对数据库进行增删改查的工具很多,跟其他的比起来,mybatis容易上手,而且开发起来也很简单,同时与spring的组合也非常容易。目前各大互联网公司多是使用mybatis。

ORM是什么

ORM(Object Relational Mapping),对象关系映射,是一种为了解决关系型数据库数据与简单Java对象(POJO)的映射关系的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系型数据库中。
ORM:对象关系映射(Object Relational Mapping,简称ORM),目的是想像操作对象一样操作数据库.因为数据库不是面向对象的,所以需要编程进行映射.
ORM框架理论上说可以比不用的情况,开发效率更高,但像hibernate的学习成本还是比较高的。缺点主要是要花时间学习框架和执行效率相对会差些;这些对于大项目来说还是值得的,只要先一个简单易用的ORM框架就行。
常见的ORM框架有hibernate,半自动orm框架有mybatis,还有新的简单易用的bee框架. jpa只是想让所有的orm框架都统一使用的标准接口; hibernate有实现jpa,但mybaits没有.
用hibernate和mybatis,每次操作一个表,都需要编写一次dao文件,感觉做些重复工,好枯燥无味。 Bee框架:一个十分钟即可学会的ORM框架。它不用每写一个dao就要编写一次代码,省时省力,开发效率极高,编码复杂度为O(1).一个开发成本和开发速度都不比php差的java ORM框架。

MyBatis为什么说是半自动ORM映射工具?它于全自动的差别在哪里!

Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象
时,可以根据对象关系模型直接获取,所以它是全自动的。而 Mybatis 在查询关联对象或
关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。

如果不用MyBatis使用传统jdbc开发会遇到什么问题

1、 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。但使用jdbc还要自己实现连接池
2、 Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码
3、使用preparestatement像占位符传参数时存在硬解码,修改sql语句时还要修改java代码,不易维护, 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。
4.结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。结果集处理存在重复代码,处理麻烦。如果可以映射成Java对象会比较方便

jdbc开发的不足之处使用MyBatis是如何解决的

对应上面那4点
1.在mybatis-config.xml中配置数据链接池,使用连接池管理数据库连接
2.将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
3. Mybatis自动将java对象映射至sql语句。
4. Mybatis自动将sql执行结果映射至java对象。

MyBatis的特点

mybatis是一种持久层框架,也属于ORM映射。前身是ibatis。
相比于hibernatehibernate为全自动化,配置文件书写之后不需要书写sql语句,但是欠缺灵活,很多时候需要优化;
mybatis为半自动化,需要自己书写sql语句,需要自己定义映射。增加了程序员的一些操作,但是带来了设计上的灵活,并且也是支持hibernate的一些特性,如延迟加载,缓存和映射等;对数据库的兼容性比hibernate差。移植性不好,但是可编写灵活和高性能的sql语句
简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
提供映射标签,支持对象与数据库的ORM字段关系映射
提供对象关系映射标签,支持对象关系组建维护
提供XML标签,支持编写动态sql。

MyBatis的优缺点

sql语句与代码分离,存放于xml配置文件中:
优点:便于维护管理,不用在java代码中找这些语句;
缺点: JDBC方式可以用用打断点的方式调试,但是Mybatis不能,需要通过log4j日志输出日志信息帮助调试,然后在配置文件中修改。
用逻辑标签控制动态SQL的拼接:
优点:用标签代替编写逻辑代码;
缺点:拼接复杂SQL语句时,没有代码灵活,拼写比较复杂。不要使用变通的手段来应对这种复杂的语句。
查询的结果集与java对象自动映射:
优点:保证名称相同,配置好映射关系即可自动映射或者,不配置映射关系,通过配置列名=字段名也可完成自动映射。提供对象关系映射标签,支持对象关系组件维护
能够与Spring很好的集成
缺点:对开发人员所写的SQL依赖很强。当字段多,关联表很多的时候,对开发人员的工作量比较大,而且对开发人员的sql功底有一定的要求
编写原生SQL:
优点:接近JDBC,比较灵活。与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接
缺点:对SQL语句依赖程度很高;并且属于半自动,数据库移植比较麻烦,比如mysql数据库编程Oracle数据库,部分的sql语句需要调整。不能随意更换数据库

MyBatis适合使用的场景

因为MyBatis专注于SQL,所以可以是一个很灵活的DAO层解决方案。
比较适用于对性能要求很高,或者需求变化很多的项目,MyBaits都是一个很不错的选择。

Hibernate和MyBaits的区别

相同点是都对jdbc进行了封装,都是对DAO层的开发且都是持久层框架;
MyBaits:
是一个半自动的映射框架,主要配置java对象和sql执行结果之间的对应关系,多表关联;配置相对说简单。
需要手动编写sql,支持动态sql、处理列表、动态生成表名、支持存储过程。相对来说工作量大。直接使用sql操作数据库,不支持于数据库无关的,但sql优化简单
轻量型框架,学习简单适合变化较多的大型项目
是一个小巧、方便、高效、简单、直接、半自动化的持久层框架
Hibernate:
是一个全表映射的框架,配置Java对象与数据库表的对应关系,多表关联关系配置复杂;
对SQL语句封装,提供了日志、缓存、级联(级联比 MyBatis 强大)等特性,此外还提供 HQL(Hibernate Query Language)操作数据库,数据库无关性支持好,但会多消耗性能。如果项目需要支持多种数据库,代码开发量少,但SQL语句优化困难。
重量级框架,学习使用门槛高,适合于需求相对稳定,中小型的项目
是一个强大、方便、高效、复杂、间接、全自动化的持久层框架

MyBatis的核心类

SqlSessionFactory:用于注册数据库连接每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或通过Java的方式构建出 SqlSessionFactory 的实例。SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,建议使用单例模式或者静态单例模式。一个SqlSessionFactory对应配置文件中的一个环境(environment),如果你要使用多个数据库就配置多个环境分别对应一个SqlSessionFactory。
SqlSession:SqlSession是一个接口,它有2个实现类,分别是DefaultSqlSession(默认使用)以及SqlSessionManager。SqlSession通过内部存放的执行器(Executor)来对数据进行CRUD。此外SqlSession不是线程安全的,因为每一次操作完数据库后都要调用close对其进行关闭,官方建议通过try-finally来保证总是关闭SqlSession。
Executor:Executor(执行器)接口有两个实现类,其中BaseExecutor有三个继承类分别是BatchExecutor(重用语句并执行批量更新),ReuseExecutor(重用预处理语句prepared statement,跟Simple的唯一区别就是内部缓存statement),SimpleExecutor(默认,每次都会创建新的statement)。以上三个就是主要的Executor。通过下图可以看到Mybatis在Executor的设计上面使用了装饰器模式,我们可以用CachingExecutor来装饰前面的三个执行器目的就是用来实现缓存。
MappedStatement:MappedStatement就是用来存放我们SQL映射文件中的信息包括sql语句,输入参数,输出参数等等。一个SQL节点对应一个MappedStatement对象。

MyBatis的运行原理解析
MyBatis的编程步骤
  1. 创建SqlSessionFactory
  2. 通过SqlSessionFactory创建SqlSession
  3. 通过sqlsession执行数据库操作
  4. 调用session.commit()提交事务
  5. 调用session.close()关闭会话
谈谈MyBatis的工作原理

关于MyBatis的工作原理,网上的文章是多如牛毛,小翊觉得,要结合jdbc来理解才能完全的了解它;
jdbc有4大核心对象:
(1)DriverManager,用于注册数据库连接
(2)Connection,与数据库连接对象
(3)Statement/PrepareStatement,操作数据库SQL语句的对象
(4)ResultSet,结果集或一张虚拟表
而MyBatis也有四大核心对象:
(1)SqlSession对象,该对象中包含了执行SQL语句的所有方法。类似于JDBC里面的Connection 。
(2)Executor接口,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。类似于JDBC里面的Statement/PrepareStatement。
(3)MappedStatement对象,该对象是对映射SQL的封装,用于存储要映射的SQL语句的id、参数等信息。
(4)ResultHandler对象,用于对返回的结果进行处理,最终得到自己想要的数据格式或类型。可以自定义返回类型。
关于他的流程大体是这样的在这里插入图片描述

  1. 读取MyBatis的配置文件mybatis_config.xml用与全局配置,配置数据库连接等信息
  2. 加载映射文件。映射文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在MyBatis配置文件mybatis-config.xml中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。
  3. 构造会话工厂。通过MyBatis的环境配置信息构建会话工厂SqlSessionFactory。
  4. 创建会话对象。由会话工厂创建SqlSession对象,该对象中包含了执行SQL语句的所有方法。
  5. Executor执行器。MyBatis底层定义了一个Executor接口来操作数据库,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。
  6. MappedStatement对象。在Executor接口的执行方法中有一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等信息。
  7. 输入参数映射。输入参数类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输入参数映射过程类似于JDBC对preparedStatement对象设置参数的过程。
  8. 输入参数映射。输入参数类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输入参数映射过程类似于JDBC对preparedStatement对象设置参数的过程。
    在JDBC中,Connection不直接执行SQL方法,而是利用Statement或者PrepareStatement来执行方法。
    在使用JDBC建立了连接之后,可以使用Connection接口的createStatement()方法来获取Statement对象,也可以调用prepareStatement()方法获得PrepareStatement对象,通过executeUpdate()方法来执行SQL语句。
    而在MyBatis中,SqlSession对象包含了执行SQL语句的所有方法。但是它是委托Executor执行的。
    从某种意义上来看,MyBatis里面的SqlSession类似于JDBC中的Connection,他们都是委托给其他类去执行。
    最后说一点,虽然SqlSession对象包含了执行SQL语句的所有方法,但是它同样包括了:
<T> T getMapper(Class<T> type);

所以SqlSession也可以委托给映射器来执行数据的增删改查操作。如下代码所示:

// 获得mapper接口的代理对象
PersonMapper pm = session.getMapper(PersonMapper.class);
// 直接调用接口的方法,查询id为1的Peson数据
Person p2 = pm.selectPersonById(1);

这上面来看,SqlSession是不是也类似于JDBC中的Connection呢。
未完待续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值