dilovanmatini/query-builder

允许 PHP 开发者构建类似于本地语言语法的 SQL 查询

v1.0.5 2023-07-14 19:26 UTC

This package is auto-updated.

Last update: 2024-09-14 22:14:19 UTC


README

允许 PHP 开发者构建类似于本地语言语法的 SQL 查询。

要求

  • PHP >= 8.1
  • PDO PHP 扩展

安装

composer require dilovanmatini/query-builder

使用

使用 PDO 实例

<?php

use Database\QueryBuilder\QB;

require_once __DIR__ . '/vendor/autoload.php';

QB::config([
    'connection' => $conn // PDO instance
]);

$user = QB::select('id, name, email')->from('users')->where('id', 1)->and('status', 1)->fetch();

echo $user->name;

在 Laravel 中

<?php

use Database\QueryBuilder\QB;

$user = QB::select('id, name, email')->from(User::class)->where('id', 1)->and('status', 1)->fetch();

echo $user->name;

在 Laravel 中,连接会自动检测。您不需要设置它。

使用数据库凭据

<?php

use Database\QueryBuilder\QB;

require_once __DIR__ . '/vendor/autoload.php';

QB::config([
    'host' => 'localhost',
    'database' => 'test',
    'username' => 'root',
    'password' => '',
]);

$user = QB::select('id, name, email')->from('users')->where('id', 1)->and('status', 1)->fetch();

echo $user->name;

配置

如果您设置了有效的 connection,则不需要设置 hostportdatabaseusernamepasswordcharset 选项。


文档

选择

select() 方法用于向查询添加 SELECT 子句,以指定要从数据库中检索哪些列。 select() 方法接受列的列表作为参数,因此您可以以逗号分隔的列表或数组的形式传递列。

要检索表中的所有列,您可以使用不带任何参数的 select() 方法。

$user = QB::select()->from('users');
SELECT * FROM users

注意: 第二段代码是第一段代码生成的 SQL 代码。


要检索单个列,请将列名作为 select() 方法的第一个参数传递。

$name = QB::select('name')->from('users');
SELECT name FROM users

要检索多个列,请将列名作为数组传递给 select() 方法。

$user = QB::select(['id', 'name', 'email'])->from('users');
SELECT id, name, email FROM users

或者,您可以将列作为逗号分隔的列表传递给 select() 方法。

$user = QB::select('id, name, email')->from('users');
SELECT id, name, email FROM users

单个查询中多次使用 select()

$user = QB::select([
        'u.id'
        QB::alias('u', [
            'name',
            'email',
        ]),
        QB::if('u.status = 1', 'active', 'inactive')->as('status'),
        QB::count('p.*')->as('count'),
    ], 'u.join_date')
    ->from('users AS u')
    ->leftJoin('posts')->as('p')->on('p.user_id', 'u.id');
SELECT
    u.id,
    u.name,
    u.email,
    IF(u.status = 1, 'active', 'inactive') AS status,
    COUNT(p.*) AS count,
    u.join_date
FROM users AS u
LEFT JOIN posts AS p ON p.user_id = u.id

select() 有一些辅助函数,使其更容易编写查询

别名

alias() 方法用于为列添加别名。 alias() 方法接受两个参数。第一个参数是别名名称,第二个参数是列的列表。

$user = QB::select([
        QB::alias('u', [
            'name',
            'email',
        ]),
    ])
    ->from('users AS u');
SELECT u.name, u.email FROM users AS u

计数

count() 方法用于将 COUNT() 函数添加到查询中。 count() 方法接受两个参数。第一个参数是列名,第二个参数是可选的,用于指定列的别名。

您也可以使用 as() 方法代替将别名作为第二个参数传递。

$user = QB::select([
        QB::count('p.*')->as('count'),
    ])
    ->from('users AS u')
    ->leftJoin('posts')->as('p')->on('p.user_id', 'u.id');
SELECT COUNT(p.*) AS count FROM users AS u LEFT JOIN posts AS p ON p.user_id = u.id

同样的方法适用于 summinmaxavg 方法。


from() 方法用于向查询添加 FROM 子句,以指定要从中检索数据的表。 from() 方法接受一个字符串变量或一个模型类名作为其第一个参数。第二个参数是可选的,用于指定表的别名。

