wonfu / cakedatabase

基于 cakephp 数据库的数据库抽象库

4.4.0-RC1 2022-03-13 15:36 UTC

This package is not auto-updated.

Last update: 2024-09-12 17:12:21 UTC


README

Total Downloads License

PHP的灵活轻量级数据库库

这个库抽象并提供了处理关系数据库的大部分方面的帮助,如保持与服务器的连接、构建查询、防止 SQL 注入、检查和修改模式,以及调试和记录发送到数据库的查询。

它采用了 PHP 的原生 PDO 扩展的 API,以提高熟悉度,但解决了 PDO 中的许多不一致性,同时还提供了几个扩展 PDO 功能的特性。

与类似的数据库连接包相比,这个库的一个显著特点是它将“数据类型”的概念作为核心。它允许您使用可以传递为查询条件或插入到数据库中的复杂 PHP 对象或结构。

类型系统将在将它们传递到数据库时智能地将 PHP 结构进行转换,并在检索时将其转换回。

连接到数据库

这个库能够与以下数据库一起工作

  • MySQL
  • Postgres
  • SQLite
  • Microsoft SQL Server (2008 及以上)

使用此库时,您需要做的第一件事是创建一个连接对象。在执行任何与连接相关的操作之前,您需要指定一个要使用的驱动程序

use Cake\Database\Connection;
use Cake\Database\Driver\Mysql;

$driver = new Mysql([
	'database' => 'test',
	'username' => 'root',
	'password' => 'secret'
]);
$connection = new Connection([
	'driver' => $driver
]);

驱动程序是负责向数据库执行命令并正确构建 SQL 的特定于数据库方言的类的集合。也可以通过传递一个类名来指定驱动程序。在这种情况下,将所有连接详情直接包含在选项数组中

use Cake\Database\Connection;

$connection = new Connection([
	'driver' => Cake\Database\Driver\Sqlite::class,
	'database' => '/path/to/file.db'
]);

连接选项

这是创建连接时可以传递的可能选项的列表

  • persistent:创建一个持久连接
  • host:服务器主机
  • database:数据库名称
  • username:登录凭证
  • password:连接密钥
  • encoding:连接编码(或字符集)
  • timezone:连接时区或时间偏移量

使用连接

创建连接后,您可以立即与数据库交互。您可以选择使用简写方法 execute()insert()update()delete() 或使用 newQuery() 来使用查询构建器。

执行查询的最简单方法是使用 execute() 方法,它将返回一个 Cake\Database\StatementInterface,您可以使用它来获取数据

$statement = $connection->execute('SELECT * FROM articles');

while($row = $statement->fetch('assoc')) {
	echo $row['title'] . PHP_EOL;
}

使用执行函数也可以将值绑定到参数化参数

$statement = $connection->execute('SELECT * FROM articles WHERE id = :id', ['id' => 1], ['id' => 'integer']);
$results = $statement->fetch('assoc');

第三个参数是在传递给数据库时传递的值应转换到的类型。如果没有传递类型,则所有参数都将解释为字符串。

或者,您可以手动构建一个语句,然后从中检索行

$statement = $connection->prepare('SELECT * from articles WHERE id != :id');
$statement->bind(['id' => 1], ['id' => 'integer']);
$results = $statement->fetchAll('assoc');

此库默认理解并可传递给 bind() 函数或 execute() 的类型是

  • biginteger
  • binary
  • date
  • float
  • decimal
  • integer
  • time
  • datetime
  • timestamp
  • uuid

可以在稍后动态添加更多类型。

可以通过将新值绑定到查询中的参数来重用语句

$statement = $connection->prepare('SELECT * from articles WHERE id = :id');
$statement->bind(['id' => 1], ['id' => 'integer']);
$results = $statement->fetchAll('assoc');

$statement->bind(['id' => 1], ['id' => 'integer']);
$results = $statement->fetchAll('assoc');

更新行

可以使用连接对象中的 update() 函数来执行更新。以下示例将更新 id = 1 的文章标题

$connection->update('articles', ['title' => 'New title'], ['id' => 1]);

数据类型的概念是这个库的核心,因此您可以使用函数的最后一个参数来指定应使用哪些类型

$connection->update(
	'articles',
	['title' => 'New title'],
	['created >=' => new DateTime('-3 day'), 'created <' => new DateTime('now')],
	['created' => 'datetime']
);

上面的示例将执行以下 SQL

UPDATE articles SET title = 'New Title' WHERE created >= '2014-10-10 00:00:00' AND created < '2014-10-13 00:00:00';

稍后将在创建复杂的WHERE条件或更复杂的更新查询时详细介绍。

