ThinkPHP数据库查询之Db类深度解析(3)

简介: ThinkPHP数据库查询之Db类深度解析

三、Db类库巧妙结合连接器、查询器、sql生成器使用

在上目录中咔咔使用了query作为案例演示,这个使用在框架中是不建议使用的,因为在维护的方面会有一定的难度。


本节案例将会使用框架常用的查询数据库方式进行查询。


image.png


在上图中可以看到使用了平时最常用的查询方式,接下来将会对这组案例进行详细分析。


同样代码会来到Db类的__callStatic这个方法,这个方法就是在调用没有声明的静态方法会进行执行的。


这个方法跟__call方法是有区别的,__call方法是调用不存在的方法会进行调用,一定要注意俩者的区别。


image.png


对于上图方法中static::connect()执行最后会返回 object(think\db\Query)这个对象,至于内部流程的执行可以参考第二目录的内容。


所以执行流程会来到thinkphp/library/think/db/Query.php这个类的table方法。


参数就是table中传递的数据库表名tp_test。


image.png


按照上图提供的代码会对传递过来的表名进行三次判断。


  • 第一次判断是否为字符串
  • 第二次判断是否存在 )
  • 第三次判断是否存在 ,

根据传递过来的字符串以上三个判断均不成立,于是会执行到下面流程。


在table这个方法中可以看到最后的执行流程就是将传递过来的表名存放在属性options这个里边。


image.png


并且最后会将think\db\Query Object这个对象进行返回。


image.png


where方法解析


table方法分析完成后会紧接着执行where方法,同样还是在类thinkphp/library/think/db/Query.php


image.png


上图中在这个类中可以看到一个方法func_get_args,这个方法会返回一个包含函数参数列表的数组。


这个方法平时都是跟call_user_func_array同时使用,之前咔咔也使用这俩个方法进行过一次案例实验。


然后会使用函数array_shift删除数组中的第一个元素(red),并返回被删除元素的值。


下图第一个结果为func_get_args这个方法获取出来的数据,第二组结果为array_shift这个方法返回的结果。


俩组结果返回的值可以进行对比一下,可以更好的理解array_shift的使用场景。


image.png


紧接着会进行分析查询表达式,也就是方法parseWhereExp做的事情。


在这个方法中需要注意一个点就是关于传递过来的这俩个参数。


参数一为查询逻辑,参数二就是在使用案例时传入的参数。


image.png


在代码的第一行就需要我们来学习的一个知识点instanceof。


instanceof可以判断某个对象是否是某个类的实例,判断一个对象是否实现了某个接口。


关于这个的使用案例在文章ThinkPHP源码解析之控制器这一文中做了详细的说明。


根据学习instanceof的作用可以清晰的明白第一个判断不会进行执行。


在继续学习以下的执行流程,根据咔咔圈出来的框来进行对代码进行简单的解析。


image.png


根据上图首先会对查询逻辑的符号全部转为小写


然后在进行判断$field instanceof Where传递过来的参数是否为Where类的实例。


最后一个判断就是$field instanceof Expression跟上一步是判断同样的功能。


所以说代码最终的执行逻辑就是下图圈到的部分。


image.png


还记得在案例过程中给where传递的参数就是一个数组。


如果将参数改为where('t_id',1)则就会走is_string($field)的这个流程,这个流程就交给大家了,咔咔就不去解析。


这里咔咔还是使用数组作为参数进行解析,那么代码依然会执行本类的parseArrayWhereItems这个方法


image.png


在这个方法中先需要知道key会返回什么,从当前内部指针位置返回元素键名。


所以代码会去执行if语句的判断,根据上边的所有判断都不符合所以会执行这段代码$where[] = [$key, is_array($val) ? 'IN' : '=', $val];


这段代码会判断循环数组的value值是否为数组,如果为数组就是in,反之为=,由于value为1所以数组的第二个值为=。


那么最终where的值就是下图打印的数据。


image.png


由于where不为空,代码执行流程会执行到下图位置,最终在返回本类实例。


image.png


find()执行流程


接着代码会还是执行本类的find方法,查找单条记录。


由于find中是没有传递参数的,所以代码会执行到$this->parseOptions();分析表达式(可用于查询或者写入操作)


就目前写的案例而言,这段看似很长的代码大家好好看看都可以看明白,最终依然是返回当前的所有参数。



image.png

以下就是返回的所以结果


image.png


真正的查询数据是这块代码$result = $this->connection->find($this);,这段代码会执行到文件thinkphp/library/think/db/Connection.php