$user = QB::select()->from('users');
SELECT * FROM users

或使用 Model 类名 针对使用 MVC 框架(如 Laravel)的开发者

$user = QB::select()->from(User::class);
SELECT * FROM users

您还可以将表的别名作为第二个参数传递给 from() 方法。

$user = QB::select()->from('users', 'u');
SELECT * FROM users AS u

或使用 as() 方法

$user = QB::select()->from('users')->as('u');
SELECT * FROM users AS u

连接

连接方法用于在查询中连接表。

《leftJoin()》、《rightJoin()》、《crossJoin()》、《innerJoin》、《fullJoin()》方法接受表名作为第一个参数,将表别名作为第二个参数。您可以使用as()方法代替第二个参数传递别名。

如果您没有为表提供别名,当查询中有多个表时,表名将用作别名。

$user = QB::select()
        ->from('users')->as('u')
        ->leftJoin('posts')->as('p');
SELECT u.* FROM users AS u LEFT JOIN posts AS p

您还可以使用on()方法来指定连接条件。

$user = QB::select()
        ->from('users')->as('u')
        ->leftJoin('posts')->as('p')->on('u.id', 'p.user_id');
SELECT u.* FROM users AS u LEFT JOIN posts AS p ON u.id = p.user_id

在查询中使用多个连接。

$user = QB::select()
        ->from('users')->as('u')
        ->leftJoin('posts')->as('p')->on('u.id', 'p.user_id')
        ->leftJoin('comments')->as('c')->on('c.post_id', 'p.id');
SELECT u.*
FROM users AS u
LEFT JOIN posts AS p ON u.id = p.user_id
LEFT JOIN comments AS c ON c.post_id = p.id

条件

where()方法用于向查询添加WHERE子句。where()方法接受三个参数。第一个参数是必需的,其他参数是可选的。

如果您将仅一个参数传递给where()方法,它将被视为由列名、运算符和值组成的完整条件。

如果您将两个参数传递给where()方法,第一个参数将被视为列名,第二个参数将被视为值。默认运算符为=

如果您将三个参数传递给where()方法,第一个参数将被视为列名,第二个参数将被视为运算符,第三个参数将被视为值。


仅使用一个参数的示例

$user = QB::select()->from('users')->where('id = 1');
SELECT * FROM users WHERE id = 1

使用两个参数的示例

$user = QB::select()->from('users')->where('id', 1);
SELECT * FROM users WHERE id = 1

使用三个参数的示例

$user = QB::select()->from('users')->where('status', '!=', 0);
SELECT * FROM users WHERE status != 0

注意:如果您想将RAW值作为第二个和第三个参数传递,您应使用QB::raw()方法。


您还可以使用`and()`和`or()`方法向`WHERE`子句添加更多条件。

使用and()方法

$user = QB::select()
        ->from('users')
        ->where('id', 1)
        ->and('status', 1);
SELECT * FROM users WHERE id = 1 AND status = 1

使用or()方法

$user = QB::select()
        ->from('users')
        ->where('skill', 'php')
        ->or('skill', 'javascript');
SELECT * FROM users WHERE skill = 'php' OR skill = 'javascript'

同时使用and()or()方法

$users = QB::select()
        ->from('users')
        ->where('hobie', 'tines')
        ->or('hobie', 'coding')
        ->and('skill', 'php');
SELECT * FROM users WHERE (hobie = 'tines' OR hobie = 'coding') AND skill = 'php'

您可以使用where()and()or()on()having方法来使用分组条件。特别是当您同时使用and()or()方法时。

$user = QB::select()
        ->from('users')
        ->where('id', 1)
        ->and('status', 1)
        ->and(
            QB::where('skill', 'php')->or('skill', 'javascript')
        );
SELECT * FROM users WHERE id = 1 AND status = 1 AND (skill = 'php' OR skill = 'javascript')

Where 辅助方法

where()方法也接受方法辅助器的组,以向查询提供更多灵活性。

