更新时间:2021年03月18日 08时58分22秒 来源:黑马程序员论坛
MyBatis工作原理 一、工作原理原型图(使用visio工具绘制) 二、工作原理分析 mybatis应用程序通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件(也可以用Java文件配置的方式,需 要添加@Configuration)中构建出SqlSessionFactory(SqlSessionFactory是线程安全的);然后, SqlSessionFactory的实例直接开启一个SqlSession,再通过SqlSession实例获得Mapper对象并运行Mapper映射的 SQL语句,完成对数据库的CRUD和事务提交,之后关闭SqlSession。说明:SqlSession是单线程对象,因为它是非 线程安全的,是持久化操作的独享对象,类似jdbc中的Connection,底层就封装了jdbc连接。 三、 详细流程说明 1、加载mybatis全局配置文件(数据源、mapper映射文件等),解析配置文件,MyBatis基于XML配置文件生成 Configuration,和一个个MappedStatement(包括了参数映射配置、动态SQL语句、结果映射配置),其对应着 <select | update | delete | insert>标签项。 2、SqlSessionFactoryBuilder通过Configuration对象生成SqlSessionFactory,用来开启SqlSession。 3、SqlSession对象完成和数据库的交互: a、用户程序调用mybatis接口层api(即Mapper接口中的方法) b、SqlSession通过调用api的Statement ID找到对应的MappedStatement对象 c、通过Executor(负责动态SQL的生成和查询缓存的维护)将MappedStatement对象进行解析,sql参数转化、动 态sql拼接,生成jdbc Statement对象 d、JDBC执行sql。 e、借助MappedStatement中的结果映射关系,将返回结果转化成HashMap、JavaBean等存储结构并返回。 四、mybatis层次图 五、mybatis缓存详解 mybatis的缓存分为两级:一级缓存、二级缓存 一级缓存是SqlSession级别的缓存,缓存的数据只在SqlSession内有效 二级缓存是mapper级别的缓存,同一个namespace公用这一个缓存,所以对SqlSession是共享的。 1、一级缓存 mybatis的一级缓存是SqlSession级别的缓存,在操作数据库的时候需要先创建SqlSession会话对象,在对象中 有一个HashMap用于存储缓存数据,此HashMap是当前会话对象私有的,别的SqlSession会话对象无法访问。 具体流程: 1.第一次执行select完毕会将查到的数据写入SqlSession内的HashMap中缓存起来。 2.第二次执行select会从缓存中查数据,如果select相同切传参数一样,那么就能从缓存中返回数据,不用去数 据库了,从而提高了效率。 注意事项: 1.如果SqlSession执行了DML操作(insert、update、delete),并commit了,那么mybatis就会清空当前 SqlSession缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现脏读 2.当一个SqlSession结束后那么他里面的一级缓存也就不存在了,mybatis默认是开启一级缓存,不需要配置 3.mybatis的缓存是基于[namespace:sql语句:参数]来进行缓存的,意思就是,SqlSession的HashMap存储缓存 数据时,是使用[namespace:sql:参数]作为key,查询返回的语句作为value保存的。 2、二级缓存 二级缓存是mapper级别的缓存,也就是同一个namespace的mappe.xml,当多个SqlSession使用同一个 Mapper操作数据库的时候,得到的数据会缓存在同一个二级缓存区域 二级缓存默认是没有开启的。需要在setting全局参数中配置开启二级缓存. 若想禁用当前select语句的二级缓存,添加useCache="false"修改如下: 具体流程: 1.当一个sqlseesion执行了一次select后,在关闭此session的时候,会将查询结果缓存到二级缓存 <!--如果是mybatis配置文件,做以下配置--> <settings> <!--默认是false:关闭二级缓存--> <setting name="cacheEnabled" value="true"/> <settings <!--当前mapper下所有语句开启二级缓存--> <!--这里配置了一个LRU缓存,并每隔60秒刷新,最大存储512个对象,而却返回的对象是只读的--> <cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/> <select id="getCountByName" parameterType="java.util.Map" resultType="INTEGER" statementType="CALLABLE" useCache="false"> 2.当另一个sqlsession执行select时,首先会在他自己的一级缓存中找,如果没找到,就回去二级缓存中找,找 到了就返回,就不用去数据库了,从而减少了数据库压力提高了性能 注意事项: 1.如果SqlSession执行了DML操作(insert、update、delete),并commit了,那么mybatis就会清空当前 mapper缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现脏读 2.mybatis的缓存是基于[namespace:sql语句:参数]来进行缓存的,意思就是,SqlSession的HashMap存储缓存 数据时,是使用[namespace:sql:参数]作为key,查询返回的语句作为value保存的。 3、总结 MyBatis的二级缓存相对于一级缓存来说,实现了SqlSession之间缓存数据的共享,同时粒度更加的细,能够到 namespace级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。 MyBatis在多表查询时,极大可 能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。 在分布式环境下,由于默认的MyBatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使 用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis,Memcached等分布式缓存可能成本 更低,安全性也更高。 六、MySQL常用存储引擎 注: 查询方式: 方式1:show variables like '%storage_engine%'; 方式2:show engines; 修改方式: 方式1:修改my.cnf,在配置文件里面增加参数default-storage-engine,然后重启数据库服务。 [mysqld] default-storage-engine=MyISAM 方式2:临时修改,服务重启后将会恢复。 set default-storage-engine=MyISAM 1、MyISAM MySQL默认数据库引擎,不支持事务、外键,速度快,用于无事务要求或者select、insert为主的场景。 会创建3个文件.frm(存储表定义),.MYD(MYData,存储数据),.MYI(MYIndex,存储引擎)。 支持3中存储格式,静态(固定长度)表,动态表,压缩表。 静态表是默认格式,固定长度速度快,但是占空间大。记录长度不够时会用空格填充,读取数据时会清除 空格,存在吃尾部空格的情况。 动态表包含变长字段,记录不是固定长度,占用空间少,但是频繁更新和删除会产生随便,需要定期整 理,并且在出现故障时恢复比较困难。 压缩表由mysiampack工具创建,空间小。 2、InnoDB 提供了具有提交、回滚、崩溃恢复能力的事务安全,但是会占用更多空间用以保存数据和索引。 支持外键,创建外键的时候,要求父表必须有对应的碎银,子表在创建索引的时候也会自动创建对应的索引。 存储表和索引有两种方式, 使用共享表空间存储,表结构保存在.frm文件中,数据和索引在innodb_data_home_dir和 innodb_data_file_path定义的表空间中,可以是多个文件。 使用多表空间存储,表结构保存在.frm文件中,每个表的数据和索引单独保存在.ibd中。 3、MEMORY 使用存在于内存中的内容来创建表,访问速度快,默认使用HASH索引,服务关闭数据会丢失。 用于内容变化不频繁的代码表,或者作为统计操作的中间结果表。 MERGE: 一组MyISAM表的组合,这些表必须结构完全相同。 MERGE表本身没有数据,CRUD时其实操作的是内部的MyISAM表。 Drop只是删除MERGE的定义,对于内部表没有影响。 |
推荐了解热门学科
java培训 | Python人工智能 | Web前端培训 | PHP培训 |
区块链培训 | 影视制作培训 | C++培训 | 产品经理培训 |
UI设计培训 | 新媒体培训 | 产品经理培训 | Linux运维 |
大数据培训 | 智能机器人软件开发 |
传智播客是一家致力于培养高素质软件开发人才的科技公司,“黑马程序员”是传智播客旗下高端IT教育品牌。自“黑马程序员”成立以来,教学研发团队一直致力于打造精品课程资源,不断在产、学、研3个层面创新自己的执教理念与教学方针,并集中“黑马程序员”的优势力量,针对性地出版了计算机系列教材50多册,制作教学视频数+套,发表各类技术文章数百篇。
传智播客从未停止思考
传智播客副总裁毕向东在2019IT培训行业变革大会提到,“传智播客意识到企业的用人需求已经从初级程序员升级到中高级程序员,具备多领域、多行业项目经验的人才成为企业用人的首选。”
中级程序员和初级程序员的差别在哪里?
项目经验。毕向东表示,“中级程序员和初级程序员最大的差别在于中级程序员比初级程序员多了三四年的工作经验,从而多出了更多的项目经验。“为此,传智播客研究院引进曾在知名IT企业如阿里、IBM就职的高级技术专家,集中研发面向中高级程序员的课程,用以满足企业用人需求,尽快补全IT行业所需的人才缺口。
何为中高级程序员课程?
传智播客进行了定义。中高级程序员课程,是在当前主流的初级程序员课程的基础上,增加多领域多行业的含金量项目,从技术的广度和深度上进行拓展。“我们希望用5年的时间,打造上百个高含金量的项目,覆盖主流的32个行业。”传智播客课程研发总监于洋表示。
黑马程序员热门视频教程【点击播放】
Python入门教程完整版(懂中文就能学会) | 零起点打开Java世界的大门 |
C++| 匠心之作 从0到1入门学编程 | PHP|零基础入门开发者编程核心技术 |
Web前端入门教程_Web前端html+css+JavaScript | 软件测试入门到精通 |