clancats/hydrahon

快速且独立的 PHP MySQL 查询构建器库。

v1.1.14 2020-09-30 14:43 UTC

README

Hydrahon

Hydrahon 是一个用 PHP 编写的 独立的 数据库 / SQL 查询构建器。它被构建来增强现有的框架、库和应用程序,它们自行处理数据库连接。它 包含 PDOmysqli 包装器。命名灵感主要来自 Eloquent 和 Kohana 框架的数据库组件。

“独立查询构建器”是什么意思?

Hydrahon 只生成一个查询 字符串 和一个参数数组。它本身无法执行查询。

Build Status Packagist Packagist GitHub release

状态

  • Hydrahon 的 MySQL 查询构建器是稳定的,已在生产中使用。
  • Hydrahon 的 AQL(Arango 查询语言)查询构建器目前正在开发中。
  • 正在考虑为 Elasticsearch 开发构建器,但尚未开始。

安装

Hydrahon 遵循 PSR-4 自动加载,可以使用 composer 安装。

$ composer require clancats/hydrahon

文档 💡

完整文档可以在 clancats.io 上找到。

快速入门(MySQL)⚡️

Hydrahon 被设计为一个相当通用的查询构建器。所以在这个快速入门中,我们坚持使用 SQL。

创建构建器

再次,这个库不是作为一个完整的数据库抽象或 ORM 构建的,它只是一个查询构建器。这意味着我们需要自己实现数据库连接和检索。因此,Hydrahon 构造函数要求你提供一个回调函数来完成这个任务,并返回结果。

在这个例子中,我们将使用 PDO

$connection = new PDO('mysql:host=localhost;dbname=my_database;charset=utf8', 'username', 'password');

// create a new mysql query builder
$h = new \ClanCats\Hydrahon\Builder('mysql', function($query, $queryString, $queryParameters) use($connection)
{
    $statement = $connection->prepare($queryString);
    $statement->execute($queryParameters);

    // when the query is fetchable return all results and let hydrahon do the rest
    // (there's no results to be fetched for an update-query for example)
    if ($query instanceof \ClanCats\Hydrahon\Query\Sql\FetchableInterface)
    {
        return $statement->fetchAll(\PDO::FETCH_ASSOC);
    }
    // when the query is a instance of a insert return the last inserted id  
    elseif($query instanceof \ClanCats\Hydrahon\Query\Sql\Insert)
    {
        return $connection->lastInsertId();
    }
    // when the query is not a instance of insert or fetchable then
    // return the number os rows affected
    else 
    {
        return $statement->rowCount();
    }	
});

我们准备好了。变量 $h 现在包含了一个 MySQL 查询构建器。

设置一个简单的表

为了继续我们的示例,我们需要创建一个简单的 MySQL 表。

CREATE TABLE `people` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT '',
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入

目前我们没有数据,为了解决这个问题,让我们插入一些数据。

// In our example we are going to execute multiple operations on the same table, 
// so instead of loading the table over and over again, we store it in a variable.
$people = $h->table('people');

$people->insert(
[
    ['name' => 'Ray', 'age' => 25],
    ['name' => 'John',  'age' => 30],
    ['name' => 'Ali', 'age' => 22],
])->execute();

将执行以下查询

insert into `people` (`age`, `name`) values (?, ?), (?, ?), (?, ?)

正如你所见,Hydrahon 自动转义了参数。

然而,因为我们都是人,当有数十万个问号时,我们可能会感到困惑,所以我将继续始终显示可运行的查询

insert into `people` (`age`, `name`) values (25, Ray), (30, John), (22, Ali)

更新

哎呀,时间过得真快,“Ray”实际上已经 26 岁了。

$people->update()
    ->set('age', 26)
    ->where('name', 'Ray')
->execute();

生成

update `people` set `age` = 26 where `name` = 'Ray'

目前,你可能认为:“好吧,直接写 SQL 查询不是更简单吗?毕竟,PHP 代码甚至更长...”。

你必须理解,这些是一些非常非常基础的例子,当事情变得更加复杂时,Hydrahon 查询构建器开始闪耀。然而,“快速入门”并不是复杂事物的合适地方,所以请查看 完整文档

删除

该死,约翰,我恨你...

$people->delete()
    ->where('name', 'John')
->execute();

生成

delete from `people` where `name` = 'John'

选择

最后,获取数据。

$people->select()->get();

生成

select * from `people`

结果

[
  {
    "id": "1",
    "name": "Ray",
    "age": "26"
  },
  {
    "id": "3",
    "name": "Ali",
    "age": "22"
  }
]

请注意,我们使用 ->get() 实际上获取数据,而我们之前使用的 ->execute() 是用于我们的其他查询(更新、插入和删除)。有关 Hydrahon 的更多详细信息,请参阅完整文档。

条件位置

在接下来的几个示例中,我们假设有一个更大的数据集,以便查询更有意义。

链式条件

// select * from `people` where `age` = 21 and `name` like 'J%'
$people->select()
    ->where('age', 21)
    ->where('name', 'like', 'J%')
    ->get();

注意,在第一个条件中省略操作符->where('age', 21),Hydrahon默认使用=

默认情况下,所有where条件都使用and操作符定义。

不同的where操作符

// select * from `people` where `name` like 'J%' or `name` like 'I%'
$people->select()
    ->where('name', 'like', 'J%')
    ->orWhere('name', 'like', 'I%')
    ->get();

请查看完整文档中的相关部分以获取更多where函数,例如

  • whereIn()
  • whereNotIn()
  • whereNull()
  • whereNotNull()

Where作用域

允许您分组条件

// select * from `people` where ( `age` > 21 and `age` < 99 ) or `group` = admin
$people->select()
    ->where(function($q) 
    {
        $q->where('age', '>', 21);
        $q->where('age', '<', 99);
    })
    ->orWhere('group', 'admin')
    ->get();

连接

连接表

// select 
//     `people`.`name`, `groups`.`name` as `group_name` 
// from `people` 
// left join `groups` on `groups`.`id` = `people`.`group_id`
$people->select('people.name, groups.name as group_name')
    ->join('groups', 'groups.id', '=', 'people.group_id')
    ->get();

分组

分组数据

// select * from `people` group by `age`
$people->select()->groupBy('age')->get();

排序

排序数据

// select * from `people` order by `age` desc
$people->select()->orderBy('age', 'desc')->get();

// select * from `people` order by `age` desc, `name` asc
$people->select()->orderBy(['age' => 'desc', 'name' => 'asc'])->get();

限制数据

限制和偏移

// select * from `people` limit 0, 10
$people->select()->limit(10)->get();

// select * from `people` limit 100, 10
$people->select()->limit(100, 10)->get();

// select * from `people` limit 100, 10
$people->select()->limit(10)->offset(100)->get();

// select * from `people` limit 150, 30
$people->select()->page(5, 30)->get();

小提醒:这是快速入门,请查看完整文档。

鸣谢

许可证

MIT许可证(MIT)。请参阅许可证文件获取更多信息。