Java面试——mybatis

MyBatis简介

说说mybatis的优点和缺点

优点

  • 基于SQL语句编程,相当灵活,不会对应用程序或者数据库现有的设计造成任何影响,SQL写在XML文件中,解除SQL与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
  • 与JDBC相比,减少了50%以上的代码量,消除了JDBC大量的冗余代码,不需要手动开关连接。
  • 很好地与各种数据库兼容(由于Mybatis使用JDBC来连接数据库,所以只要JDBC支持的数据,MyBaits都支持)。
  • 提供映射标签,支持对象与数据库的ORM字段映射;提供对象关系映射标签,支持对象关键组件维护。

缺点

  • SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
  • SQL语句的编写工足量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。

MyBatis的架构

MyBatis编程步骤是怎么样的

  • 创建SqlSessionFactory
  • 通过SqlSessionFactory创建SqlSession对象
  • 通过SqlSession对象执行数据库操作
  • session.commit()提交事务
  • session.close()关闭会话

说一说MyBatis的工作原理

在这里插入图片描述

  1. 读取MyBatis配置文件。
  2. 加载SQL映射文件。
  3. 创建会话工厂SqlSessionFactory。
  4. 创建会话对象SqlSession。
  5. Executor 执行器:MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession
    传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。
  6. MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参
    数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。
  7. 输入参数映射。
  8. 输出参数映射

映射器

实体类的属性名与表中的字段名不一致时,怎么办?

  1. 通过在SQL语句中定义字段的别名,让别名与实体类的属性名一致
<select id="selectorder " parametertype="int" resultetype="me.gacl.domain.order"> 
	select order_id id, order_no orderno ,order_price price 
	form orders 
	where order_id=#{id};
</select>
  1. 使用resultMap映射标签,其id属性用来映射主键字段,result属性用来映射非主键字段。
<select id="getOrder" parameterType="int" resultMap="orderresultmap">
	select * from orders where order_id=#{id}
</select>
<resultMap type=me.gacl.domain.order id=orderresultmap〉
	<!–用 id 属性来映射主键字段–>
	<id property=id column=order_id〉
	<!–用 result 属性来映射非主键字段,property 为实体类属性名,column 为数据表中的属性–> 
	<result property = “orderno” column =order_no/
	<result property=price column=order_price /
</reslutMap>

MyBatis是如何将sql执行结果封装为目标对象并返回的?

第一种是使用标签,逐一定义数据库列名和对象属性名之间的映射关系。
第二种是使用 sql 列的别名功能,将列的别名书写为对象属性名。
有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时使用反射给对象的属性逐一赋 值并返回,那些找不到映射关系的属性,是无法完成赋值的。

mybatis的一级缓存、二级缓存

mybaits进行SQL查询时,会先去缓存进行查询。如果缓存没有命中,再去数据库进行查询。这样避免每次查询都查询数据库,提升了检索数据的效率。
在这里插入图片描述

一级缓存

在这里插入图片描述

原理
在sql session中有一个excutor对象,Local cache对象,当用户发起查询的时候呢,executor就会根据SQL语句在local cache里面去查询,那如果没有命中的话就会再去查询数据库,将查询结果写入Local Cache中,否则那就直接返回。所以多个Sql Session或者是分布式环境下就可能导致数据库的写操作出现脏数据。
在这里插入图片描述

二级缓存

在这里插入图片描述
在这里插入图片描述

原理

开启了二级缓存的查询流程会在进行一级缓存查询前,通过cachingExecutor进行二级缓存的查询,cachingExecutor对Executor进行了一个封装,实现了多个SqlSession的缓存数据共享,是一个全局缓存。如果二级缓存没有命中再查一级缓存。
在这里插入图片描述

在这里插入图片描述

一级缓存基于Sql Session,默认开启,其作用域是Session,当session进行flush或者close时,该Session的所有cache就会被清空。
二级缓存基于Namespace 和 Mapper的作用域,需要额外开启。

mybaits中#{}和${}有什么区别

  1. #号,是一个占位符,等同于JDBC中的?号。相当于向PreparedStatement中的预处理语句设置参数,该语句是预编译的,如果有特殊字符会进行转移,可以有效防止SQL注入。
  2. $号,是一个动态参数,相当于直接把参数拼接到原始的SQL里面,存在SQL注入的风险。

在这里插入图片描述
在这里插入图片描述

mybatis是如何实现分页的?

  • 数据库层面。通过数据库提供的分页关键字(limit、offset),然后再业务层传递当前页以及每页的页数即可。
  • 使用mybatis提供的RowBounds对象,实现内存级别分页。RowBounds会一次性加载所有符合条件的目标数据,根据分页参数在内存中实现分页。
  • 基于Mybatis中的Interceptor,在SQL执行前动态拼接分页关键词。

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值