MyBatis 3源码分析

mybatis 3.x源码深度解析与最佳实践.html redis设计与实现解读,解析SDSss 立即下载
Mybatis3.2源码分析:
一、加载配置文件。
    使用SAX解析配置文件。读取xml配置文件后,调用XMLConfigBuilder.parse()方法,在parse方法中再调用parseConfiguration()方法,对读取到的配置信息保存到BaseBuilder.configuration中。
     propertiesElement(root.evalNode("properties")); //issue #117 read properties first    
        代码分析:此方法实现将属性信息存入Configuration中。
            1、如果properties节点不为空,查找配置节点中子节点的属性文件并赋值给defaults(Properties类型,继承自HashTable,线程安全的,HashTable集成Dictionary,实现Map接口),否则此方法结束。
            2、查询resource和url,注意两者不能同时配置,否则会抛出异常,最后将resource或url的属性putAll 进入 defaults中,
            3、将defaults变量存入Configuration中去。

      typeAliasesElement(root.evalNode("typeAliases"));
        代码分析:此方法实现将Bean的别名保存在BaseBuilder.typeAliasRegistry中,如果别名为空,则存Bean的SimpleName。
           
      pluginElement(root.evalNode("plugins"));
        代码分析:此方法将插件信息存入configuration中,可以配置属性。configuration.interceptors

      objectFactoryElement(root.evalNode("objectFactory"));
        代码分析:对象工厂,如果为空则默认使用DefaultObjectFactory工厂。configuration.objectFactory
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
         代码分析:对象包装工厂,如果为空则默认使用DefaultObjectWrapperFactory。configuration.objectWrapperFactory
      settingsElement(root.evalNode("settings"));
         代码分析:先获取settings节点子节点properties属性解析到Properties props中,检查是否由不存在的setter方法,有则抛出异常。没有问题则将pros的值赋值到configuration中去,如果pros中的值为空,则设置一个默认值。
                           详细如下:
                                    configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL")));
      configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true));
      configuration.setProxyFactory((ProxyFactory) createInstance(props.getProperty("proxyFactory")));
      configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), false));
      configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), true));
      configuration.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true));
      configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true));
      configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false));
      configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE")));
      configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null));
      configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false));
      configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false));
      configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION")));
      configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER")));
      configuration.setLazyLoadTriggerMethods(stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString"));
      configuration.setSafeResultHandlerEnabled(booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true));
      configuration.setDefaultScriptingLanguage(resolveClass(props.getProperty("defaultScriptingLanguage")));
      configuration.setCallSettersOnNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), false));
      configuration.setLogPrefix(props.getProperty("logPrefix"));
      configuration.setLogImpl(resolveClass(props.getProperty("logImpl")));
      configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory")));
      environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631
         代码分析:设置运行环境。如果为空,默认使用default。如果设置指定的环境id,则设置事务工厂,设置数据源。并build环境。id,transactionFactory,dataSource都不允许为空。configuration.setEnvironment
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
         代码分析:获取数据库产品的名称。dataSource为空会抛出异常。注:如果使用多个数据源就需要采用多个SqlSessionFactory的配置,为不同的调用使用不同的SqlSessionFactory,在mybatis中自己是无法实现的,需要使用spring托管数据源方可。
      typeHandlerElement(root.evalNode("typeHandlers"));
         代码分析:自定义数据类型转换。提供javaType和jdbcType的映射。BaseBuilder.typeHandlerRegistry。
      mapperElement(root.evalNode("mappers"));
        代码分析:如果子节点是package,获取package的name。调用configuration.addMappers(mapperPackage);这个方法的内部调用mapperRegistry.addMappers(packageName);在这个方法中根据包名搜索下面的类并添加到knownMappers中,knownMappers是在MapperRegistry中定义的一个final map。mapper.resource使用xml资源文件。mapper.url可以使用绝对地址,理论上讲可以从网络上直接调用地址,可以在远程服务器上传一个xml拿下来解析。mapper.class使用注解方式的时候使用这种方式。
        resource和url两种配置方式都调用了XMLMapperBuilder.parse()方法,解析加载到的mapper文件,调用mapperRegistry.addMapper(Class<T> type)方法。然后移除挂起的ResultMap,挂起的缓存引用,挂起的Statement。
        通过configuration都可以获取这些mapper信息。
    
        在mapperParser.parse().configurationElement():
            
            private void configurationElement(XNode context) {
    try {
      String namespace = context.getStringAttribute("namespace");
      if (namespace.equals("")) {
       throw new BuilderException("Mapper's namespace cannot be empty");
      }
      builderAssistant.setCurrentNamespace(namespace);
      cacheRefElement(context.evalNode("cache-ref"));
      cacheElement(context.evalNode("cache"));
      parameterMapElement(context.evalNodes("/mapper/parameterMap"));
      resultMapElements(context.evalNodes("/mapper/resultMap"));
      sqlElement(context.evalNodes("/mapper/sql"));
      buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing Mapper XML. Cause: " + e, e);
    }
  }
            在这里解析了mapper文件,将