删除行

同样,使用delete()方法从数据库中删除行

$connection->delete('articles', ['created <' => DateTime('now')], ['created' => 'date']);

将生成以下SQL

DELETE FROM articles where created < '2014-10-10'

插入行

可以使用insert()方法插入行

$connection->insert(
	'articles',
	['title' => 'My Title', 'body' => 'Some paragraph', 'created' => new DateTime()],
	['created' => 'datetime']
);

可以使用Query类生成更复杂的更新、删除和插入查询。

查询构建器

该库的一个目标是通过获取查询的新实例来轻松生成简单和复杂的查询。可以通过获取查询的新实例来访问查询构建器

$query = $connection->newQuery();

选择字段

SELECT子句添加字段

$query->select(['id', 'title', 'body']);

// Results in SELECT id AS pk, title AS aliased_title, body ...
$query->select(['pk' => 'id', 'aliased_title' => 'title', 'body']);

// Use a closure
$query->select(function ($query) {
	return ['id', 'title', 'body'];
});

WHERE条件

生成条件

// WHERE id = 1
$query->where(['id' => 1]);

// WHERE id > 2
$query->where(['id >' => 1]);

如你所见,你可以在字段名后放置一个空格来使用任何运算符。添加多个条件也很简单

$query->where(['id >' => 1])->andWhere(['title' => 'My Title']);

// Equivalent to
$query->where(['id >' => 1, 'title' => 'My title']);

还可以生成OR条件

$query->where(['OR' => ['id >' => 1, 'title' => 'My title']]);

对于更复杂的条件,可以使用闭包和表达式对象

$query->where(function ($exp) {
        return $exp
            ->eq('author_id', 2)
            ->eq('published', true)
            ->notEq('spam', true)
            ->gt('view_count', 10);
    });

这将导致

SELECT * FROM articles
WHERE
	author_id = 2
	AND published = 1
	AND spam != 1
	AND view_count > 10

也可以组合表达式

$query->where(function ($exp) {
        $orConditions = $exp->or(['author_id' => 2])
            ->eq('author_id', 5);
        return $exp
            ->not($orConditions)
            ->lte('view_count', 10);
    });

这将生成

SELECT *
FROM articles
WHERE
	NOT (author_id = 2 OR author_id = 5)
	AND view_count <= 10

当使用表达式对象时,可以使用以下方法创建条件

  • eq() 创建一个等价条件。
  • notEq() 创建一个不等价条件
  • like() 使用LIKE运算符创建一个条件。
  • notLike() 创建一个否定LIKE条件。
  • in() 使用IN创建一个条件。
  • notIn() 使用IN创建一个否定条件。
  • gt() 创建一个>条件。
  • gte() 创建一个>=条件。
  • lt() 创建一个<条件。
  • lte() 创建一个<=条件。
  • isNull() 创建一个IS NULL条件。
  • isNotNull() 创建一个否定IS NULL条件。

聚合和SQL函数

// Results in SELECT COUNT(*) count FROM ...
$query->select(['count' => $query->func()->count('*')]);

可以使用func()方法创建许多常用函数

  • sum() 计算总和。参数将被视为文字值。
  • avg() 计算平均值。参数将被视为文字值。
  • min() 计算列的最小值。参数将被视为文字值。
  • max() 计算列的最大值。参数将被视为文字值。
  • count() 计算计数。参数将被视为文字值。
  • concat() 将两个值连接在一起。除非标记为文字,否则参数被视为绑定参数。
  • coalesce() 合并值。除非标记为文字,否则参数被视为绑定参数。
  • dateDiff() 获取两个日期/时间之间的差异。除非标记为文字,否则参数被视为绑定参数。
  • now() 将'time'或'date'作为参数,允许你获取当前时间或当前日期。

当为SQL函数提供参数时,你可以使用两种类型的参数:文字参数和绑定参数。文字参数允许你引用列或其他SQL文字。绑定参数可以用于将用户数据安全地添加到SQL函数中。例如

$concat = $query->func()->concat([
    'title' => 'literal',
    ' NEW'
]);
$query->select(['title' => $concat]);

上述代码生成

SELECT CONCAT(title, :c0) ...;

其他SQL子句

官方API文档中阅读构建器能够生成所有其他SQL子句

从查询中获取结果

一旦你创建了查询,你将想要从其中检索行。有几种方法可以实现这一点

// Iterate the query
foreach ($query as $row) {
    // Do stuff.
}

// Get the statement and fetch all results
$results = $query->execute()->fetchAll('assoc');

官方API

你可以阅读官方的官方API文档以了解更多关于此库的功能。