phpgt / sqlbuilder
SQL查询的对象化表示。
Requires
- php: >=8.0
Requires (Dev)
- phpmd/phpmd: ^2.13
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.3
- squizlabs/php_codesniffer: ^3.7
This package is auto-updated.
Last update: 2024-09-22 00:14:43 UTC
README
此库不生成任何SQL,而是提供了SQL查询的对象化表示,允许开发者在定义查询结构的同时获得继承的好处。
当PHP应用程序达到一定规模时,数据库往往是性能瓶颈。当查询代表开发者生成时,它们往往难以优化,因为失去了控制。使用SqlBuilder,开发者始终控制着原始SQL。
示例用法:表示SELECT查询的类
想象一个典型的数据库应用程序,使用一个用于存储每个学生详细信息的student
表。一个基本的查询可能看起来像这样
select id, forename, surname, dateOfBirth from student
上述查询将返回所有学生的列表。问题是,当你需要再次从学生表中选取数据时,这次添加了诸如年龄范围或按姓氏排序等约束条件,整个查询需要重复,而只需更改原始查询的一小部分。
相反,可以使用以下类来表示上述查询
class StudentSelect extends SelectQuery { public function select():array { return [ "id", "forename", "surname", "dateOfBirth", ]; } public function from():array { return [ "student", ]; } }
上述类的__toString
方法将产生与原始查询相同的SQL。
现在,要编写另一个查询以返回特定年龄的学生
class StudentSelectByAge extends StudentSelect { public function where():array { return [ "year(now()) - year(dateOfBirth) = :age", ]; } }
示例用法:构建SELECT查询的流畅类(v2版本中提供)
如上例所示,SqlQuery
函数始终返回表达式数组。SqlBuilder
类具有相同的方法(select
、from
、where
等),但将表达式作为参数,充当一个流畅接口。
用流畅语法创建与上例相同的查询
$selectQuery = new SelectBuilder( "id", "forename", "surname", "dateOfBirth" )->from( "student" )->where( "year(now()) - year(dateOfBirth) = :age" );
这特别有用,当你有一个基础查询,比如StudentSelect
,而你的代码只需要一个额外的条件。无需为这种单次使用创建一个单独的类,可以将其内联调用
// Start by using a base StudentSelect, then add a single inline condition to it. $studentSelect = new StudentSelect(); $selectQuery = new SelectBuilder($studentSelect) ->where( "year(now()) - year(dateOfBirth) = :age" );
条件
在where
和having
子句中的表达式可以通过逻辑运算符连接,通常可以组合。为了防止逻辑错误,使用Condition
对象来指定逻辑的优先级。
例如,要选择具有特定年龄和性别的学生
class StudentSelectByAge extends StudentSelect { public function where():array { return [ new AndCondition("year(now()) - year(dateOfBirth) = :age"), new AndCondition("gender = :gender"), ]; } }
子查询
SqlQuery
对象具有一个__toString()
函数,而SqlBuilder
结果创建SqlQuery
实例。因此,它们可以在查询或构建器的任何其他表达式中使用。
纯SQL的限制
纯SQL提供的唯一工具,可用于编写DRY代码是视图和存储过程,两者在编写整洁和可维护的代码时都有自己的局限性。
此库提供的解决方案是将SQL查询分解为其不同的部分,由PHP类表示,这些类可以由其他类扩展,同时仍然保留表示的纯SQL。
SQL兼容性
这个库在设计上不提供任何SQL处理能力。任何特定于驱动程序的SQL用法将与其他驱动程序不兼容。这允许开发者完全利用他们选择的SQL驱动程序,而不是生成通用的 SQL。