二、创建SqlSessionFactory。
        在第一步加载配置问价您的时候创建了一个configuration对象,将这个对象传入SqlSessionFactoryBuilder,创建一个DefaultSqlSessionFactory的工厂对象。

三、创建SqlSession:
        SqlSession由SqlSessionFactory创建,SqlSessionFactory提供了8种openSession多态方法,不带参数的自动提交为false,SqlSessionFactory还提供一个获取configuration的方法,调用openSession方法获取到一个DefaultSqlSession。

四、获取到Mapper代理:
        使用SqlSession.getMapper(XXXMapper.class)获取代理类,实际获取位置是MapperRegistry.knownMappers。获取到指定接口的MapperProxyFactory,然后MapperProxyFactory.newInstance(sqlSession);(这里使用了动态代理)这样就生成了一个XXXMapper的代理类,返回。
        
五、接口方法调用:
        当调用接口方法的时候,实际上调用的MapperProxy这个类的实例对象中的invoke方法,在invoke方法中使用了方法缓存,最后调用mapperMethod.execute方法。
        下面分析SqlSession.selectOne():这个方法最终会调用到:public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds),其中的executor根据是否开启缓存来选择,如果开启缓存:则使用CacheingExecutor.query,如果没有再调用BaseExecutor.query查询结果,并将查询出来的结果存放到CachingExecutor中的tcm(TransactionalCacheManager)对象中,TransactionalCacheManager内部使用了HashMap存储缓存和事务缓存。接着我们看BaseExecutor.query的调用,
它最终调用到:
        private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql);
        BaseExecutor : protected abstract <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql);
        SimpleExecutor : public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException;
        经过一系列中转,最终调用到jdbc预编译,和执行,之后按照要求组装查询到的数据。
            
六、在Mybatis中使用了的设计模式:
1、动态代理,最典型的是通过动态代理委托MapperProxy执行相关数据操作。
2、装饰器模式:开启缓存的时候,Caching包装了SimpleExecutor;对象工厂装饰器objectFactoryWrapper。
3、工厂模式:SqlSessionFactory的使用,还有MapperProxyFactory。
4、构造器模式:构建Configuration对象的步骤。
使用Mybatis相关:
5、SqlSessionFactory无需重复创建,在使用时应该使用单例模式调用。


mybatis-3.4.4(包含源码,中文帮助文档PDF,JAR包)[超清晰版] 文档是Mybatis在github上的官方中文教程文档,很详细的讲解的mybatis的用法。pdf文档是文字版可复制,是我通过工具将官方的中文文档转化为pdf的,如果好用的话,希望大家给个好的评论(好资源就是要分享) 立即下载

相关推荐

mybatis 3.x源码深度解析与最佳实践1.html.zip

还不错的MyBatis源码分析资料,对学习MyBatis有不错的帮助,可以参考学习,不懂的可以交流哈 V:study_51ctofx

mybatis百度云盘分享

链接:https://pan.baidu.com/s/1VpzbSHjb-csCfKv9thL-mg 提取码:g42z 下载地址:https://github.com/mybatis/mybatis-3/releases

m0_67390788的博客 615

深入浅出MyBatis技术原理与实战.pdf 高清

《深入浅出MyBatis技术原理与实战》不是一本味同嚼蜡的理论专著,而是一本MyBatis 的实践指南,无论你是Java 程序员、MyBatis开发者,还是Java 持久层框架的研究者,你都能从本书中收获知识。

Mybatis3源码全解析

Mybatis架构: 图自:MyBatis整体架构_tiankong_12345的博客-优快云博客_mybatis架构 Mybatis架构分三层: 第一层:SqlSession 这是使用mybatis的主要接口,通过这个接口我们可以执行命令,获取mapper或者管理事务。 Through this interface you can execute commands, get mappers and manage transactions. 第二层:核心处理层 配置解析模块:myb