Where 辅助方法列表

  • QB::equal( $value )
  • QB::notEqual( $value )
  • QB::lessThan( $value )
  • QB::lessThanOrEqual( $value )
  • QB::greaterThan( $value )
  • QB::greaterThanOrEqual( $value )
  • QB::like( $value )
  • QB::notLike( $value )
  • QB::between( $value1, $value2 )
  • QB::notBetween( $value1, $value2 )
  • QB::in( $values )
  • QB::notIn( $values )
  • QB::isNull()
  • QB::isNotNull()
  • QB::isEmpty()
  • QB::isNotEmpty()

上述所有辅助方法都可以用作where()and()or()on()having方法的第二个或第三个参数。

一些示例

$user = QB::select()
        ->from('users')
        ->where('id', QB::equal(1))
        ->and('status', QB::notEqual(0))
        ->and('skills', QB::in(['php', 'javascript']));
SELECT * FROM users WHERE id = 1 AND status != 0 AND skills IN ('php', 'javascript')

$users = QB::select()
        ->from('users')
        ->where('id', QB::between(1, 10))
        ->and('status', QB::notBetween(0, 5));
SELECT * FROM users WHERE id BETWEEN 1 AND 10 AND status NOT BETWEEN 0 AND 5

$users = QB::select()
        ->from('users')
        ->where('name', QB::like('%john%'))
        ->and('skill', QB::notLike('%script'))
        ->and('birthday', QB::isNotNull())
        ->and('hobie', QB::isNotEmpty());
SELECT *
FROM users
WHERE
    name LIKE '%john%' AND
    skill NOT LIKE '%script' AND
    birthday IS NOT NULL AND
    hobie IS NOT NULL

注意:like()notLike()不会将值作为占位符,因此您可以直接传递值。但如果你想将值作为占位符,您可以使用QB::param()方法传递值。


分组

groupBy()方法用于向查询添加GROUP BY子句。groupBy()方法接受列名列表作为参数。

$users = QB::select()
        ->from('users')
        ->groupBy('skill');
SELECT * FROM users GROUP BY skill

$users = QB::select()
        ->from('users')
        ->groupBy('skill', 'hobie');
SELECT * FROM users GROUP BY skill, hobie

排序

orderBy()方法用于向查询添加ORDER BY子句。orderBy()方法接受多个参数。

如果您没有传递ASCDESC,则默认排序为ASC

$users = QB::select()
        ->from('users')
        ->orderBy('name');
SELECT * FROM users ORDER BY name ASC

$users = QB::select()
        ->from('users')
        ->orderBy('name ASC', 'join_date DESC');
SELECT * FROM users ORDER BY name ASC, join_date DESC

having()方法用于向查询添加HAVING子句。having()方法与where()方法类似。

$users = QB::select()
        ->from('users')
        ->groupBy('skill')
        ->having('COUNT(id)', '>', 10);
SELECT * FROM users GROUP BY skill HAVING COUNT(id) > 10

$users = QB::select()
        ->from('users')
        ->groupBy('skill')
        ->having('COUNT(id)', '>', 10)
        ->and('COUNT(id)', '<', 20);
SELECT * FROM users GROUP BY skill HAVING COUNT(id) > 10 AND COUNT(id) < 20

限制

limit()方法用于向查询添加LIMIT子句。limit()方法接受一个参数。

$users = QB::select()
        ->from('users')
        ->limit(10);
SELECT * FROM users LIMIT 10

您还可以将偏移量作为第二个参数传递。

$users = QB::select()
        ->from('users')
        ->limit(10, 100);
SELECT * FROM users LIMIT 10, 100

偏移

offset()方法用于向查询添加OFFSET子句。offset()方法接受一个参数。

offset()方法必须与limit()方法一起使用。

$users = QB::select()
        ->from('users')
        ->limit(10)
        ->offset(100);
SELECT * FROM users LIMIT 10, 100

Fetch,FetchAll 和 Statement

fetch() 方法用于从数据库中获取数据。fetch() 方法接受一个参数作为获取模式。

默认的获取模式是 PDO::FETCH_OBJ。您可以从 PDO 类中传递任何获取模式。

将数据作为 stdClass 实例对象获取

$user = QB::select()
        ->from('users')
        ->where('id', 1)
        ->fetch();

echo $user->name; // John Doe

当您只想获取一行数据时,可以使用 fetch

将数据作为关联数组获取

$user = QB::select()
        ->from('users')
        ->where('id', 1)
        ->fetch(\PDO::FETCH_ASSOC);

