1.深入详解 Mybatis 框框架的架构原理与 6 大核心流程
2.springâAOPä¸äºå¡
3.ORM如何自己手写一个ORM框架
4.MyBatis 源码解析:映射文件的加载与解析(上)
5.Odoo框架源码研读二:ORM框架与日志
6.iBATIS框架源码剖析内容简介
深入详解 Mybatis 的架构原理与 6 大核心流程
深入解析 MyBatis 的架构原理与核心流程,对于进入一线互联网大厂的架源开发者来说,掌握 MyBatis 实现的使用以及其内部机制是基本要求之一。理解 MyBatis 原理的架构与原理,阅读其核心源码,框框架能够显著提升职业技能,架源获取页面获取源码增强在职场上的实现竞争力。MyBatis 原理的整体架构可划分为三层,分别为接口层、框框架数据处理层和基础支撑层。架源
接口层:提供与数据库交互的实现接口 API,允许开发者通过本地 API 操纵数据库。原理接口层接收调用请求后,框框架调用数据处理层执行具体数据操作。架源例如,实现使用 Mapper 接口时,配置文件中的每个 节点映射为一个 Mapper 接口,接口方法与节点项对应,如 id、parameterType 和 resultMap。MyBatis 根据接口声明的信息生成 Mapper 实例,通过 SqlSession 方法执行数据库操作。
数据处理层:是 MyBatis 的核心,负责 SQL 查询、解析、执行及结果映射。它完成的主要任务是根据请求完成数据库操作。在操作中,动态生成 SQL 语句,实现 SQL 的灵活性和扩展性。参数映射涉及 Java 和 JDBC 数据类型之间的转换,包括查询阶段和结果集处理阶段。
基础支撑层:是 MyBatis 框架的基础,包括连接管理、事务管理、配置加载和缓存处理。此层提供共用功能组件,预订源码是什么为数据处理层提供支撑。关键功能包括:
缓存机制:优化数据库性能,通过缓存拦截部分数据库请求,减少压力、提高系统性能。反射工具:封装 Java 反射,提供简洁 API,优化反射操作性能。类型转换:实现 JDBC 类型与 Java 类型之间的转换,支持查询结果映射。日志:提供详细日志输出,集成第三方日志框架。资源加载:封装类加载器,确保资源加载顺序,支持加载类文件和资源文件。解析器:封装 XPath,支持配置文件解析,处理动态 SQL 占位符。事务管理:提供简单事务接口和实现,集成 Spring 管理事务。Binding:关联自定义 Mapper 接口与映射配置文件,避免运行时异常。Data Source:组织数据源,优化性能。MyBatis 的核心执行流程包括:
配置文件:配置全局信息和 SQL 映射。SqlSessionFactory:构建会话工厂,用于创建 SqlSession。SqlSession:执行数据库操作。Exector:自定义执行器接口,操作数据库。MappedStatement:封装配置信息与 SQL 映射,执行前后处理输入和输出参数。通过全面解析 MyBatis 的架构原理与核心流程,开发者能够深入理解其工作机制,从而更有效地利用这一强大的 ORM 框架。此系列旨在提供全面指南,外贸订单源源码帮助读者掌握 MyBatis 的核心原理与实现。
springâAOPä¸äºå¡
title: springââAOPä¸äºå¡.mddate: -- ::
categories: [Spring]
tags: [AOP,äºå¡]
toc: true
å ååºæºç ä¸æ¯è¾éç¹çå 个类ï¼
1ã<aop:before method="before" pointcut-ref="myMethods"/>å è£ æä¸ä¸ªadvisor
2ãAspectJAwareAdvisorAutoProxyCreatorï¼å½å®ä¾åææbeané½ä¼æ§è¡å°AspectJAwareAdvisorAutoProxyCreatorç±»
å®ä¼æ£æµbeanæ¯å¦advisor以åadviceåå¨ï¼å¦ææ就说æè¿ä¸ªbeanæåé¢ï¼æåé¢é£ä¹å°±ä¼çæ代ç
3ãjdkç代çï¼beanéé¢çææadvisorå å ¥å°proxyFactoryã
4ãjdkDynamicProxy invokeï¼æ¿å°beanéé¢çææInterceptorï¼ä¼å¾ªç¯proxyFactoryéé¢çææadvisor
éé¢æadviceï¼éé¢çadviceæ两ç§ç±»åï¼è¦ä¹æ¯adviceï¼è¦ä¹æ¯MethodInterceptorç±»åç
5ãå½ä»£ç对象è°ç¨æ¹å¼ï¼æ¯ä¸ä¸ªMethodInterceptorç±»åçç±»çé¾å¼è°ç¨è¿ç¨ï¼ç´å°å®¹å¨ç大å°åç´¢å¼ä¸è´çæ¶åè°ç¨JoinPointç®æ æ¹æ³
beforeï¼this.advice.before(),invocation.processd();
è£ é åæ°ï¼åé¢éé¢beforeæ¹æ³çmethod对象ï¼method.getParamterTypes()[0]
æç»ä¼æadviceå°è£ æMethodInterceptorç±»åç对象
ç¨åºæ§è¡çæ个ç¹å®ä½ç½®ï¼å¦ç±»å¼å§åå§ååãç±»åå§ååãç±»æ个æ¹æ³è°ç¨åãè°ç¨åãæ¹æ³æåºå¼å¸¸åãä¸ä¸ªç±»æä¸æ®µç¨åºä»£ç æ¥æä¸äºå ·æè¾¹çæ§è´¨çç¹å®ç¹ï¼è¿äºç¹ä¸çç¹å®ç¹å°±ç§°ä¸ºâè¿æ¥ç¹âãSpringä» æ¯ææ¹æ³çè¿æ¥ç¹ï¼å³ä» è½å¨æ¹æ³è°ç¨åãæ¹æ³è°ç¨åãæ¹æ³æåºå¼å¸¸æ¶ä»¥åæ¹æ³è°ç¨ååè¿äºç¨åºæ§è¡ç¹ç»å ¥å¢å¼ºãè¿æ¥ç¹ç±ä¸¤ä¸ªä¿¡æ¯ç¡®å®ï¼ç¬¬ä¸æ¯ç¨æ¹æ³è¡¨ç¤ºçç¨åºæ§è¡ç¹ï¼ç¬¬äºæ¯ç¨ç¸å¯¹ç¹è¡¨ç¤ºçæ¹ä½ã
æ¯ä¸ªç¨åºç±»é½æ¥æå¤ä¸ªè¿æ¥ç¹ï¼å¦ä¸ä¸ªæ¥æ两个æ¹æ³çç±»ï¼è¿ä¸¤ä¸ªæ¹æ³é½æ¯è¿æ¥ç¹ï¼å³è¿æ¥ç¹æ¯ç¨åºç±»ä¸å®¢è§åå¨çäºç©ãAOPéè¿âåç¹âå®ä½ç¹å®çè¿æ¥ç¹ãè¿æ¥ç¹ç¸å½äºæ°æ®åºä¸çè®°å½ï¼èåç¹ç¸å½äºæ¥è¯¢æ¡ä»¶ãåç¹åè¿æ¥ç¹ä¸æ¯ä¸å¯¹ä¸çå ³ç³»ï¼ä¸ä¸ªåç¹å¯ä»¥å¹é å¤ä¸ªè¿æ¥ç¹ãå¨Springä¸ï¼åç¹éè¿org.springframework.aop.Pointcutæ¥å£è¿è¡æè¿°ï¼å®ä½¿ç¨ç±»åæ¹æ³ä½ä¸ºè¿æ¥ç¹çæ¥è¯¢æ¡ä»¶ï¼Spring AOPçè§å解æå¼æè´è´£åç¹æ设å®çæ¥è¯¢æ¡ä»¶ï¼æ¾å°å¯¹åºçè¿æ¥ç¹ãå ¶å®ç¡®åå°è¯´ï¼ä¸è½ç§°ä¹ä¸ºæ¥è¯¢è¿æ¥ç¹ï¼å 为è¿æ¥ç¹æ¯æ¹æ³æ§è¡åãæ§è¡åçå æ¬æ¹ä½ä¿¡æ¯çå ·ä½ç¨åºæ§è¡ç¹ï¼èåç¹åªå®ä½å°æ个æ¹æ³ä¸ï¼æ以å¦æå¸æå®ä½å°å ·ä½è¿æ¥ç¹ä¸ï¼è¿éè¦æä¾æ¹ä½ä¿¡æ¯ã
å¢å¼ºæ¯ç»å ¥å°ç®æ ç±»è¿æ¥ç¹ä¸çä¸æ®µç¨åºä»£ç ï¼å¨Springä¸ï¼å¢å¼ºé¤ç¨äºæè¿°ä¸æ®µç¨åºä»£ç å¤ï¼è¿æ¥æå¦ä¸ä¸ªåè¿æ¥ç¹ç¸å ³çä¿¡æ¯ï¼è¿ä¾¿æ¯æ§è¡ç¹çæ¹ä½ãç»åæ§è¡ç¹æ¹ä½ä¿¡æ¯ååç¹ä¿¡æ¯ï¼æ们就å¯ä»¥æ¾å°ç¹å®çè¿æ¥ç¹ã
å¢å¼ºé»è¾çç»å ¥ç®æ ç±»ãå¦æ没æAOPï¼ç®æ ä¸å¡ç±»éè¦èªå·±å®ç°ææé»è¾ï¼èå¨AOPç帮å©ä¸ï¼ç®æ ä¸å¡ç±»åªå®ç°é£äºé横åé»è¾çç¨åºé»è¾ï¼èæ§è½çè§åäºå¡ç®¡ççè¿äºæ¨ªåé»è¾åå¯ä»¥ä½¿ç¨AOPå¨æç»å ¥å°ç¹å®çè¿æ¥ç¹ä¸ã
å¼ä»æ¯ä¸ç§ç¹æ®çå¢å¼ºï¼å®ä¸ºç±»æ·»å ä¸äºå±æ§åæ¹æ³ãè¿æ ·ï¼å³ä½¿ä¸ä¸ªä¸å¡ç±»åæ¬æ²¡æå®ç°æ个æ¥å£ï¼éè¿AOPçå¼ä»åè½ï¼æ们å¯ä»¥å¨æå°ä¸ºè¯¥ä¸å¡ç±»æ·»å æ¥å£çå®ç°é»è¾ï¼è®©ä¸å¡ç±»æ为è¿ä¸ªæ¥å£çå®ç°ç±»ã
ç»å ¥æ¯å°å¢å¼ºæ·»å 对ç®æ ç±»å ·ä½è¿æ¥ç¹ä¸çè¿ç¨ãAOPåä¸å°ç»å¸æºï¼å°ç®æ ç±»ãå¢å¼ºæå¼ä»éè¿AOPè¿å°ç»å¸æºå¤©è¡£æ ç¼å°ç¼ç»å°ä¸èµ·ãæ ¹æ®ä¸åçå®ç°ææ¯ï¼AOPæä¸ç§ç»å ¥çæ¹å¼ï¼
aãç¼è¯æç»å ¥ï¼è¿è¦æ±ä½¿ç¨ç¹æ®çJavaç¼è¯å¨ã
bãç±»è£ è½½æç»å ¥ï¼è¿è¦æ±ä½¿ç¨ç¹æ®çç±»è£ è½½å¨ã
cãå¨æ代çç»å ¥ï¼å¨è¿è¡æ为ç®æ 类添å å¢å¼ºçæåç±»çæ¹å¼ã
Springéç¨å¨æ代çç»å ¥ï¼èAspectJéç¨ç¼è¯æç»å ¥åç±»è£ è½½æç»å ¥ã
ä¸ä¸ªç±»è¢«AOPç»å ¥å¢å¼ºåï¼å°±äº§åºäºä¸ä¸ªç»æç±»ï¼å®æ¯èåäºåç±»åå¢å¼ºé»è¾ç代çç±»ãæ ¹æ®ä¸åç代çæ¹å¼ï¼ä»£çç±»æ¢å¯è½æ¯ååç±»å ·æç¸åæ¥å£çç±»ï¼ä¹å¯è½å°±æ¯åç±»çåç±»ï¼æ以æ们å¯ä»¥éç¨è°ç¨åç±»ç¸åçæ¹å¼è°ç¨ä»£çç±»ã
åé¢ç±åç¹åå¢å¼ºï¼å¼ä»ï¼ç»æï¼å®æ¢å æ¬äºæ¨ªåé»è¾çå®ä¹ï¼ä¹å æ¬äºè¿æ¥ç¹çå®ä¹ï¼Spring AOPå°±æ¯è´è´£å®æ½åé¢çæ¡æ¶ï¼å®å°åé¢æå®ä¹ç横åé»è¾ç»å ¥å°åé¢ææå®çè¿æ¥ç¹ä¸ã
advisorï¼ pointCut advice
ä¸ç±»åè½çå¢å¼º
aroundæ¹æ³éé¢ä»£ç åé¢
äºå¡åé¢
ç¼ååé¢
æ¥å¿åé¢
äºå¡ï¼Transactionï¼ï¼ä¸è¬æ¯æè¦åçææåçäºæ ãå¨è®¡ç®æºæ¯è¯ä¸æ¯æ访é®å¹¶å¯è½æ´æ°æ°æ®åºä¸åç§æ°æ®é¡¹çä¸ä¸ªç¨åºæ§è¡åå (unit)ãæ¯æ°æ®åºæä½çæå°å·¥ä½åå ï¼æ¯ä½ä¸ºå个é»è¾å·¥ä½åå æ§è¡çä¸ç³»åæä½ï¼è¿äºæä½ä½ä¸ºä¸ä¸ªæ´ä½ä¸èµ·åç³»ç»æ交ï¼è¦ä¹é½æ§è¡ãè¦ä¹é½ä¸æ§è¡ï¼äºå¡æ¯ä¸ç»ä¸å¯ååå²çæä½éåï¼å·¥ä½é»è¾åå ï¼ã
大è´æµç¨å½¢å¦
æ°æ®åºäºå¡æ¥æå 大ç¹æ§ï¼
äºå¡çå大ç¹æ§ï¼
äºå¡æ¯æ°æ®åºçé»è¾å·¥ä½åä½ï¼äºå¡ä¸å å«çåæä½è¦ä¹é½åï¼è¦ä¹é½ä¸å
äº å¡æ§è¡çç»æå¿ é¡»æ¯ä½¿æ°æ®åºä»ä¸ä¸ªä¸è´æ§ç¶æåå°å¦ä¸ä¸ªä¸è´æ§ç¶æãå æ¤å½æ°æ®åºåªå å«æåäºå¡æ交çç»ææ¶ï¼å°±è¯´æ°æ®åºå¤äºä¸è´æ§ç¶æãå¦ææ°æ®åºç³»ç» è¿è¡ä¸åçæ éï¼æäºäºå¡å°æªå®æ就被迫ä¸æï¼è¿äºæªå®æäºå¡å¯¹æ°æ®åºæåçä¿®æ¹æä¸é¨åå·²åå ¥ç©çæ°æ®åºï¼è¿æ¶æ°æ®åºå°±å¤äºä¸ç§ä¸æ£ç¡®çç¶æï¼æè è¯´æ¯ ä¸ä¸è´çç¶æã
ä¸ä¸ªäºå¡çæ§è¡ä¸è½å ¶å®äºå¡å¹²æ°ãå³ä¸ä¸ªäºå¡å é¨çæä½å使ç¨çæ°æ®å¯¹å ¶å®å¹¶åäºå¡æ¯é离çï¼å¹¶åæ§è¡çå个äºå¡ä¹é´ä¸è½äºç¸å¹²æ°ã
ä¹ç§°æ°¸ä¹ æ§ï¼æä¸ä¸ªäºå¡ä¸æ¦æ交ï¼å®å¯¹æ°æ®åºä¸çæ°æ®çæ¹åå°±åºè¯¥æ¯æ°¸ä¹ æ§çãæ¥ä¸æ¥çå ¶å®æä½ææ éä¸åºè¯¥å¯¹å ¶æ§è¡ç»ææä»»ä½å½±åã
个人ç解ï¼äºå¡å¨Springä¸æ¯åå©AOPææ¯æ¥å®ç°çï¼å¯ä»¥ä½ä¸ºAOPä¸çä¸ä¸ªäºå¡åé¢ãspringæºç 对äºå¡çå¤çé»è¾ï¼èªå·±ç 究å§ï¼
ORMæ¡æ¶ä¸ä»¥Mybatis为ä¾ï¼äºå¡å¤çå°±æ¯ç¨å°äºä¸ä¸ªç±»Transactionï¼é¨åæºç å¦ä¸
å¯ä»¥çåºTransaction管ççå°±æ¯ä¸ä¸ªconnectionï¼èconnectionæ们å¾æ¸ æ¥æ¯ä¸ç¨æ·ä¼è¯æé©çã
é£ä¹å ³ç³»å°±æ¯Transaction 管çConnection ï¼èconnectionä¸ ç¨æ·sessionä¸å¯¹ä¸åå¨ã
å¨springBootä¸ï¼åªéè¦å å ¥POMå°±å¯ä»¥äºï¼é å注解使ç¨å³å¯ã
æ¥ä¸æ¥å°±æ¯äºå¡çæ§å¶äºã
é¦å äºå¡æå å¤§ä¼ æå±æ§ï¼
å ¶ä¸æ常è§çï¼ç¨å¾æå¤å°± PROPAGATION_REQUIREDãPROPAGATION_REQUIRES_NEWã PROPAGATION_NESTED è¿ä¸ç§ãäºå¡çä¼ æå±æ§æ¯ spring ç¹æçï¼æ¯ spring ç¨æ¥æ§å¶æ¹æ³äºå¡çä¸ç§æ段ï¼è¯´ç´ç½ç¹å°±æ¯ç¨æ¥æ§å¶æ¹æ³æ¯å¦ä½¿ç¨åä¸äºå¡çä¸ç§å±æ§ï¼ä»¥åæç §ä»ä¹è§ååæ»çä¸ç§æ段ã
ä¸é¢ç¨ä»£ç æ¼ç¤ºè¿ä¸ç§å±æ§çæºå¶ï¼
äºå¡çé»è®¤å±æ§å°±æ¯requiredï¼éè¿Transactional.javaä¸çPropagation propagation() default Propagation.REQUIRED; å¯ä»¥çåºã
è¿ç§æ åµå°±æ¯äºå¡1ï¼äºå¡2 é½å å ¥å°äºäºå¡0ä¸ãä¸ç®¡æ¯1ï¼2åªä¸ªäºå¡æåºå¼å¸¸ï¼äºå¡0é½ä¼åæ»ãæ°æ®æ·»å ä¼å¤±è´¥ã
è¿ç§æ åµå°±æ¯ï¼
äºå¡0ï¼requiredï¼ {
äºå¡1 ï¼REQUIRES_NEWï¼
äºå¡2
}
æ¤æ¶ã
æ åµaï¼
1ãå¦æåªæ¯äºå¡2åºç°äºå¼å¸¸ï¼é£ä¹äºå¡1ä¼æ交ï¼äºå¡2å å ¥å°äºå¡0ä¸ä¼åæ»ã
2ãå¦æåªæ¯äºå¡1åºç°äºå¼å¸¸ï¼é£ä¹äºå¡1ä¼åæ»ï¼åä¸å±äºå¡0æå¼å¸¸ï¼äºå¡2ä¼å å ¥å°äºå¡0ä¸ï¼è¿æ¶é½ä¼åæ»ã
æ åµbï¼
å¦æäºå¡1ï¼äºå¡2é½æ¯REQUIRES_NEWä¼ æå±æ§ãé£ä¹ç»æå°±æ¯ï¼
1ãå¦æäºå¡1ï¼æåºäºå¼å¸¸ï¼é£ä¹äºå¡2æ¯ä¸ä¼æ§è¡çï¼é£ä¹äºå¡0å¿ ç¶åæ»ã
2ãå¦æäºå¡2ï¼æåºå¼å¸¸ï¼é£ä¹äºå¡1ä¼æ交ï¼è¡¨ä¸ä¼ææ°æ®ãäºå¡2æå¼å¸¸åæ»å¹¶æåºï¼äºå¡0åæ»ã
NESTEDå±æ§å ¶å®å°±æ¯å建äºåæ»ç¹ï¼æå¼å¸¸æ¶ï¼ä¼åæ»å°æå®çåæ»ç¹ã
å¨è¿éè¿ä»£ç æµè¯ï¼åºç°ä¸ç§æ åµæ¯ï¼æ 论äºå¡1ï¼äºå¡2åªä¸ªæå¼å¸¸ï¼æ°æ®é½ä¸ä¼æå ¥æåï¼åå æ¯ï¼ä¸è®ºæ¯äºå¡1è¿æ¯äºå¡2é½ä¼åäºå¡0æåºå¼å¸¸ï¼äºå¡0æè·å°å¼å¸¸åï¼æ§è¡rollback()æ¹æ³ï¼è¿å°±æä½æäºï¼äºå¡çå ¨é¨åæ»ã
å¦ææ³è¦äºå¡1åäºå¡2 æ³è¦æ ¹æ®èªå·±çåæ»ç¹åæ»ï¼é£ä¹äºå¡0å¿ é¡»èªå·±å¤çå¼å¸¸ï¼ä¸è®©springæè·å°è¿ä¸ªå¼å¸¸ï¼é£ä¹å°±æ»¡è¶³äºãæ代ç æ¹æè¿ç§ï¼
Jack大佬æä¾äºï¼ä¼ªä»£ç åææ³ã
æç §Springæºç çäºå¡å¤çé»è¾ï¼ä¼ªä»£ç 大è´ä¸ºï¼
ORM如何自己手写一个ORM框架
本文将讨论如何构建一个ORM框架,并以cushy-storage磁盘缓存框架为例进行实现。ORM框架,即对象关系映射框架,允许程序员使用面向对象的方式操作数据库,简化了SQL语言的复杂性和繁琐性。
在Python中,如SQLAlchemy这样的流行ORM框架可以帮助轻松实现数据库的CRUD操作。使用ORM框架,开发者可以像操作本地对象一样操作数据库,从而提高了代码的可读性和维护性。
下面以安装SQLAlchemy为例,展示如何创建数据库表和进行基本操作。首先,通过命令安装SQLAlchemy。接着,定义表结构并执行CRUD操作。示例代码展示了使用ORM框架进行数据库操作的简易性。
编写一个完整的ORM框架需要深入理解数据库、Python编程以及设计模式。若希望深入了解,可参考如Django、SQLAlchemy、Peewee等优秀的开源ORM框架的源代码及文档。
本文将结合cushy-storage的功能,快速构建一个ORM框架,实现对本地文件数据的增删改查。cushy-storage是一个基于磁盘缓存的Python库,简化了数据存储和读取的过程。
实现的主要功能包括:存储、检索、更新和删除自定义对象。通过继承BaseORMModel类,自定义类可以轻松实现ORM功能。CushyOrmCache类继承CushyDict,地铁票源码并结合ORM功能,实现对象级数据的高效管理。
构建QuerySet类,提供更丰富的查询功能,如条件筛选、返回所有数据、返回第一个数据等。最后,通过ORMMixin实现增删改查功能,CushyORMCache类提供完整的ORM框架接口。
使用CushyORMCache,开发者可以方便地进行对象级数据的增删改查操作。下面的示例展示了如何构建用户系统并使用CushyORMCache进行操作。
完整实现代码展示了如何继承BaseORMModel、初始化CushyOrmCache,以及进行基本的增删改查操作。通过传入User对象或表名(如"User")进行数据查询,实现复杂条件查询和批量返回。
本文总结了ORM框架的概念和构建方法,以cushy-storage为依托,构建了一个实用的ORM框架。该框架支持复杂条件查询、批量数据返回等功能,简化了对象级数据的操作。
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 语句执行和映射操作使用。Odoo框架源码研读二:ORM框架与日志
上一期我们带来了关于Odoo框架源码第一期内容(传动门➡《Odoo框架源码研读一:前后端交互》),让大家对Odoo整体结构和前后端交互有了更深刻的了解。
而Odoo在实际开发的大多数场景都是基于它的ORM框架进行的,所以本期我们将带来Odoo框架源码的第二期内容——ORM和日志。
一、ORM
Odoo是通过Controller控制器,来控制前后台的交互。上一期我们详细的介绍了如何让请求顺利到达Controller控制器。
那么当请求到达Controller后,又如何来实现后端的业务逻辑呢?这就不得不提到Odoo一个非常强大的类——Environment。
通过_loca属性,Environment可以直接管理线程中的environments上下文状态,并且包装了ORM相关四个属性:
而且Environment还提供了Model name和Model之间的映射,通过self.env[ModelName] 就可以直接调用Model的API ,非常强大。
现在,再回头看Controller中的方法,可以看到,通过request.env[model]可以直接获取对应的Model对象,然后直接调用Model的方法。
Odoo中一切都是基于Model编程。即使是前端的menu、action、view,都是也都有对应 Model,和业务数据无异。
创建一个Model ,然后通过简单的视图配置,那么这个Model对应的CRUD基础功能就已经实现,这些都归功于Odoo对于Model的抽象。
Odoo中的model分为三类:AbstractModel、Model、TransientModel;
继承关系如下图 ⬇
从源码中可以看出AbstractModel 是Model 和TransientModel的父类。而这个三者的区别也主要在_auto、_register、_abstract、_transient这四个属性上。
由此可以AbstractModel是抽象类,不会在数据库创建表,Model和TransientModel 不是抽象类,会在数据库建表,但TransientModel建的是临时表,数据会被系统定期清除,这个可以在系统中设置清除频率。
由于这种特性的不同,三个Model的用途也不相同。
TransientModel由于存临时表的特性,多用来做wizard向导视图,存储临时缓存数据;
Model多用于做业务的主要Model,AbstractModel多用来抽象做父类,由于不创建表的特性,有时也会用来做向导视图。
新模块中的Model,根据功能需要去继承这三个类,由于这三个父类中丰富的API方法,新建 Model在创建完字段后,功能就已经基本完善,如果有定制化的逻辑,只需要重写父类的方法就可以了。
Model中的Field不是Python的基础类型,而是继承Odoo封装的Field类。
因此,在Model字段赋值的时候,和基础类型字段不同,会调用Field中的API方法,这是容易踩坑的地方。
二、日志
Odoo的日志是在Python的logging基础模块之上,做了定制化的封装和配置。这部份代码主要在odoo/netsvc.py文件中。
Odoo定义了自己的Filter对象、Formatter对象、以及Handler对象。
1)项目启动的时候,配置管理器configmanager初始化,这个时候会去初始化默认的系统配置,包括日志模块。
2)随后,配置管理器会去加载配置文件odoo.conf中的自定义配置覆盖原先的默认配置。
3)最后,处理完配置加载,Odoo会调用日志初始化代码,根据最终的日志配置去设定相关的logger对象。
上图即为Odoo日志的默认配置。
初始化过程:
通过logging.logging.getLogger(_name_)调用前包层级的logger 对象,logging.logging.getLogger() 则返回root logger对象。
本期关于Odoo的ORM和日志就聊到这里,下一期我们会继续聊一下Odoo的异常和流程引擎,感兴趣的小伙伴记得关注我~
iBATIS框架源码剖析内容简介
本书以深入剖析iBATIS框架为核心内容,分为三个部分。首先,第一章将带领读者回顾iBATIS的基础知识,为后续深入理解奠定基础。 第二部分,读者将了解到iBATIS DAO框架的结构及其实现原理,包括框架的核心组件和工作流程。这一部分详细解释了DAO的构建和如何与数据库交互。 重中之重的是第三部分,主要聚焦于iBATIS的底层平台——iBATIS SQL Map。首先,我们会揭示SQL Map如何解析和加载配置信息,展示配置管理的关键环节。接着,深入探讨SQL Map引擎的运作机制,以及它如何构建出独特的框架结构,涉及核心实现步骤和事务管理、数据库连接池等关键功能。 此外,还会剖析SQL Map中Mapping的实现,这是iBATIS区别于其他ORM框架的独特之处。讲解如何通过TypeHandler进行类型转换,以及iBATIS常用工具的运用,帮助读者掌握核心技术。 在源码解析的过程中,作者采用代码注释、UML分析、设计模式的运用以及实际案例的讲解,全方位展示iBATIS的实现策略和编程技巧。这不仅有助于读者理解开发者的思维模式,也为他们在实际项目开发中提供有价值的参考和实践指导。 本书特别适合软件设计师、架构师以及具备扎实Java基础的开发者,无论是作为iBATIS学习的参考资料,还是在设计阶段的决策支持,都能从中获益匪浅。扩展资料
iBATIS是一种比较流行的ORM框架,本书全面介绍其结构体系和分析其源程序代码,该框架的核心包括两个组件,一个是iBATIS DAO,另一个是iBATIS SQL Map。gorm 垃圾么?
深入探讨:Gorm ORM框架:效能与底层实现 Gorm,由知名开发者jinzhu开发,凭借其强大的orm映射功能,使得Go语言中的数据库操作如同操作本地对象般直观。本文将从v1..5版本出发,深入解析Gorm的底层设计,涉及初始化DB、数据操作、源码剖析和事务管理,旨在揭示其高效而简洁的架构。1. 数据操作实践
从基础数据操作开始,让我们逐个探索Gorm的威力:创建: db.Create(&r) - Test_create函数演示了如何利用Gorm的API快速创建数据。
删除: db.Delete(&r, 1) - Test_delete展示了删除数据的简洁过程。
更新: db.Where("id = ?", 2).Update(&r) - Test_update揭示了如何根据条件进行更新。
事务: db.Transaction(do) - Test_tx演示了事务处理的无缝集成。
2. 核心组件解析
Gorm的核心在于其DB类,它是操作的基石。它包含Config、Error、RowsAffected等字段,以及关键的Statement和Schema。Statement是会话状态的核心,存储操作信息和数据库连接池。在克隆DB时,会确保Statement的状态得以传递。 3. 源码揭秘2.1 初始DB构建: gorm.Open - 创建DB实例,包括配置、Dialector和回调函数的初始化。
2.2 预处理模式:PreparedStmtDB封装了数据库操作,提供更高效的SQL执行。
2.3 执行器与processor:通过回调执行各种操作,如创建、查询等。
2.4 Statement的构建与执行:动态生成SQL,确保操作的灵活性。
深入理解
4.1 CRUD操作的处理器设计:每个操作都有其特定的处理器,如Create、Query、Delete和Update,它们遵循特定的流程和函数链。 5. 数据操作流程:从db.Create到db.Delete,每个操作的执行路径和细节都精心设计,确保效率与一致性。 6. 事务管理:在Gorm中,事务是透明的,用户只需提供一个闭包,Gorm会自动处理事务的开启、提交或回滚。结论
通过本文,我们不仅了解了Gorm的使用方法,还深入理解了其底层架构。ORM的优雅设计让Go开发者在数据库操作上省去繁琐的SQL编写,提高了开发效率。继续深入学习,探索更多Go语言与数据库的精彩结合。 文末福利:关注“小徐先生”和“小徐先生的编程世界”获取更多编程知识和实战解析。