摘要:而在项目开发中,我们想要的是一个更好用的可维护的工具,此时,对代码的封装模块化就显得尤为重要,于是出现了两种方案查询构造器,对象关系映射。典型环境下按照一般的查询构造器处理就行。
文章目录
写一个“特殊”的查询构造器 - (前言)
写一个“特殊”的查询构造器 - (一、程序结构,基础封装)
写一个“特殊”的查询构造器 - (二、第一条语句)
写一个“特殊”的查询构造器 - (三、条件查询)
写一个“特殊”的查询构造器 - (四、条件查询:复杂条件)
写一个“特殊”的查询构造器 - (五、聚合函数、分组、排序、分页)
写一个“特殊”的查询构造器 - (六、关联)
写一个“特殊”的查询构造器 - (七、DML 语句、事务)
写一个“特殊”的查询构造器 - (八、单元测试、收尾工作)
更新此项目已经从 WorkerA 中拆分为独立项目,完整代码请到 wazsmwazsm/DB 中查看。
前言对于后端程序员来说,数据库操作是必备知识,对数据的增删查改也是业务中最普遍、频繁的操作。
对于关系型数据库,如 Mysql、Postgresql 等,我们可以使用 SQL (Structured Query Language) 来操作我们的数据,如 “SELECT * FROM test;” 这类的 SQL 语句,大部分的编程语言如 PHP、Python、go 等都提供了相应的数据库扩展,可以方便的进行数据库连接、执行 SQL 获取结果。
但是,直接使用基础的扩展效率并不高,每次都要创建连接、手动写 SQL、对执行结果进行判断、将查询得到的数据进行处理等,代码的重用性和维护性并不是很好,在多人开发的时候更是不能保证代码质量。而在项目开发中,我们想要的是一个更好用的可维护的工具,此时,对代码的封装、模块化就显得尤为重要,于是出现了两种方案:查询构造器,对象关系映射。
查询构造器 (query builder),顾名思义,它的目的就是以简便的形式构造、执行 SQL,为查询数据库的业务提供了方便好用的接口,一些知名的 web 框架如 PHP 的 Laravel、CodeIgniter、ThinkPHP 等都提供了好用的查询构造器。
对象关系映射 (ORM) 是一种更面向对象的数据模型化操作,将数据库的数据映射成对象模型,数据库的直接操作对开发者透明,开发者只需关注对象模型即可,更符合面向对象程序思维。同样,很多框架也提供了 ORM 的方式去操作数据。
为什么要写查询构造器,我的需求是什么写这个查询构造器的起因是 workerman,一个由 PHP 编写的、可以常驻内存的 Socket 框架。
当时选用 workerman 去做一个 webAPI 的项目,针对 workerman 的环境编写了一个简单的 http 框架 WorkerA,一是没有找到合适的 (在一个非典型 web 环境中,想要一个类似 laravel 那样方便的查询构造器),二是想要锻炼自己,于是选择了自己去写这个查询构造器。
如今该查询构造器已经完工,完整代码在我的框架核心代码中: 查看
Q&AQ:为什么选择查询构造器而不是 ORM
A:对于我自己的需求,我需要一个简单好用又快速的工具,ORM 的性能和复杂性显然不合适。
Q:该查询构造器“特殊”在何处
A:区别于典型 web 的一次 HTTP 请求的代码运行周期,这个查询构造器除了可以使用在普通的 web 环境中,还支持常驻内存的环境,支持断线重连 (这个很重要)
Q:为什么选 PHP
A:因为我自己用 PHP 开发最多,重要的是 workerman 是 PHP 编写的。
Q:支持哪些数据库
A:目前支持了 Mysql、Postgresql、Sqlite 这三个数据库,而且全部通过了单元测试
Q:好的使用实践?
A:我在 workerman 的环境中使用的是单例模式,每个进程一个数据库连接单例模型。典型 web 环境下按照一般的查询构造器处理就行。同样常驻内存的情景可以自己写链接池之类的功能,当然这和查询构造器本身没有关系,一切由你的需求来决定。
需求和技术的选择 (想想自己想要什么)底层驱动的选择:
php 提供了 mysql 和 pgsql 这些常用数据库的扩展,但是每个扩展暴露出的接口都不大一样,封装不便,pass
php 的 PDO 提供了多种数据库的底层驱动,统一了访问接口,prepare 方法可以有效的防止 SQL 注入,就选它
错误异常处理:
使用 PHP 的 try catch 机制,使用内置的异常和 PDO 的异常进行异常抛出
代码结构的设计:
查询构造器要支持多个数据库,我们要把相同的部分 (查询等) 封装起来,将不同的部分 (不同数据库的连接和设置) 独立开来,那么只需创建一个基类 (封装 PDO 的操作),每个数据库多带带建立一个类继承基类,将各自差异的部分重写即可。
SQL 的构建:
sql 的构建属于字符串的操作,构建 sql 即是构造字符串,PHP 有丰富的字符串处理函数
好用和性能的均衡考虑:
有些工具好用但是性能不一定好 (比如正则表达式),当然并不是说为了语言层面的极致性能而放弃一些便易性,查询构造器的瓶颈一般在于连接数据库的网络消耗和数据库对 SQL 的执行上。那么我们就以此作为平衡点,只要不比平衡点慢,我们可以选择更方便开发的方式写代码。
测试:
选择 phpunit 作为单元测试工具,以可测试为前提拆分代码为最小单元,提升代码的可维护性
总体思路进行相关的需求分析和技术选择后,我们得出了构建查询构造器的大概的思路:
基于 PDO
通过字符串操作构建 SQL
将构造好的字符串交给 PDO 执行,获取结果
以继承、重写的模式搭建代码的架子
错误异常处理
编写单元测试
理清思路,开始干活。
(本系列文章默认您已经掌握 PHP、PDO、SQL 的基础知识)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/28695.html
摘要:构造条件如果单单是执行这样的语句,使用原生扩展就好了,使用查询构造器就是杀鸡用牛刀。这一篇,我们来讲讲如何使用查询构造器进行条件查询。 构造 where 条件 如果单单是执行 SELECT * FROM test_table; 这样的语句,使用原生扩展就好了,使用查询构造器就是杀鸡用牛刀。当然,在实际的业务需求中,大部分的 SQL 都没这么简单,有各种条件查询、分组、排序、连表等操作,...
摘要:我们做代码审计之前选好工具也是十分必要的。一审计工具介绍代码审计系统功能介绍是一款基于开发的针对代码安全审计的软件。自定义审计规则。黑盒敏感信息泄露一键审计。挖掘这种漏洞主要是检查是否使用了,搜索和。 GitChat 作者:汤青松原文:PHP 开发者如何做代码审查?关注微信公众号:「GitChat 技术杂谈」 一本正经的讲技术 【不要错过文末彩蛋】 前言 工欲善其事,必先利其器。我们做...
摘要:单元测试的好处是给开发人员的,并不是给机器的。对于查询构造器这个项目,我们可以让其在远程运行环境安装相关数据库软件,执行数据表建立,数据导入,执行单元测试等操作。查询构造器的完整代码查询构造器的单元测试完整代码。 debug 模式 对查询构造器进行调试并不难,从其构造 SQL -> 数据绑定 -> SQL 执行的过程中就能发现,要方便调试,只要可以观察以下信息: 构造的 SQL 绑定...
摘要:虽然现在这样的情况已经很少,但是对于查询构造器而言,还是要提供一个方便的方法来对表前缀进行设置,特别是当你没有权限修改表名的时候。所以我们将表前缀作为一个配置参数传入查询构造器,在查询构造器的底层进行自动前缀添加。 关联查询是关系型数据库典型的查询语句,根据两个或多个表中的列之间的关系,从这些表中查询数据。在 SQL 标准中使用 JOIN 和 ON 关键字来实现关联查询。 Join 子...
摘要:聚合函数在中,有一些用来统计汇总的函数,被称作聚合函数,如等。方法其它方法如之类的编写就不一一展示了,代码请看聚合函数。如何获取总数当然是使用上面讲到的聚合函数来处理。 where 相关的子句构造完成后,我们继续构造其它子句。这一篇我们进行聚合函数、分组、排序等子句的构造。 聚合函数 在 SQL 中,有一些用来统计、汇总的函数,被称作聚合函数,如 SUM、COUNT、AVG 等。 使用...
阅读 2701·2023-04-25 14:59
阅读 888·2021-11-22 11:59
阅读 635·2021-11-17 09:33
阅读 2468·2021-09-27 13:34
阅读 3897·2021-09-09 11:55
阅读 2320·2019-08-30 15:44
阅读 1123·2019-08-30 14:06
阅读 1924·2019-08-29 16:55