谈谈我对mybatis的总结

1.1.说说我对Mybatis的了解
1.Mybatis 基于java的持久层框架,它的内部封装了JDBC,让开发人员只需要关注SQL语句本身,不需要花费精力在驱动的加载、连接的创建、Statement的创建等复杂的过程。

2.Mybatis 通过 XML 或注解的方式将要执行的各种的 statement 配置起来,并通过 java 对象和 statement 中的 sql 的动态参数进行映射生成最终执行的SQL 语句,最后 由mybatis框架执行SQL,并将结果直接映射为java对象 。
3.采用了 ORM思想 解决了实体类和数据库表映射的问题。对 JDBC进行了封装 ,屏蔽了 JDBCAPI 底层的访问细节,避免我们与 jdbc 的 api 打交道,就能完成对数据的持久化操作。
 

1.2 Mybatis解决的问题
1、数据库连接的创建、释放连接的频繁操作造成资源的浪费从而影响系统的性能。

2、SQL语句编写在代码中,硬编码造成代码不容易维护,实际应用中SQL语句变化的可能性比较大,一旦变动就需要改变java类。

3、使用preparedStatement的时候传递参数使用占位符,也存在硬编码,因为SQL语句变化,必须修改源码。

4、对结果集的解析中也存在硬编码。
 

1.4 Mybatis解决的问题
1、数据库连接的创建、释放连接的频繁操作造成资源的浪费从而影响系统的性能。

2、SQL语句编写在代码中,硬编码造成代码不容易维护,实际应用中SQL语句变化的可能性比较大,一旦变动就需要改变java类。

3、使用preparedStatement的时候传递参数使用占位符,也存在硬编码,因为SQL语句变化,必须修改源码。

4、对结果集的解析中也存在硬编码。

3、Mybatis对象分析
3.1 Resources
Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象。
1.5 SqlSessionFactoryBuilder
SqlSessionFactory 的 创 建 , 需 要 使 用 SqlSessionFactoryBuilder 对 象 的 build() 方 法 。 事实上使用 SqlSessionFactoryBuilder 的原因是将SqlSessionFactory 这个复杂对象的创建交由 Builder 来执行,也就是使用了 建造者设计模式 。
建造者模式 : 又称生成器模式 , 是一种 对象的创建模式 。 可以将一个产品的内部表象与产品的生成过程分割开来 , 从而可以使一个建造过程生成具有不同的内部表象的产品( 将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示 ). 这样用户只需指定需要建造的类型就可以得到具体产品, 而不需要了解具体的建造过程和细节 .
在建造者模式中, 角色分指导者 (Director) 与建造者 (Builder): 用户联系指导者 , 指导者指挥建造者 , 最后得到产品 . 建造者模式可以强制实行一种分步骤进行的建造过程.
SqlSessionFactoryBuilder 充当的就是建造者角色 ,sqlSession就是我们最后得到的产品。

1.6 SqlSessionFactory
SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),是 线程安全 的,所以一个应用只需要一个该对象。创建SqlSession 需  SqlSessionFactory 接口的 openSession() 方法。
默认的 openSession()方法没有参数,它会创建有如下特性的 SqlSession :
1 、会开启一个手动提交的事务(也就是不自动提交)。
2 、将从由当前环境配置的 DataSource 实例中获取 Connection 对象。事务隔离级别将会使用驱动或数据源的默认设置。
3 、预处理语句不会被复用,也不会批量处理更新。
openSession(true) :创建一个有自动提交功能的 SqlSession
openSession(false) :创建一个非自动提交功能的 SqlSession ,需手动提交
openSession() :同 openSession(false)
3.4 SqlSession
SqlSession 接口对象用于执行持久化操作(内存数据写入数据库)。一个 SqlSession 对应着一次数据库会话,一次会话以 SqlSession 对象的创建开始,以SqlSession 对象的关闭结束。
SqlSession 接口对象是 线程不安全 的,所以每次数据库会话结束前,需要马上调用其 close() 方法,将其关闭。再次需要会话,再次创建。 SqlSession 在方法内部创建,使用完毕后关闭。
SqlSession 类中有超过 20 个方法,我们常用的几乎都是执行语法相关的方法。
这些方法被用来执行定义在 SQL 映射的 XML 文件中的 SELECT 、 INSERT 、 UPDATE 和 DELETE 语句。它们都会自行解释,每一句都使用语句的 ID 属性和参数对象,参数可以是原生类型(自动装箱或包装类)、 JavaBean 、 POJO 或 Map 。

20210810155604788.png
 selectOne 和 selectList 的不同仅仅是 selectOne 必须返回一个对象或 null 值。如果返回值多于一个,那么就会抛出异常。 

