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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 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进行简单的分析。



相关文章
|
6天前
|
SQL 关系型数据库 MySQL
学成在线笔记+踩坑(3)——【内容模块】课程分类查询、课程增改删、课程计划增删改查,统一异常处理+JSR303校验
课程分类查询、课程新增、统一异常处理、统一封装结果类、JSR303校验、修改课程、查询课程计划、新增/修改课程计划
学成在线笔记+踩坑(3)——【内容模块】课程分类查询、课程增改删、课程计划增删改查,统一异常处理+JSR303校验
|
6天前
|
前端开发 应用服务中间件 API
|
14天前
|
存储 关系型数据库 MySQL
如何优化数据库查询?
如何优化数据库查询?
33 1
|
6天前
|
SQL 存储 数据库
MSSQL遍历数据库根据列值查询数据
【9月更文挑战第12天】在 SQL Server 中,可以通过游标或临时表遍历数据库并根据列值查询数据。示例展示了如何创建临时表存储数据库名,并通过循环遍历这些名称来执行特定查询。需替换 `YourTableName`、`YourColumnName` 和 `YourValue` 为实际值。此方法要求有足够权限访问各数据库。若无跨库权限,需分别执行查询。
|
7天前
|
SQL 关系型数据库 MySQL
MySQL技术安装配置、数据库与表的设计、数据操作解析
MySQL,作为最流行的关系型数据库管理系统之一,在WEB应用领域中占据着举足轻重的地位。本文将从MySQL的基本概念、安装配置、数据库与表的设计、数据操作解析,并通过具体的代码示例展示如何在实际项目中应用MySQL。
33 0
|
19天前
|
存储 C# 关系型数据库
“云端融合:WPF应用无缝对接Azure与AWS——从Blob存储到RDS数据库,全面解析跨平台云服务集成的最佳实践”
【8月更文挑战第31天】本文探讨了如何将Windows Presentation Foundation(WPF)应用与Microsoft Azure和Amazon Web Services(AWS)两大主流云平台无缝集成。通过具体示例代码展示了如何利用Azure Blob Storage存储非结构化数据、Azure Cosmos DB进行分布式数据库操作;同时介绍了如何借助Amazon S3实现大规模数据存储及通过Amazon RDS简化数据库管理。这不仅提升了WPF应用的可扩展性和可用性,还降低了基础设施成本。
42 0
|
19天前
|
Java 数据库连接 数据库
AI 时代风起云涌,Hibernate 实体映射引领数据库高效之路,最佳实践与陷阱全解析!
【8月更文挑战第31天】Hibernate 是一款强大的 Java 持久化框架,可将 Java 对象映射到关系数据库表中。本文通过代码示例详细介绍了 Hibernate 实体映射的最佳实践,包括合理使用关联映射(如 `@OneToMany` 和 `@ManyToOne`)以及正确处理继承关系(如单表继承)。此外,还探讨了常见陷阱,例如循环依赖可能导致的无限递归问题,并提供了使用 `@JsonIgnore` 等注解来避免此类问题的方法。通过遵循这些最佳实践,可以显著提升开发效率和数据库操作性能。
41 0
|
19天前
|
SQL 数据库 Java
HQL vs SQL:谁将统治数据库查询的未来?揭秘Hibernate的神秘力量!
【8月更文挑战第31天】Hibernate查询语言(HQL)是一种面向对象的查询语言,它模仿了SQL的语法,但操作对象为持久化类及其属性,而非数据库表和列。HQL具有类型安全、易于维护等优点,支持面向对象的高级特性,内置大量函数,可灵活处理查询结果。下面通过示例对比HQL与SQL,展示HQL在实际应用中的优势。例如,HQL查询“从员工表中筛选年龄大于30岁的员工”只需简单地表示为 `FROM Employee e WHERE e.age > 30`,而在SQL中则需明确指定表名和列名。此外,HQL在处理关联查询时也更为直观易懂。然而,对于某些复杂的数据库操作,SQL仍有其独特优势。
26 0
|
19天前
|
API Java 数据库连接
从平凡到卓越:Hibernate Criteria API 让你的数据库查询瞬间高大上,彻底告别复杂SQL!
【8月更文挑战第31天】构建复杂查询是数据库应用开发中的常见需求。Hibernate 的 Criteria API 以其强大和灵活的特点,允许开发者以面向对象的方式构建查询逻辑,同时具备 SQL 的表达力。本文将介绍 Criteria API 的基本用法并通过示例展示其实际应用。此 API 通过 API 构建查询条件而非直接编写查询语句,提高了代码的可读性和安全性。无论是简单的条件过滤还是复杂的分页和连接查询,Criteria API 均能胜任,有助于提升开发效率和应用的健壮性。
34 0
|
19天前
|
Java UED 开发者
当错误遇上Struts 2:一场优雅的异常处理盛宴,如何让错误信息成为用户体验的救星?
【8月更文挑战第31天】在Web应用开发中,异常处理对确保用户体验和系统稳定性至关重要。Struts 2 提供了完善的异常处理机制,包括 `exception` 拦截器、`ActionSupport` 类以及 OGNL 表达式,帮助开发者优雅地捕获和展示错误信息。本文详细介绍了 Struts 2 的异常处理策略,涵盖拦截器配置、错误信息展示及自定义全局异常处理器的实现方法,使应用程序更加健壮和用户友好。
30 0

热门文章

最新文章

推荐镜像

更多