1.2万多行MyBatis源码,源码你知道里面用了多少种设计模式吗?
2.Mybatis 源码TypeHandler(类型处理器)转换参数到SQL和转换SQL查询结果到Java类
3.Mybatis源码剖析(懒加载原理)
4.重磅!MyBatis-Plus 可视化代码生成器来啦,源码开发效率提升2倍 !源码
5.MyBatis-Plusä¸å¦ä½ä½¿ç¨ResultMap
6.MyBatis 源码源码解析:映射文件的加载与解析(上)
2万多行MyBatis源码,你知道里面用了多少种设计模式吗?
在MyBatis的源码小数怎么写源码两万多行的框架源码中,设计模式的源码巧妙使用是整个框架的精华。
MyBatis中主要使用了以下设计模式:工厂模式、源码单例模式、源码建造者模式、源码适配器模式、源码代理模式、源码组合模式、源码装饰器模式、源码模板模式、源码策略模式和迭代器模式。
具体来说,工厂模式用于SqlSessionFactory的创建,单例模式用于Configuration的管理,建造者模式用于ResultMap的构建,适配器模式用于统一日志接口,代理模式用于MapperProxy的实现,组合模式用于SQL标签的组合,装饰器模式用于二级缓存操作,模板模式用于定义SQL执行流程,策略模式用于多类型处理器的暴涨拉升指标源码实现,迭代器模式用于字段解析的实现。
通过运用这些设计模式,MyBatis成功地实现了复杂场景的解耦,并将问题合理切割为若干子问题,以提高理解和解决的效率。
总的来说,MyBatis大约运用了种左右的设计模式,这使得框架在处理复杂问题时能够更加高效和灵活。
学习源码不仅可以帮助我们更好地理解设计模式和设计原则,更能够扩展我们的编码思维,积累实际应用的经验。
希望本文的分享能够帮助到您,同时也推荐您阅读《手写MyBatis:渐进式源码实践》一书,了解更多关于MyBatis的知识。
Mybatis TypeHandler(类型处理器)转换参数到SQL和转换SQL查询结果到Java类
TypeHandler在Mybatis中的作用
在预处理语句(PreparedStatement)中设置参数或从结果集中取出值时,TypeHandler负责将获取的值以合适的方式设置到PreparedStatement,或转换成Java类型。通过重写TypeHandler或创建自己的TypeHandler,可以处理不支持的或非标准类型。
在项目中,对于只有有限个值的字段,常使用数字类型表示,如考试状态字段exam_status定义为tinyint。在代码中直接使用Integer表示时,读性和维护性较差,水母是光源码故定义枚举类来表示。需要实现TypeHandler以自动完成从数据库数字类型转换成枚举类的过程。
实现TypeHandler的方案如下:定义枚举类实现EnumBase接口,包含codeOf静态方法进行数字转换。然后创建TypeHandler类实现org.apache.ibatis.type.TypeHandler接口,重写相应方法。避免在xml配置文件为每个枚举单独声明TypeHandler,使用Java代码动态注册,关键在于配置类。
Mybatis注册工厂TypeHandlerRegistry初始化常见类型转换器,如String类型。执行转换时,通过TypeHandlerRegistry获取TypeHandler。自定义枚举类能起作用,依据TypeHandlerRegistry获取TypeHandler的顺序。Mybatis使用TypeHandler实现参数设置到SQL和转换SQL查询结果到Java类的过程。
在mapper文件中,所有parameter入参的Java参数关联TypeHandler,解析成ParameterMapping对象,其中每条SQL的parameter入参关联UnknownTypeHandler,因为字段未指定JavaType和jdbcType属性,只有指定parameterType属性,Mybatis才能获取实际Java类型。resultMap的Java参数也关联TypeHandler,通过type属性获取实际Java类型并关联TypeHandler。智慧商圈系统源码
执行代码时,SQL参数设置和查询结果转换到Java类的过程由TypeHandler完成。对于参数设置,调用TypeHandler设置SQL参数,获取真正TypeHandler是通过TypeHandlerRegistry.getTypeHandler方法实现。转换查询结果到Java类的过程复杂,由DefaultResultSetHandler处理。
了解Mybatis执行流程有助于深入理解TypeHandler的作用和实现细节。建议实际项目中实践TypeHandler的使用,提高代码的可读性和可维护性。
TypeHandler源码地址:[提供源码GitHub链接]
Mybatis源码剖析(懒加载原理)
懒加载,即按需加载,旨在优化查询性能。以一个包含订单列表的User对象为例,当仅获取用户信息时,若启用懒加载模式,执行SQL不会查询订单列表。需获取订单列表时,才会发起数据库查询。实现方式包括在核心配置文件中设置或在相关映射文件中通过fetchType属性配置懒加载策略。
懒加载的配置如何加载到项目中呢?首先,这些配置保存在全局Configuration对象中,通常在解析核心配置文件的代码中实现。在settingsElement方法中,懒加载配置被保存在lazyLoadingEnabled属性中。源码科技未来前景对于resultMap标签中collection | association的fetchType属性,其配置通过解析mappers标签下的resultMap标签实现,最终调用buildResultMappingFromContext方法处理子标签。该方法结合全局配置判断是否需要执行懒加载。
懒加载的实现原理涉及动态代理。当调用代理对象的延迟加载属性方法时,如访问a.getB().getName(),代理对象会调用拦截器方法。若发现需要延迟加载,代理对象会单独发送SQL查询关联对象,加载数据后设置属性值,完成方法调用。简而言之,懒加载通过动态代理实现,拦截指定方法并执行数据加载。
深入剖析懒加载源码,会发现它涉及查询和数据处理的多步操作。查询完成后,结果集处理、列值获取、判断是否进行懒加载等步骤共同构建懒加载机制。动态代理在访问对象属性时触发,最终通过Javassist库创建代理对象,实现懒加载逻辑。当访问如userList2.get(0).getOrderList()时,若满足条件,代理对象会调用懒加载查询方法获取数据。判断懒加载条件的关键在于结果集处理阶段,通过访问映射关系和查询映射值来确定是否执行后续懒加载查询。
综上所述,Mybatis的懒加载机制通过动态代理和结果集处理实现,旨在优化性能,按需加载数据,提高查询效率。通过核心配置和映射文件中的配置,懒加载逻辑被加载到项目中,为开发者提供灵活的加载策略。
重磅!MyBatis-Plus 可视化代码生成器来啦,开发效率提升2倍 !
基于Mybatis-Plus的代码自助生成器
在使用Mybatis-Plus进行开发时,可以提高开发效率。然而,常规的代码生成工具可能无法满足所有需求,尤其是对于多数据库的支持,以及高度定制化的要求。因此,一款支持图形用户界面的代码生成框架变得尤为重要。本文介绍了一款名为mybatis-plus-generator-ui的代码生成器,旨在为开发者提供更加高效、灵活的代码生成解决方案。
mybatis-plus-generator-ui是基于Mybatis-Plus生成器进行封装,通过Web界面快速生成兼容Spring Boot和Mybatis-Plus框架的业务代码。它提供了交互式的Web界面,让开发者能够生成符合Mybatis-Plus框架的实体类(Entity)、映射类(Mapper)、Mapper.xml、服务类(Service)、控制器类(Controller)等。此外,该工具支持自定义模板和各类输出参数,甚至可以通过SQL查询语句直接生成代码。
要使用mybatis-plus-generator-ui,首先可以通过Maven引入jar包,并创建一个程序入口,使用main函数运行。从1.4.0版本开始,mybatis-plus-generator-ui支持独立部署为Spring Boot项目,通过页面指定目标项目的根目录,为多个项目提供源码生成服务。配置示例包括数据库连接信息、运行端口以及默认的模板目录地址。
使用mybatis-plus-generator-ui进行代码生成时,可以浏览和查询配置的数据源的数据表信息,选择生成模板代码。工具内置了多种代码模板配置,包括Entity、Mapper、Service、Controller等,并提供了模板替换和参数修改功能。此外,支持策略配置,如是否覆盖原有文件、生成文件的种类等。SQL配置生成功能允许用户通过输入SQL查询语句,自动生成对应的查询方法、DTO对象和ResultMap。
为了满足不同团队的需求,mybatis-plus-generator-ui提供了代码模板调整和自定义扩展功能。开发者可以通过修改btl模板文件来自定义代码生成的各个方面,包括代码层级配置、服务层、控制器层、实体类命名等。mybatis-plus-generator-ui的前端界面也支持自定义修改,只需将代码clone下来,进入frontend目录进行扩展开发即可。
总结来说,mybatis-plus-generator-ui为基于Mybatis-Plus的开发提供了高效、灵活的代码生成工具,简化了代码开发流程,提高了开发效率。通过实例集成和详细的扩展开发介绍,本文旨在为有需要的开发者提供实用的指导和帮助。
MyBatis-Plusä¸å¦ä½ä½¿ç¨ResultMap
MyBatis-Plus 对 MyBatis åºæ¬é¶ä¾µå ¥ï¼å®å ¨å¯ä»¥ä¸ MyBatis æ··å使ç¨ï¼è¿ç¹å¾èµã
å¨æ¶åå°å ³ç³»åæ°æ®åºå¢å æ¥æ¹çä¸å¡æ¶ï¼ææ¯è¾åæ¬¢ç¨ MyBatis-Plus ï¼å¼åæçæé«ãå ·ä½ç使ç¨å¯ä»¥åèå®ç½ï¼æè èªå·±ä¸ææ¸ç´¢æåä¸ä¸ã
ä¸é¢ç®åæ»ç»ä¸ä¸å¨ MyBatis-Plus ä¸å¦ä½ä½¿ç¨ ResultMap ã
å ç个ä¾åï¼
æå¦ä¸ä¸¤å¼ 表ï¼
å ¶ä¸ï¼ tb_hero ä¸ç bid å ³è tb_book 表ç id ã
ä¸é¢å ç Hero å®ä½ç±»ç代ç ï¼å¦ä¸ï¼
注æäºï¼æç¹å°æ tb_hero 表ä¸ç bid å段æ å°æå®ä½ç±» Hero ä¸ç bookId å±æ§ã
MyBatis-Plus æå°åºç SQL 为ï¼
没æ¯ç ï¼ MyBatis-Plus ä¼æ ¹æ® @TableField æå®çæ å°å ³ç³»ï¼çæ对åºç SQL ã
MyBatis-Plus æå°åºç SQL 为ï¼
ä¹æ²¡æ¯ç ï¼å¯ä»¥çå°çæç SELECT ä¸æ bid åäºå«å bookId ã
æ¯å¦ç°å¨ææ³è¿æ¥ tb_hero ä¸ tb_book è¿ä¸¤å¼ 表ï¼å¦ä¸ï¼
æ¥è¯¢ MyBatis-Plus æå°åºç SQL 为ï¼
SQL没å¥é®é¢ï¼è¿æ»¤ä¸å页ä¹é½æ£å¸¸ï¼ä½æ¯æ¤æ¶ä½ ä¼åç° bookId å±æ§ä¸º null ï¼å¦ä¸ï¼
为ä»ä¹å¢ï¼
è°ç¨ BaseMapper ä¸å ç½®ç selectById() æ¹æ³å¹¶æ²¡æåºç°è¿ç§æ åµåï¼ï¼ï¼
åè¿å¤´æ¥å对æ¯ä¸ä¸å¨ HeroMapper ä¸èªå·±å®ä¹çæ¥è¯¢ä¸ MyBatis-Plus èªå¸¦ç selectById() æå¥ä¸åï¼è¿è®°å¾ä¸é¢çååçæµè¯åï¼çæçSQLæå¥ä¸åï¼
åæ¥ï¼ MyBatis-Plus 为 BaseMapper ä¸å ç½®çæ¹æ³çæSQLæ¶ï¼ä¼æ SELECT åå¥ä¸ bid åå«å bookId ï¼èèªå·±åçæ¥è¯¢ MyBatis-Plus 并ä¸ä¼å¸®ä½ ä¿®æ¹ SELECT åå¥ï¼ä¹å°±å¯¼è´ bookId å±æ§ä¸º null ã
å¨è¿éå°±æ¯ tb_hero 表ä¸ç bid å段æ å°æå®ä½ç±» Hero ä¸ç bid å±æ§ãè¿æ ·å½ç¶å¯ä»¥è§£å³é®é¢ï¼ä½ä¸æ¯æ¬ç¯è®²çéç¹ã
å¨ @TableName 设置 autoResultMap = true
ç¶åå¨èªå®ä¹æ¥è¯¢ä¸æ·»å @ResultMap 注解ï¼å¦ä¸ï¼
è¿æ ·ï¼ä¹è½è§£å³é®é¢ã
ä¸é¢ç®åçä¸æºç ï¼ @ResultMap("mybatis-plus_å®ä½ç±»å") æä¹æ¥çã
详æ è§ï¼ com.baomidou.mybatisplus.core.metadata.TableInfo#initResultMapIfNeed()
注æçä¸é¢çå符串 id çææï¼ä½ åºè¯¥å¯ä»¥æç½ã
æèï¼ è¿ç§æ¹å¼ç ResultMap é»è®¤æ¯å¼ºç»å¨ä¸ä¸ª @TableName ä¸çï¼å¦ææ¯æ个èåæ¥è¯¢æè æ¥è¯¢çç»æ并é对åºä¸ä¸ªçå®ç表æä¹åå¢ï¼æ没ææ´ä¼é çæ¹å¼ï¼
åºäºä¸é¢çæèï¼æåäºä¸é¢ç®åçå®ç°ï¼
å ³é®ä»£ç å ¶å®æ²¡æå è¡ï¼èå¿çä¸åºè¯¥ä¸é¾æã
è¿æ¯ç¨ä¾åæ¥è¯´ææ´ç´è§ã
ä¸é¢æ¯ä¸ä¸ªèåæ¥è¯¢ï¼
å ¶ä¸ BookAgg çå®ä¹å¦ä¸ï¼å¨å®ä½ç±»ä¸ä½¿ç¨äº @AutoResultMap 注解ï¼
MyBatis 源码解析:映射文件的加载与解析(上)
MyBatis 的映射文件是其核心组成部分,用于配置 SQL 语句、二级缓存及结果集映射等功能,是其区别于其他 ORM 框架的重要特色。 在解析映射文件时,MyBatis 通过调用 XMLMapperBuilder#parse 方法实现加载与解析操作。此方法首先判断映射文件是否已解析,若未解析则调用 XMLMapperBuilder#configurationElement 方法解析所有配置,并注册当前映射文件关联的 Mapper 接口。对于处理异常的标签,MyBatis 会记录至 Configuration 对象并尝试二次解析。 解析流程主要涉及以下几个关键步骤:缓存配置(cache 标签):MyBatis 采用缓存设计,分为一级缓存和二级缓存。解析 cache 标签时,首先获取相关属性配置,然后使用 CacheBuilder 创建缓存对象,并记录到 Configuration 对象。
缓存引用(cache-ref 标签):标签默认限定在 namespace 范围内,用于引用其它命名空间中的缓存对象。解析过程中记录引用关系,然后从 Configuration 中获取引用的缓存对象。
结果集映射(resultMap 标签):解析 resultMap 标签配置,构建 ResultMap 对象,并将其记录到 Configuration 中。
SQL 语句(sql 标签):通过 sql 标签配置复用的 SQL 语句片段,解析后记录至 Configuration 的 sqlFragments 属性中。
核心数据库操作(select / insert / update / delete 标签):解析这些标签时,构建 MappedStatement 对象并记录到 Configuration 中。
每个标签解析实现由 MyBatis 提供的多个方法执行,如 XMLMapperBuilder 的 configurationElement 方法和解析具体标签的子方法,如 cacheElement、sqlElement 等。解析过程中,MyBatis 会调用不同的构造器和工厂方法来创建、初始化和配置相应的对象。 在解析完成之后,MyBatis 将所有配置对象封装在 Configuration 对象中,该对象包含所有映射文件中定义的配置信息,供后续的 SQL 语句执行和映射操作使用。