selectMap 稍微特殊一点,因为它会将返回的对象的其中一个属性作为 key 值,将对象作为 value 值,从而将多结果集转为 Map 类型值。

1.7 Mybatis架构/工作流程

 1 、 Mybatis.xml 文件是 mybatis 框架的全局配置文件,配置了 mybatis 框架运行的环境等信息。
Mapper1.xml..... 是 SQL 的映射文件,文件中配置了所有的操作数据库的 sql 语句, 在mybatis全局配置文件中去加载这些sql映射文件 。
2 、 通过mybatis环境等配置信息构建SqlSessionFactroy , 相当于是产生连接池
3 、 由会话工厂创建SqlSession即会话 (连接),操作数据库需要通过 SqlSession 进行的。
4 、 Mybatis 底层自定义了 Executor执行器 的接口操作数据库, Executor 接口有两个实现,一个基本的执行器,一个是缓存的执行器。
5 、 Mapped statement 也是 mybatis 框架一个底层的封装对象,他包装了 mybatis 配置信息以及 sql 映射信息。 Mapper.xml文件中的一个SQL语句对应一个Mapped statement对象 , sql 的 id 就是 Mapped statement 的 id 。
6 、 Mapped statement 对 SQL 执行输入参数的定义,输入参数包括 HashMap 、基本类型、 pojo, Executor通过Mapped statemen在执行SQL语句前进行输入映射即将输入java对象映射到sql语句中,执行完毕SQL之后,输出映射就是JDBC编码中的对preparedStatement 执行结果的定义。
 

7、Mybatis缓存
8、 缓存作用
缓存是一般的 ORM 框架都会提供的功能,目的就是 提升查询的效率和减少数据库的压力 。将经常查询的数据存在缓存(内存)中,用户查询该数据的时候不需要从磁盘(关系型数据库文件)上查询,而是 直接从缓存中查询,提高查询效率,解决高并发问题 。
MyBatis 也有一级缓存和二级缓存,并且预留了集成第三方缓存的接口/中间件,如果项目比较小,对缓存要求不高,可以使用一级二级缓存就足够了,对并发非常高的大型项目,一般选择第三方的缓存中间件
只有在查询的时候才会去缓存查找,增删改操作的还是数据库,并清空缓存。
9、 一级缓存:SqlSession级别的缓存,自动开启
10、 一级缓存工作原理
在操作数据库时需要构造 sqlSession 对象,在对象中有一个 ( 内存区域 ) 数据结构( HashMap )用于存储缓存数据。不同的 sqlSession 之间的缓存数据区域( HashMap )是互相不影响的。
一级缓存的 作用域 是同一个 SqlSession ,在同一个 sqlSession 中两次执行相同的 sql 语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率
当一个 sqlSession 结束后该 sqlSession 中的一级缓存也就不存在了。
Mybatis 默认开启一级缓存,存在内存中 ( 本地缓存 ) 不能被关闭,可以调用 clearCache() 来清空本地缓存,或者改变缓存的作用域。
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNDU0ODYz,size_16,color_FFFFFF,t_70

当用户发起第一次查询 team=1001 的时候,先去缓存中查找是否有 team=1001 的对象;如果没有,继续向数据库中发送查询语句,查询成功之后会将 teamId=1001 的结果存入缓存中;
当用户发起第 2 次查询 team=1001 的时候,先去缓存中查找是否有 team=1001 的对象,因为第一次查询成功之后已经存储到缓存中,此时可以直接从缓存中获取到该数据,意味着不需要再去向数据库发送查询语句。
如果 SqlSession 执行了 commit( 有增删改的操作 ) ,此时该 SqlSession 对应的缓存区域被整个清空,目的避免脏读。
前提: SqlSession 未关闭。
 

11、 二级缓存:Mapper级别的缓存
12、二级缓存工作原理

当多个SqlSession 去查询同一个 Mapper 的同一条 sql 语句(参数相同), 得到数据会存在二级缓存区域,多个 SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession的。同样的当增删改并提交后缓存也会被清空。
二级缓存是多个 SqlSession 共享的,其 作用域 是 mapper 的同一个 namespace 。
不同的 sqlSession 两次执行相同 namespace 下的 sql 语句参数相同即最终执行相同的 sql 语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。
Mybatis 默认没有开启二级缓存,需要在 setting 全局参数中配置开启二级缓存。
如果缓存中有数据就不用从数据库中获取,大大提高系统性能。
如果两个session不是从同一个Factory获取,那么二级缓存将不起作用。
二级缓存原理图:
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNDU0ODYz,size_16,color_FFFFFF,t_70