从这块代码可以看到当查询一条数据时框架默认给加上了limit为1,至于为什么这么加你就需要查看一下sql优化方面的知识了。

image.png



在这里就是关于sql语句的生成,代码自己好好看看就会明白,咔咔解析的只是执行流程和具体代码简单的了解一下即可。


至于具体实现流程咔咔在后期如果有机会会单独把每个方法进行深度解析,那时就是主要针对代码的解析。


image.png


最终返回结果如下


image.png


以上就是关于Db在结合连接器,查询器,生成器实现的数据库查询功能。


截止到这里关于Db的场景就分析到这里,接下来咔咔将会对Model进行简单的分析。



相关文章
|
Java 开发者
重学Java基础篇—Java类加载顺序深度解析
本文全面解析Java类的生命周期与加载顺序,涵盖从加载到卸载的七个阶段,并深入探讨初始化阶段的执行规则。通过单类、继承体系的实例分析,明确静态与实例初始化的顺序。同时,列举六种触发初始化的场景及特殊场景处理(如接口初始化)。提供类加载完整流程图与记忆口诀,助于理解复杂初始化逻辑。此外,针对空指针异常等问题提出排查方案,并给出最佳实践建议,帮助开发者优化程序设计、定位BUG及理解框架机制。最后扩展讲解类加载器层次与双亲委派机制,为深入研究奠定基础。
510 0
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
12月前
|
存储 缓存 自然语言处理
评论功能开发全解析:从数据库设计到多语言实现-优雅草卓伊凡
评论功能开发全解析:从数据库设计到多语言实现-优雅草卓伊凡
359 8
评论功能开发全解析:从数据库设计到多语言实现-优雅草卓伊凡
|
11月前
|
存储 关系型数据库 数据库
高性能云盘:一文解析RDS数据库存储架构升级
性能、成本、弹性,是客户实际使用数据库过程中关注的三个重要方面。RDS业界率先推出的高性能云盘(原通用云盘),是PaaS层和IaaS层的深度融合的技术最佳实践,通过使用不同的存储介质,为客户提供同时满足低成本、低延迟、高持久性的体验。
|
存储 监控 安全
重学Java基础篇—类的生命周期深度解析
本文全面解析了Java类的生命周期,涵盖加载、验证、准备、解析、初始化、使用及卸载七个关键阶段。通过分阶段执行机制详解(如加载阶段的触发条件与技术实现),结合方法调用机制、内存回收保护等使用阶段特性,以及卸载条件和特殊场景处理,帮助开发者深入理解JVM运作原理。同时,文章探讨了性能优化建议、典型异常处理及新一代JVM特性(如元空间与模块化系统)。总结中强调安全优先、延迟加载与动态扩展的设计思想,并提供开发建议与进阶方向,助力解决性能调优、内存泄漏排查及框架设计等问题。
591 5
|
安全 IDE Java
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
463 1
|
Java 数据库 开发者
详细介绍SpringBoot启动流程及配置类解析原理
通过对 Spring Boot 启动流程及配置类解析原理的深入分析,我们可以看到 Spring Boot 在启动时的灵活性和可扩展性。理解这些机制不仅有助于开发者更好地使用 Spring Boot 进行应用开发,还能够在面对问题时,迅速定位和解决问题。希望本文能为您在 Spring Boot 开发过程中提供有效的指导和帮助。
2144 12
|
传感器 监控 Java
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
552 5
|
机器学习/深度学习 人工智能 监控
鸿蒙赋能智慧物流:AI类目标签技术深度解析与实践
在数字化浪潮下,物流行业面临变革,传统模式的局限性凸显。AI技术为物流转型升级注入动力。本文聚焦HarmonyOS NEXT API 12及以上版本,探讨如何利用AI类目标签技术提升智慧物流效率、准确性和成本控制。通过高效数据处理、实时监控和动态调整,AI技术显著优于传统方式。鸿蒙系统的分布式软总线技术和隐私保护机制为智慧物流提供了坚实基础。从仓储管理到运输监控再到配送优化,AI类目标签技术助力物流全流程智能化,提高客户满意度并降低成本。开发者可借助深度学习框架和鸿蒙系统特性,开发创新应用,推动物流行业智能化升级。
464 1
|
安全 编译器 C语言
【C++篇】深度解析类与对象(中)
在上一篇博客中,我们学习了C++类与对象的基础内容。这一次,我们将深入探讨C++类的关键特性,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载、以及取地址运算符的重载。这些内容是理解面向对象编程的关键,也帮助我们更好地掌握C++内存管理的细节和编码的高级技巧。

热门文章

最新文章

推荐镜像

更多
  • DNS