MieMieFly的专栏 1318

DeepSpeed Zero3 Offload实战:从GCC版本检查到环境配置的完整避坑指南

本文是一份针对DeepSpeed Zero3 Offload部署的完整避坑指南。针对训练中常见的`AttributeError: ‘DeepSpeedCPUAdam‘ object has no attribute ‘ds_opt_adam`报错,文章深入剖析了其根源在于GCC编译器版本过低。指南提供了从系统GCC版本深度探查、安全启用高版本GCC环境,到DeepSpeed一致性安装验证的全链路实战方案,旨在帮助用户构建稳定的大模型训练环境。

weixin_29070721的博客 474

机械臂 关节电机选型计算

电机 机械臂

hisen92的专栏 8984

Mybatis3源码分析(1)生命周期与核心配置解读以及批量操作

单独用mybatis编程式进行DB操作 --------------------利用mapper String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new Sq...

yakax的博客 249

MyBatis3-源码剖析

MyBatis3-源码剖析

冰点契约的博客 517

什么是 SAP Fiori 的 Technical Catalog

笔者之前的文章曾经提到一个叫做本文介绍 Technical Catalog 这个概念在 SAP Fiori 技术体系中的作用。首先我们如何在系统里查看这个 Catalog SAP_BASIS_TCR_T 里面包含的内容呢?如果大家照着本文开头那篇文章里提到的步骤,那么在自己系统里会创建好名叫的 PFCG role.我们登录 ABAP 系统,启动事务码 PFCG,打开这个 role, 就能看到它。展开之后,发现它扮演着一个容器的角色,里面包含了很多 ABAP 对象。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 744

YOLO11改进|注意力机制篇|引入MLCA轻量级注意力机制

YOLO11中添加MLCA轻量级注意力机制

A1983Z的博客 4064

GitHub上标星2.9w+,20年IT老码农整理分享内部绝密MyBatis源码深度解析文档,直接涨薪20K~

前言 MyBatis作为持久层框架,以其小巧轻便、SQL可配置、使用简单等特点深受广大Java开发者喜爱。 然而大多数开发人员对MyBatis框架的理解仅局限于使用,并不理解框架底层的实现原理。作为一名开发人员,阅读开源框架的源码,可以学习源码中对设计模式及面向对象设计原则的应用,有助于提升自身编码能力。笔者在工作之余,深入研究了MyBatis框架的源码,本文将会从源码的角度分析MyBatis框架各个特性的实现原理。 本文特征: 追本溯源︰从MyBatis的基本应用出发,挖掘底层实现,深入理解MyB

程序员高级码农 1414

Flink Web UI 如何使用和调试保姆级教程(持续更新)

Running Jobs(运行中的作业):显示正在运行的所有 Flink 作业的列表。每个作业都有一个独特的 Job ID,可以点击进入查看作业的详细信息。Completed Jobs(已完成的作业):显示已经完成或取消的作业列表。:显示当前集群中所有 TaskManager 的健康状态,包括 CPU 使用率、内存使用情况、Slot 数量等。Job Manager Configuration(JobManager 配置):显示 JobManager 的一些配置参数,帮助调试和优化 Flink 集群。

大模型大数据攻城狮的专栏 3993

Mybatis3源码分析(01)-前期准备

Mybatis3源码分析(01)-前期准备

weixin_33695082的博客 95

YOLOv11 改进策略之 Conv 篇:基于 C2fC 与 RepC_SPELAN4 的性能跃迁教程

某工业质检场景中,采用本文改进模块的 YOLOv11 模型,对微小零件缺陷的检测准确率提升 22%;YOLOv10 提出的 C2fC 模块与 RepC_SPELAN4 结构,是针对特征融合与卷积效率的突破性设计,掌握它们,你就能让自己的 YOLOv11 模型在精度与速度的平衡上实现“质的飞跃”。别再让“模型精度不足”成为你的瓶颈——现在就动手修改代码,让你的 YOLOv11 模型在特征提取与检测效率上实现质的飞跃,用技术实力证明你的 AI 研发能力!中的卷积层为 RepC_SPELAN4。

m0_71589036的博客 99

[QMT量化交易小白入门]-三十七、QMT中如何使用类似于通达信中的VBA函数(量化python代码解析)

