连mybits工作原理都不懂,你敢说你自己会java?

云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!


一、相较于Hibernatemybatis的优势在哪里?

Hibernate缺点:

1、运行效率低,内存占用比较严重
2、针对单一对象的增删改查,适合Hibernate,而Hibernate在& ] i v ! z Z + N批量操作时处于弱势
3、虽然Hibernate引入一二级缓存、lazyload、查询缓存等更多优化空间(对于那些改动 不大且经常使用的数据,可将他们放入缓存中),但Hibernate对于持久层封装过于完 整,导致开发人员无法对sql进行优化,不适用于大型项目

myx 1 zbatis优m / r r i W ` :点:

1、代码量大大减少,开发效率b ( + i u % g X
2、 M B x z L X `yBatis相当灵活,SQL写在XML里,从程序代码中彻底分离,降低耦合度,便于统 一管理和优化,并可重用
3、运行效率高

二、mybatis原理

下面是mybatis的一个原理图,看懂这个图对理解mybatis工作原理很重要:

连mybits工作原理都不懂,你敢说你自己会java?

上面的原理图看的不是很清晰,下面再详细介绍一下mybatis的主X 0 S _ } m要成员:

1、Configuration

MyBatis所有的配置信息都保存在Confi7 B zguration对象之中,配置文件的大部分. O l F 9 配置都会存储到该类中

2、SqlSession

作为M% E - k u DyBatis工作的主要顶层API,表示和数据库交互时的会话,完成必要数据库增删改查功能

3、ExecutorMy

Batis执行器,是MyBatis 调度的核心o k ) Z e,负责SQL语句的生成和% s 8 S 4查询缓存的维! S . 7 c

StatementHandler 封装了JDBC Statement操作,负责对JDBC statement 的操作,. E i % I t u如设置参数等

4、ParameterHandler

负责对用户传递的参数转换成JDBC Statement 所对应的数据类型

5、Resuh . b qltSetHandler

负责将JDBC返回的ResultSet结果集对象转换成List类型的集合

6、TypeHand[ ` * &ler

负责java数据类型和jdbc数据类型(也可以说是数据表列类型)之间的映射和转换

7、MappedStatement

MappedStatement维护一条节点的封装

8、SqlSource

负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回

9、BoundSql

表示动态生成的SQL语句以及相应4 z w t ? _ .的参数信息

下面介绍一下mybatis的工作流程:

首先,mybatis的增删改查这些数据库操作都是基于sqlsession类的U g O,SqlSession又是由SqlSessionFactory类创建出来K e s o的(这里采用了java设计模式中的工厂模式),而SqlSessionFactory是由Sg V I @ Z oqlSessionFactoryBuilder创建的,SqlSessionFac@ : S 6 a i 0 2 RtoryBuilder要想创建SqlSessionFa- = o J & lctory,必须要有原料(即mybatis配置文N , [ + 3 (件),下面是创建Sqo J c $ Q + `lSesn & y 3 x 5 4 Msion的代码:

//加载classpath路径下的mybatis配置文件H H N a ( X @ E TInputStream in=Resources.getResourc6 t v G ? S / UeAsStream("mybatis-config.xml");Q E / _ x//根据加载配置文件产生的输入流,来创建一个SqlSessionFactn W 8 _ w C P 0orySqlSessionFactory sessionFactory = new SqlSessionFx V 0 d G u eactoryBG y * - ouilder% ) G k ` i :().build(in);//根据SqlSe~ y Z N n  / 3 9ssionFactoryX R P创建SqlSessionSqlSession session = sessionFactory.openSession();

下面介绍这几个重要对象的作用域和生命周期

1、SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。你可以重用 SqlSessionFJ , u T ` d ]actoryBum ~ Y ] q F )ilder 来创建多个 SqlSe| 2 mssionFactory 实例,但是最好还是不K M U要让其一直存在以保证所有的 XML 解析资源开放z e e M @ `给更重要的事3 @ - d 5 r 3 y情。

2、SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运* N 5 % X Y ! r行期间一直存在,没有任何理由对它进行清除或重建。使用 SqlSessiov 5 7 u t ? | ,nFactory 的最佳实践是在应用运行期间不要重复创建多次。因此 SqlSessionFactory 的最佳作用域是应用X / , l N [ b C作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式

3、S3 1 D ; y sqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或N Y l f &方法作用域。绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。sqlSq r 0 [ G _ 2 F Zession在每次用完之后必须关闭它

三、mybatis缓存机制

1、一级缓存

MyBati_ E $ y - Rs一级缓存是基于sqlSession的,sqlSession对象有一个HashMap用于存储缓存数据,此HashMap是当前会话对象_ : j私有的,别的SqlSession会话对^ ! p象无法访问。一级缓存默认是开启的,且无法关闭。增删改操作会清空当前sqlSession里的缓存

2、二级缓存

MyBatis二级缓存是mapper级别的缓存,同一个namespace共用这一个缓存,所以对SqlSession是共享的,二级; z u } 0 p % F缓存是默认关闭的。

如何配置二级缓存?只需要在sql映射文件中添加即可

测试代码:

/* * 注意:被缓存的数据要实现序列化接- r 1口(在这里将Book.java实现序列化+ R ` d h m接口),否则会出现异常 * 另外,当某一个sqlSession修改了共享的缓存数据之后,二级缓存也会清空 */b V # Z j [ 3 i }SqlSession session_1 = Myi g _ P v L k |BatisUtil.ge} s w z 4tSessionw z O V I D();BookDao mapper_1 = session_1.getMapper(BookDao.class);mapper_1.listBook();//注意,必须提交才能将数据放进二级缓存session_1.commit();        SqlSession session_2 = MyBatisUtil.getSession();BookDao mapper_2 = session_2.getMapper(BookDao.class);mapper_2.li% ; v mstBook();

这里只是为了测试二级缓存的原理,所以MyBatisUtil类如何获取SqlSession的代码就没有粘贴进来了。

连mybits工作原理都不懂,你敢说你自己会java?

运行上面的代码,通过log4j打印出来的日志可以看到2 n S V y ! :,,明明运行了两次listBook方法,但最终查询语句(select * from book)只出现一次,这次因为第二次查询命中了缓存,就不需要再查数据J d @ 2库了。

【云栖号在线课堂】每天都有产S n i Y h品技术专家分享!
课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-07-06
本文作者:程序员麦冬
本文来自:“掘金”,了解相关信息可以关注“XXXX”