【笔记】mybatis面试题总结

目录

MyBatis是什么?

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

传统JDBC开发存在的问题

Mybatis是如何解决传统JDBC开发的问题的?

Hibernate 和 MyBatis 的区别

#{}和${}的区别

Mybatis中的缓存机制

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


MyBatis是什么?

MyBatis是一个半自动的ORM(对象关系映射)持久层框架,支持定制化SQL。

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

之所以说mybatis是半自动的,是因为mybatis需要手动写sql。Hibernate属于全自动的,因为配置java bean和数据表的映射关系后,可以直接使用hql进行数据库操作,不需要编写sql;不过hql并不是万能的,对于某些复杂的查询场景会非常麻烦。

传统JDBC开发存在的问题

  • 频繁的创建销毁数据库连接对象,容易造成资源浪费。可以使用连接池,但是要自己实现连接池的相关代码。
  • 在java代码中编写sql,sql变动要改变java代码,不方便。
  • sql参数的设置、查询结果集的获取转换和资源的释放都十分繁琐,代码量大。

Mybatis是如何解决传统JDBC开发的问题的?

  • 可以直接在mybatis的xml配置文件中配置数据库连接池,非常简单。
  • mybatis的sql统一编写在xml配置文件中,修改sql不必改动java代码。
  • mybatis可以传递多种类型去作为sql参数,同时对于查询结果集也能映射到多种数据类型(集合、bean等)。

Hibernate 和 MyBatis 的区别

  • mybatis是一个半自动的ORM框架,开发人员必须自己编写sql;hibernate是一个全自动ORM框架,通过配置Java对象与数据库表的关系,能够做到不用编写sql就能操作数据库。
  • mybatis的数据库移植性比hibernate要差,因为mybatis是手写sql,如果写开发人员没有这方面的经验容易产生这类问题;hibernate通过bean表映射和hql能忽略掉数据库sql的具体细节,由hibernate根据不同数据库生成sql,直接操作数据库,所以移植性好。
  • 不过也正是因为hibernate的sql可以直接生成,所以在复杂场景下对sql的优化比较麻烦;而mybatis因为是手写sql,所以优化分方便。

#{}和${}的区别

#{}是占位符,预编译处理;${}是拼接符,字符串替换,没有预编译处理。预编译就是传入的参数只会被当成值,因为会为参数加上单引号;而${}不会加单引号,参数可能会称为sql语句的一部分。

Mybatis中的缓存机制

https://www.cnblogs.com/wuzhenzhao/p/11103043.html

mybatis中有一、二级缓存,默认一级缓存是开启的,开启二级缓存需要进行配置。mybatis查询数据的顺序是:二级缓存——>一级缓存——>数据库。

一级缓存

  • 作用域:一级缓存的作用域是SqlSession,也就是数据库会话。项目中通常会创建多个SqlSession,它们之间是相互独立的,这意味着内部的缓存数据也是相互独立的。
  • 数据结构:SqlSession类有一个Executor属性,这个属性中维护了一个PerpetualCache对象,里面有一个HashMap,这个HashMap就是用来存储一级缓存数据的。
  • 缓存更新机制:当执行select语句时,会将查询结果存储在当前会话的一级缓存中;当执行更新操作(insert、update、delete)时,为了保证当前会话中缓存的一致性,当前会话中的缓存会失效。
  • 生命周期:一级缓存的生命周期是数据库会话的生命周期,当会话结束后,一级缓存也失效了。
  • 问题:若项目中存在多个会话,当一个会话在数据库中修改了另一个会话中缓存的数据,另一个会话就有可能读到脏数据。解决:mybatis一级缓存有两种:session和statement。可以把缓存模式改成statement(配置文件中配置),这样每次查询结束时会清理掉一级缓存(BaseExecutor的query方法)。

二级缓存

  • 作用域:二级缓存主要是为了解决一级缓存不能跨会话共享的问题,作用域是namespace,也就是一个mapper内的所有方法共享一份缓存,而所有mapper缓存对所有的会话都是共享的
  • 数据结构或实现:SqlSession使用CachingExecutor执行sql语句,CachingExecutor是对普通Executor的装饰,查询时会先从会话外部指定的namespace缓存中进行查找,有就返回,没有就委托被装饰的Executor(执行器)进行查找,会先查找一级缓存,有就返回,没有就查询数据库,然后把数据添加到一级和二级缓存中。
  • 缓存更新机制:缓存添加和失效的机制和一级缓存一致。
  • 生命周期:和整个应用的生命周期一致。
  • 问题:跨namespace也可能会出现数据脏读的问题。解决:1.多个namespace共享一个缓存(如下)。2.关闭二级缓存。
<cache-ref namespace="其它命名空间" />

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

  • SimpleExecutor:每次执行update或select操作,都会创建一个Statement对象,用完立刻关闭。
  • ReuseExecutor:每次执行update或select操作,会先根据sql(key)查找有没有已经创建好的statement,有就使用,没有就创建,创建之后会放到map中,以便下次使用。
  • BatchExecutor:执行update时,可以缓存多个Statement,然后一起执行。
  • CachingExecutor :开启二级缓存后使用的查询器,是对以上三种执行器的装饰。查询时,会现在二级缓存中查询,没有再使用普通查询器进行查询。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值