echo $user['name']; // John Doe

fetchAll() 方法用于从数据库中获取所有数据。fetchAll() 方法接受一个参数作为获取模式。

$users = QB::select()
        ->from('users')
        ->fetchAll();

foreach ($users as $user) {
    $user->name; // John Doe
}

当您想获取所有行数据时,可以使用 fetchAll


statement() 方法用于获取 PDOStatement 对象。

$stmt = QB::select()
        ->from('users')
        ->statement();

while ($user = $stmt->fetch()) {
    echo $user->name; // John Doe
}

当您想使用 PDOStatement 方法时,可以使用 statement


原始

raw() 方法用于返回原始查询字符串。raw() 方法接受一个参数,指示您是否希望查询作为一个字符串或一个包含占位符参数的 stdClass 对象。

$query = QB::select()
        ->from('users')
        ->where('id', 1)
        ->raw();
SELECT * FROM users WHERE id = 1

辅助函数

原始

raw() 方法用于将原始字符串添加到查询中。raw() 方法接受一个参数。

$users = QB::select()
        ->from('users')
        ->where('id', QB::raw('COUNT(id)'))
SELECT * FROM users WHERE id = COUNT(id)

参数

param() 方法用于将值作为占位符添加到查询中。param() 方法接受两个参数。第一个是必需的,作为值;第二个是可选的,作为占位符的名称。

$users = QB::select()
        ->from('users')
        ->leftJoin('skills' 's')->on('s.user_id', 'u.id')->and('s.name', QB::param('php', 'skill'))
        ->where('id', 1);
SELECT * FROM users LEFT JOIN skills s ON s.user_id = u.id AND s.name = :skill WHERE id = 1

对于 where() 子句,您不需要使用 param() 方法。where() 自动将值添加为占位符。


现在

now() 方法用于将当前日期和时间添加到查询中。

$users = QB::select()
        ->from('users')
        ->where('created_at', QB::now());
SELECT * FROM users WHERE created_at = NOW()

从简单到复杂的示例

$users = QB::select()
        ->from('users')
        ->where('id', 1)
        ->and('status', 1)
        ->and(
            QB::where('skill', 'php')->or('skill', 'javascript')
        )
        ->groupBy('skill')
        ->having('COUNT(id)', '>', 10)
SELECT *
FROM users
WHERE
    id = 1 AND
    status = 1 AND
    (skill = 'php' OR skill = 'javascript')
GROUP BY skill
HAVING COUNT(id) > 10

$users = QB::select()
        ->from('users')
        ->where('id', 1)
        ->and('status', 1)
        ->and(
            QB::where('skill', 'php')->or('skill', 'javascript')
        )
        ->groupBy('skill')
        ->orderBy('name ASC', 'join_date DESC')
        ->having('COUNT(id)', '>', 10)
        ->limit(10)
        ->offset(100);
SELECT *
FROM users
WHERE
    id = 1 AND
    status = 1 AND
    (skill = 'php' OR skill = 'javascript')
GROUP BY skill
HAVING COUNT(id) > 10
ORDER BY name ASC, join_date DESC
LIMIT 10, 100

$users = QB::select(
        'u.id, u.name, u.email, s.name as skill',
        QB::if('u.status = 1', 'active', 'inactive')->as('status'),
        QB::select('COUNT(id)')->from('skills')->where('user_id', QB::raw('u.id'))->as('skill_count')
    )
    ->from('users')->as('u')
    ->leftJoin('posts', 'p')->on('p.user_id', 'u.id')
    ->leftJoin('comments')->as('c')->on('c.post_id', 'p.id')
    ->where('u.status', 1)
    ->and(
        QB::where('u.skill', 'php')->or('u.skill', 'javascript')
    )
    ->and('u.join_date', QB::greaterThan('2019-01-01'))
    ->and('u.role',
        QB::if(
            QB::where('u.role', QB::in('admin', 'super_admin')),
            'admin',
            'user'
        )
    )
    ->groupBy('u.skill')
    ->having('COUNT(p.id)', '>', 10)
    ->orderBy('u.name ASC', 'u.join_date DESC')
    ->limit(10)
    ->having('COUNT(c.id)', '<', 100)
    ->offset(100);