这段代码主要围绕着在QMT环境中实现类似通达信VBA函数的功能展开,核心功能是基于RSI指标来判断股票的买卖时机,并根据持仓情况进行相应的交易操作。class G():passg = G()这里定义了一个空类G,并创建了该类的实例g。这个实例g将作为全局变量来存储一些在整个程序运行过程中需要共享的数据,例如除复权类型、股票代码、目标数量等。1、使用VBA开发策略时,参数固化的问题会带来一些限制,比如无法修改MA函数的周期参数,只能使用固定周期。

木头大左的博客 1702

mybatis3.4.6 源码分析笔记

官网配置教程: http://www.mybatis.org/mybatis-3/ 源码下载: 常用使用说明 使用mybatis集成pom配置 使用我的练习项目;第一次自己搭maven 可以在一个maven工程里放子工程,这个方式还挺好的;两个子项目可以共用父项目的pom配置 &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;dependencies&amp;amp;amp;a

神武舞 1158

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Mybatis3.5.4源码分析-3- 获取mapper,反射调用查询

BlogMapper mapper = session.getMapper(BlogMapper.class); mybatis中,通过session.getMapper来获取mapper接口的实现类,同样的,ctrl+alt+B 进入这个方法的默认实现 org.apache.ibatis.session.defaults.DefaultSqlSession#getMapper 中: @Override public <T> T getMapper(Class<T> t.

weixin_41300437的博客 1592

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

mybatis3源码分析

1.原生JDBC查询 编写sql–》预编译sql–》参数设置–》执行sql–》结果封装 2.半自动框架 与Hibernate不同,Hibernate是全自动映射框架,目的是消除sql,但是消除sql的同时,Hibernate又失去了灵活性和sql优化空间,尽管提出了一个HQL概念,但是又增加了学习成本。所以,mybatis在这种背景下发展起来的,mybatis选择不封装sql编写操作(mapper.xml文件),封装其他JDBC操作,追求的是封装性,又不失sql灵活性。 3.mybatis前言 与所有框架

weixin_39296289的博客 411

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Mybatis 源码分析3

cursor (1)Cursor 指针接口 isOpen 指针是否打开 isConsumed 是否被消费 getCurrenIndex 获取当前索引 cursor.default (1)DefaultCurcor mybatis 的 Cursor 接口的默认实现 这个实现不是线程安全 datasource (1)DataSourceException 数据源异常封装类...

时光钟摆 578

Mybatis3源码分析(3)流程走向

分析源码我们还是从编程式demo入手 我们通过建造者模式创建一个工厂类,配置文件的解析就是在这一步完成的,包括 mybatis-config.xml 和 Mapper 适配器文件。 首先进入build 进入XMLconfigBuilder–这里就是配置文件创建的地方 可以看到这里有很多解析文件的类 解析节点–这里可以看出文件只解析了一次。 解析文件还是比较简单的,基本上就是读取文...

yakax的博客 220

【mybatis3】MyBatis源码分析

MyBatis源码分析

wufaqidong1的博客 328

【mybatis源码】3、插件源码分析

请先看: mybatis源码分析:https://blog.youkuaiyun.com/hancoder/article/details/110152732 Mybatis允许我们在四大对象执行的过程中对其指定方法进行拦截,这样就可以很方便了进行功能的增强,这个功能跟Spring的切面编程非常类似。 文章目录helloworld预热jdbcmybatis四大对象插件原理插件的代理来源代理执行器①getSignatureMap(interceptor)②getAllInterfaces③Proxy.newProxyIn

努力充实,远方可期 455

MyBatis源码分析(3)

解析select\insert\ update\delete标签中的SQL语句,最终将解析到的SqlNode封装到MixedSqlNode中的List集合中。SimpleExecutor:简单执行器,每执行一条 sql,都会打开一个 Statement,执行完成后关闭;BaseExecutor:基础执行器,封装了子类的公共方法,包括一级缓存、延迟加载、回滚、关闭等功能;功能,并且在当前 sql 和上一条 sql 完全一样的时候,重用 Statement,在调用。问题:sql占位符如何进行的替换?

u010156553的博客 146

Mybatis3源码分析(12)-Sql解析执行-MetaObject

MetaObject MetaObject类相当于一个工具类,Mybatis在sql参数设置和结果集映射里经常使用到这个对象。下面来详细分析一下这类。 这个类有四个属性,其中两个基本不用看。 //原始的对象 private Object originalObject; //对原始对象的一个包装 private ObjectWrapper objectWrapper;

ashan 4400
上一篇: Java动态代理实现
下一篇: 给定一个值S,在有序数组中找出两个元素A和B,使 A+B = S.
七郎
博客等级 码龄14年 31粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值