13、 缓存的属性配置
缓存中有哪些属性

1.映射语句文件中的所有select语句将会被缓存;
2.映射语句文件中的所有CUD操作将会刷新缓存;
3.缓存会默认使用LRU(Least Recently Used)算法来收回;
        3.1、LRU – 最近最少使用的:移除最长时间不被使用的对象。
        3.2、FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
        3.3、SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
        3.4、WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
4.缓存会根据指定的时间间隔来刷新(默认情况下没有刷新间隔,缓存仅仅调用语句时刷新);
5.缓存会存储列表集合或对象(无论查询方法返回什么),默认存储1024个对象。
6.缓存会被视为是read/write(可读/可写)的缓存,意味着检索对象不是共享的,而且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
 

 如果想在命名空间中共享相同的缓存配置和实例,可以使用cache-ref 元素来引用另外一个缓存

<cache-ref namespace="com.kkb.mapper.TeamMapper" />

// 引用 TeamMapper 命名空间中的 cache 。

简单答疑

1.Mybaits 的优点

1、基于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在 XML 里,解除 sql 与程序代码的耦合,便于统一管理;提供 XML 标签,支持编写动态 SQL 语句,并可重用。

2、与 JDBC 相比,减少了 50%以上的代码量,消除了 JDBC 大量冗余的代码,不需要手动开关连接;

3、很好的与各种数据库兼容(因为 MyBatis 使用 JDBC 来连接数据库,所以只要 JDBC 支持的数据库 MyBatis 都支持)。

4、能够与 Spring 很好的集成;

5、提供映射标签,支持对象与数据库的 ORM 字段关系映射;提供对象关系映射 标签,支持对象关系组件维护。
 

2.MyBatis 框架的缺点

1、SQL 语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写 SQL 语句的功底有一定要求。

2、SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

3.MyBatis 与 Hibernate 有哪些不同?

1、Mybatis 和 hibernate 不同,它不完全是一个 ORM 框架,因为 MyBatis 需要 程序员自己编写 Sql 语句。

2、Mybatis 直接编写原生态 sql,可以严格控制 sql 执行性能,灵活度高,非常 适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需 求变化要求迅速输出成果。但是灵活的前提是 mybatis 无法做到数据库无关性, 如果需要实现支持多种数据库的软件,则需要自定义多套 sql 映射文件,工作量大。

3、Hibernate 对象/关系映射能力强,数据库无关性好,对于关系模型要求高的 软件,如果用 hibernate 开发可以节省很多代码,提高效率。

4.MyBatis 框架适用场合

1、MyBatis 专注于 SQL 本身,是一个足够灵活的 DAO 层解决方案。

2、对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis 将是 不错的选择。

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

#{}是预编译处理(占位符),${}是字符串替换。

Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的 set 方法来赋值;

Mybatis 在处理 时,就是把 {}时,就是把 时,就是把{}替换成变量的值。

使用#{}可以有效的防止 SQL 注入,提高系统安全性。
 

6.如何执行批量插入?

通过在sqlsessionfactory.opensession(executortype.batch),在开启一个SqlSession时,加入一个开启批处理的参数:executortype.batch

7.Mybatis 动态 sql 有什么用?执行原理?有哪些动态 sql?

Mybatis 动态 sql 可以在 Xml 映射文件内,以标签的形式编写动态 sql,执行原理是:根据表达式的值来完成逻辑判断 + 动态拼接 sql 的功能。

Mybatis 提供了 9 种动态 sql 标签:trim | where | set | foreach | if | choose | when | otherwise | bind。

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

< resultMap> ,< parameterMap>, < sql>, < include>, < selectKey>, 加上动态 sql 的 9 个标签,其中为 sql 片段标签,通过 < include>标签引入 sql 片段,< selectKey>为不支持自增的主键生成策略标签。
 

9.Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?

不同的 Xml 映射文件,如果配置了 namespace,那么 id 可以重复;如果没有配 置 namespace,那么 id 不能重复;

原因就是 namespace+id 是作为 Map<String, MapperStatement>的 key 使用的,如果没有 namespace,就剩下 id,那么,id 重复会导致数据互相覆盖。 有了 namespace,自然 id 就可以重复,namespace 不同,namespace+id 自然也就不同。

10.MyBatis 实现一对一有几种方式?具体怎么操作的?

有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在 resultMap 里面配置 association 节点配置一对一的类就可以完成;

嵌套查询是先查一个表,根据这个表里面的结果的 外键 id,去再另外一个表里面 查询数据,也是通过 association 配置,但另外一个表的查询通过 select 属性配置。
 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值