SELECT
    u.id, u.name, u.email, s.name as skill,
    IF(u.status = 1, 'active', 'inactive') as status,
    (SELECT COUNT(id) FROM skills WHERE user_id = u.id) as skill_count
FROM users u
LEFT JOIN posts p ON p.user_id = u.id
LEFT JOIN comments c ON c.post_id = p.id
WHERE
    u.status = 1 AND
    (u.skill = 'php' OR u.skill = 'javascript') AND
    u.join_date > '2019-01-01' AND
    u.role = IF(u.role IN ('admin', 'super_admin'), 'admin', 'user')
GROUP BY u.skill
HAVING COUNT(p.id) > 10 AND COUNT(c.id) < 100
ORDER BY u.name ASC, u.join_date DESC
LIMIT 10, 100

插入

QB::insert() 方法用于创建 INSERT 查询。insert() 方法接受一个参数作为表名。

QB::insert('users')->values([
    'name' => 'John Doe'
]);
INSERT INTO users (name) VALUES ('John Doe')

您还可以使用 insertInto(),它是 insert() 方法的别名。

您可以使用 Model 类代替表名。


columns() 方法用于向 INSERT 查询中添加 COLUMNScolumns() 方法是可选的,接受以下参数

  • 作为原始 SQL 的字符串。
  • 作为列名的数组。

如果您传递给 columns() 一个字符串,则 values() 方法也必须是字符串。

如果您传递给 values() 方法一个数组,则不需要使用 columns() 方法。

QB::insert('users')->columns('name')->values('John Doe');
INSERT INTO users (name) VALUES ('John Doe')

values() 方法用于向 INSERT 查询中添加 VALUESvalues() 方法接受以下参数

  • 作为原始 SQL 的字符串。
  • 作为列名和值的数组。

当您将数组传递给 values() 方法时,数组的键是列名,值是列的值。

QB::insert('users')->values([
    'name' => 'John Doe'
]);
INSERT INTO users (name) VALUES ('John Doe')

数组的值将自动作为占位符。


要执行查询,您可以使用 run()execute() 方法。

QB::insert('users')->values([
    'name' => 'John Doe'
])->run();

更新

QB::update() 方法用于创建 UPDATE 查询。update() 方法接受两个参数作为表名和表的别名。

您也可以使用 as() 方法设置表的别名。

QB::update('users')->set([
    'name' => 'John Doe'
])->where('id', 1);
UPDATE users SET name = 'John Doe' WHERE id = 1

您可以使用 Model 类代替表名。


设置

set() 方法用于向 UPDATE 查询中添加 SETset() 方法接受以下参数

  • 作为原始 SQL 的字符串。
  • 作为列名和值的数组。

当您将数组传递给 set() 方法时,数组的键是列名,值是列的值。

QB::update('users')->set([
    'name' => 'John Doe'
])->where('id', 1);
UPDATE users SET name = 'John Doe' WHERE id = 1

数组的值将自动作为占位符。


要使用 where() 方法与 update() 方法一起,请参阅Where 部分。

注意:不能在没有使用 where() 方法的情况下使用 update() 方法。


要执行查询,您可以使用 run()execute() 方法。

QB::update('users')->set([
    'name' => 'John Doe'
])->where('id', 1)->run();
UPDATE users SET name = 'John Doe' WHERE id = 1

删除

QB::delete() 方法用于创建一个 DELETE 查询。该方法接受两个参数,分别是表名和表的别名。

您也可以使用 as() 方法设置表的别名。

QB::delete('users')->where('id', 1);
DELETE FROM users WHERE id = 1

您还可以使用 deleteFrom()。它是 delete() 方法的别名。

您可以使用 Model 类代替表名。


要使用 where() 方法与 delete() 方法结合,请参阅 Where 部分。

注意:您不能在不使用 where() 方法的情况下使用 delete() 方法。


要执行查询,您可以使用 run()execute() 方法。

QB::delete('users')->where('id', 1)->run();
DELETE FROM users WHERE id = 1

您可以通过在 SELECTINSERTUPDATEDELETE 查询的查询末尾调用 raw() 方法来获取 SQL 查询字符串。


许可证

本项目是开源软件,根据 MIT 许可证授权 - 详细信息请参阅 LICENSE 文件。