| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> mybatis总结 -> 正文阅读 |
|
[Java知识库]mybatis总结 |
推荐一个介绍mybatis的:https://blog.csdn.net/zwx900102/category_8934270.html 学习了自己做个总结 一:流程
第一步:加载创建sqlSessionFactorySqlSessionFactoryBuilder是一个创建sqlSessionFactory的类,采用了构造器模式的,这个类职责很简单,就是new 出sqlSessionFactory,内部有多个build方法,所以这个类生命周期很短。 ?build方法核心在于parser.parse()方法,这个方法会去解析配置文件,解析mapper接口,xml文件,关联mapper与xml,解析sql,保存Configuration中。 所以加载这一步是在spring启动的时候就加载起来的。 第二步,获取SqlSession从sqlSessionFactory中获取SqlSession,sqlSessionFactory采用了工厂模式,sqlSessionFactory有多个openSession方法,根据入参不同来区别。 ?sqlSessionFactory#openSession方法核心是会根据configuration获取一个executor对象, executor对象就是后面真正执行sql的对象。 第三步 获取mapper在第一步加载的时候,mybatis会把加载好的所有mapper和方法保存在Configuration中,所以 EmailMapper emailMapper = sqlSession.getMapper(EmailMapper.class); 是在Configuration中get出来的 ?第四步:执行SQL4.1 寻找SQL通过MapperMethodInvoker代理模式构造了一个MapperMethod对象,MapperMethod会有执行的SQL,入参,返回结果集等信息 4.2执行SQL前面说到sqlSession会有一个executor对象,executor是真正执行SQL流程的对象,具体知识可以看:【MyBatis系列7】原来SqlSession只是个甩手掌柜,真正干活的却是Executor等四大对象_zwx900102的博客-CSDN博客 executor总结:解析SQL,拼装入参,最终转换成PreparedStatement,去执行JDBC的execute方法,返回结果集,再解析结果集转成dto对象映射。所以底层还是用java的jdbc执行。 当然怎么转成PreparedStatement,怎么映射结果集,具体还是很复杂的。 二:mybatis的缓存具体解析请看:??????【MyBatis系列8】给我五分钟,带你彻底掌握MyBatis的缓存工作原理_zwx900102的博客-CSDN博客 我这只是做简单的总结,方便自己理解。 看源码首先,从结构来看,缓存的核心是Cache接口,decorators包下面的类都是实现了Cache接口的,但同时每一种Cache类中都定义了Cache delegate对象: private final Cache delegate 其实这里用到了设计模式中的装饰器模式,实际Cache的实现类只有一个PerpetualCache PerpetualCache实际是用了一个map来做缓存。 一级缓存一级缓存也叫本地缓存,在MyBatis中,一级缓存是在会话(SqlSession)层面实现的,这就说明一级缓存作用范围只能在同一个SqlSession中,跨SqlSession是无效的。 MyBatis中一级缓存是默认开启的,不需要任何配置。 一级缓存只对同一个SqlSession有效。 一级缓存原理既然一级缓存是sqlsession的,我们来看sqlSession的源码,sqlSession只有这5个对象,看前面两个: Configuration是全局的,Configuration类里只有关于mapper和xml,结果集等信息,没有关于缓存的信息,所以跳过。 Executor,前面说过Executor是实际去执行SQL的地方,所以缓存也是放在这最合适的 ?这里用到了Cache的实际实现类,所以我们才说一级缓存是sqlsession(一个会话)层面的。 具体使用缓存,大概无非就是执行查询前判断下缓存(CacheKey)有没有,有就用,没有则执行查询SQL,并缓存结果, 一级缓存什么时候会被清除1、就是获取缓存之前会先进行判断用户是否配置了flushCache=true属性(参考一级缓存的创建代码截图),如果配置了则会清除一级缓存。 二级缓存二级缓存目的就是要实现作用范围更广,那肯定是要实现跨会话共享的,在MyBatis中二级缓存的作用域是namespace,也就是作用范围是同一个命名空间 在MyBatis中为了实现二级缓存,专门用了一个Executor的装饰器来维护:CachingExecutor
二级缓存需要开启吗既然一级缓存默认是开启的,而二级缓存是需要我们手动开启的,那么我们什么时候应该开启二级缓存呢? 1、因为所有的update操作(insert,delete,uptede)都会触发缓存的刷新,从而导致二级缓存失效,所以二级缓存适合在读多写少的场景中开启。 2、因为二级缓存针对的是同一个namespace,所以建议是在单表操作的Mapper中使用,或者是在相关表的Mapper文件中共享同一个缓存。 自定义缓存mybatis支持自定义使用第三方作为缓存,比如redis等。 三 mybatis的日志mybatis支持6种日志:SLF4J,LOG4J,LOG4J2,JDK_LOGGING,COMMONS_LOGGING,STDOUT_LOGGING,NO_LOGGING。 采用的设计模式是适配器模式 ? 在Configuration类中,可以看到有注册所有类型的日志,然后再setLogImpl中用LogFactory来创建日志对应的适配器,LogFactory静态初始化了所有的类型 ? ?setImplementation()方法适配指定的日志类型。 四 mybatis分页插件在MyBatis中插件式通过拦截器来实现的,真正执行Sql的是四大对象:Executor,StatementHandler,ParameterHandler,ResultSetHandler。而MyBatis的插件正是基于拦截这四大对象来实现的。需要注意的是,虽然我们可以拦截这四大对象,但是并不是这四大对象中的所有方法都能被拦截,下面就是官网提供的可拦截的对象和方法汇总: mybatis拦截器插件源码解析?在SqlSessionFactory build的时候解析配置文件,这里有个解析插件的?,
可以看到?InterceptorChain是Configuration一个属性,InterceptorChain内部其实是一个List,就是说如果我们实现了多个拦截器,Mybatis是遍历list执行所有的拦截器的。 ? ?注意: interceptor.plugin(target)这个方法里,其实是wrap()方法,这个方法最底层这里有用到动态代理哦,所以mybatis的插件是通过拦截器使用代理模式工作的。 ?PageHelper分页插件也是用到拦截器,在执行sql前拦截并setPage,注意,这里有用到线程本地变量。 为什么PageHelper只对startPage后的第一条select语句有效在finally内把ThreadLocal中的分页数据给清除掉了,所以只要执行一次查询语句就会清除分页信息,故而后面的select语句自然就无效了。 ? 五? mybatis中的设计模式?学习mybatis源码还能学习设计模式:构造模式,工厂模式,代理模式 缓存中用到的模式:装饰器模式 日志用到的模式:适配器模式,工厂模式 插件(分页插件)用到模式:拦截器(aop),动态代理模式 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 6:02:52- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |