gowork / dqo
数据库查询对象
0.4.1
2023-02-15 11:26 UTC
Requires
- php: >=8.1
- doctrine/dbal: ^3.3
- gowork/safe: ^0.2
- gowork/values: ^0.6
- nikic/php-parser: ^4.10
- open-serializer/type: ^0.1
- phpdocumentor/reflection-docblock: ^5.2
- symfony/config: ^6.0
- symfony/console: ^6.0
- symfony/dependency-injection: ^6.0
- symfony/http-kernel: ^6.0
- symfony/process: ^6.0
Requires (Dev)
- phpstan/phpstan: ^1.7
- phpstan/phpstan-strict-rules: ^1.4
- phpunit/phpunit: ^9.5
- dev-master
- 0.4.1
- 0.4.0
- 0.3.3
- 0.3.2
- 0.3.1
- 0.3.0
- 0.2.1
- 0.1.0
- dev-fix-deprecated-null-param
- dev-dependabot/composer/phpunit/phpunit-tw-9.5or-tw-10.0
- dev-feature/dbal3v2
- dev-fix/fetch-col-null
- dev-fix/fetch-column
- dev-feature/php-8.1
- dev-feature/query-gen2
- dev-bronek89-patch-2
- dev-fix/remove-version
- dev-feature/update-values
- dev-feature/phpstan1
- dev-feature/switch-to-dbal3
- dev-feature/remove-better-reflection
- dev-bronek89-patch-4
- dev-feature/dbal-3
- dev-bronek89-patch-3
- dev-bronek89-patch-1
- dev-feature/symfony4
- dev-feature/run-tests
- dev-feature/dev-bundle
- dev-feature/fixers
- dev-feature/query-gen
- dev-add-license-1
- dev-feature/nikic-generate
This package is auto-updated.
Last update: 2024-09-15 10:50:52 UTC
README
简介
DQO 提供了 SQL 数据库表、行和选择查询的对象表示。
特性
- 每个数据库表都可以描述为
Table
类 - 在编写查询时启用 IDE 中的列名自动完成
- 提供常量作为表列枚举
- 从 SELECT 查询返回的每一行都可以描述为
Row
类 - 可以为相应的
Row
类添加特定的反序列化配方 - 可以使用 Symfony 控制台命令生成
Table
和Row
类的代码 - 提供不可变的
DatabaseSelectBuilder
用于构建 SELECT 查询
DQO 基于 Doctrine DBAL,并使用 Doctrine 类型进行数据反序列化,以及 Doctrine\DBAL\Connection
进行查询执行。
Table
定义
表示特定数据库表的类。它包含表列的枚举常量,并简化了字段别名。可以创建多个实例,使用不同的别名。
final class UserTable extends GW\DQO\Table { public const ID = 'id'; public const EMAIL = 'email'; public const NAME = 'name'; public function id(): string { return $this->fieldPath(self::ID); } public function email(): string { return $this->fieldPath(self::EMAIL); } public function name(): string { return $this->fieldPath(self::NAME); } public function createRow(array $raw): UserRow { return new UserRow($raw, $this); } } $userTable = new UserTable('user_alias'); $userTable->table(); // "user" $userTable->alias(); // "user_alias" $userTable->id(); // "user_alias.id" $userTable->selectField(UserTable::ID); // "user_alias.id as user_alias_id"
TableRow
定义
可以创建的类,用于统一从相应表提取和反序列化数据。
final class UserRow extends ClientRow { public function id(): UserId { return $this->getThroughType('UserId', UserTable::ID); } public function name(): string { return $this->getString(UserTable::NAME); } public function email(): Email { return Email::fromString($this->getString(UserTable::EMAIL)); } public function optionalSecondEmail(): ?Email { return $this->getThrough([Email::class, 'fromString'], UserTable::OPTIONAL_SECOND_EMAIL); } public function about(): ?string { return $this->getNullableString(UserTable::NAME); } } $userTable = new UserTable(); $userRow = new UserRow($rowFromQuery, $userTable);
使用 DatabaseSelectBuilder
构建 SELECT 查询
DatabaseSelectBuilder
简化了使用 Table
对象构建 SELECT 语句。
/** @var Doctrine\DBAL\Connection $connection */ $builder = new GW\DQO\DatabaseSelectBuilder($connection); $meTable = new UserTable('me'); $friendTable = new UserTable('friend'); $builder ->from($meTable) ->join($friendTable, "{$friendTable->id()} = {$meTable->friendId()}") ->where("{$meTable->username()} = :me", ['me' => 'John Doe']) ->select($friend->name()) ->offsetLimit(0, 10);
SELECT 列别名
默认情况下,TableRow
预期 SELECT 部分中使用的表列具有以下别名:table_alias.column_name as table_alias_column_name
。
有 2 种方法来创建这样的别名
- 使用
Table
方法创建列别名$table = new UserTable(); $builder = $builder->select(...$table->select(UserTable::ID, UserTable::email)); // or $builder = $builder->select($table->selectField(UserTable::ID), $table->selectField(UserTable::email)); // or $builder = $builder->select(...$table->selectAll());
- 当
select()
在table()
或join()
之后时,简单地使用$table->column()
$table = new UserTable(); // first add $table to builder so it can recognize `user.id`, `user.email` and create valid aliases... $builder = $builder->from($table); // ...then simply select $builder = $builder->select($table->id(), $table->email());
查询参数
查询参数可以直接在 where/having
方法中指定,也可以稍后提供。
$builder = $builder->from($user) ->where("{$user->name()} = :name", ['name' => 'John Doe']) ->having('orders > :limit', ['limit' => 10]); // or $builder = $builder->from($user) ->where("{$user->name()} = :name") ->withParameter('name', 'John Doe'); // or $builder = $builder->from($user) ->where("{$user->name()} = :name") ->withParameters(['name' => 'John Doe']);
可以指定 where()
参数的查询参数类型。
$yesterday = new DateTime('yesterday'); $builder = $builder ->from($user) ->where("{$user->registered()} > :yesterday", ['yesterday' => $yesterday], ['yesterday' => 'datetime']);
您还可以定义参数类到正确 Doctrine 类型的映射。
$start = new DateTimeImmutable('first day of last month 00:00'); $end = new DateTimeImmutable('last day of last month 23:59'); $builder = $builder ->withTypes([DateTimeImmutable::class => 'datetime_immutable']) ->from($user) ->where("{$user->registered()} BETWEEN :start AND :end", ['start' => $start, 'end' => $end]);
获取结果
/** @var array<string, mixed>|null $result one result row or null when there are no rows */ $result = $builder->fetch(); /** @var mixed|null $result one column from first result or null when no results */ $result = $builder->fetchColumn(); /** @var array<int, array<string, mixed>> $result fetch all result rows */ $result = $builder->fetchAll(); /** * @var ArrayValue<array<string, mixed>> $result * @see https://github.com/gowork/values */ $result = $builder->wrapAll(); /** @var int $result */ @result = $builder->count();
安装
composer require gowork/dqo
设置
Symfony
将 DatabaseAccessGeneratorBundle 添加到您的应用程序的内核(仅适用于 dev
环境)
<?php public function registerBundles(): array { $bundles = [ // ... ]; if ($this->getEnvironment() === 'dev') { // ... $bundles[] = new GW\DQO\Symfony\DatabaseAccessGeneratorBundle(); } ... }
生成表类
dqo:generate-tables src/Database App/Database table_1 table_2
表查询模式
所有查询都应扩展 GW\DQO\Query\AbstractDatabaseQuery
待办事项
- 为表生成查询
- 添加命令以更新表/行的新字段
关于
使用于