foleon / api-tools-doctrine-querybuilder
Laminas API Tools Doctrine QueryBuilder模块
Requires
- php: ^7.3 || ~8.0.0 || ~8.1.0 || ~8.2.0
- doctrine/doctrine-module: ^2.1.8 || ^3.0.1 || ^4.1.0 || ^5.1
- foleon/api-tools-doctrine: 1.0
- laminas-api-tools/api-tools-api-problem: ^1.2.2
- laminas-api-tools/api-tools-hal: ^1.4.2
- laminas/laminas-hydrator: ^2.2.1 || ^3.0 || ^4.0
- laminas/laminas-modulemanager: ^2.7.2
- laminas/laminas-mvc: ^2.7.13 || ^3.0.2
- laminas/laminas-servicemanager: ^2.7.6 || ^3.1.1
- laminas/laminas-zendframework-bridge: ^1.0
Requires (Dev)
- doctrine/dbal: ^2.12.1 || ^3.0.0
- doctrine/doctrine-mongo-odm-module: ^1.0 || ^2.0.2 || ^3.0.2 || ^4.0
- doctrine/doctrine-orm-module: ^2.1.3 || ^4.0 || ^5.1
- doctrine/orm: ^2.7.5
- laminas-api-tools/api-tools-provider: ^1.2
- laminas/laminas-i18n: ^2.7.3
- laminas/laminas-log: ^2.9.1
- laminas/laminas-serializer: ^2.8
- laminas/laminas-test: ^2.6.1 || ^3.0.1 || ^4.0
- phpspec/prophecy-phpunit: ^2.0
- phpunit/phpunit: ^9.5.0
- psalm/plugin-phpunit: ^0.15
- symfony/yaml: ^2.3 || ^3.0 || ^4.0
- vimeo/psalm: ^4.7
Suggests
- doctrine/doctrine-mongo-odm-module: ^1.0 || ^2.0.2 || ^3.0.2, if you wish to use the Doctrine ODM
- doctrine/doctrine-orm-module: ^2.1.3 || ^3.1.1, if you wish to use the Doctrine ORM
- ext/mongo: Mongo extension, if using ODM
Replaces
This package is not auto-updated.
Last update: 2024-09-17 22:47:04 UTC
README
🇷🇺 俄罗斯公民
我们,Laminas的参与者,来自不同的国家。我们中许多人有在俄罗斯和乌克兰的朋友、亲戚和同事。我们中的一些人出生在俄罗斯。我们中的一些人现在住在俄罗斯。我们中的一些人的祖父母在二战中与法西斯作战。在这里,没有人支持法西斯主义。
我们中的一员有一个乌克兰亲戚,她带着儿子逃离了家园。火车因前方道路上的轰炸而延误。我们有朋友躲在防空洞里。我们在空袭后焦急地等待他们的消息,空袭无差别地袭击医院、学校、幼儿园和住宅。我们不是从任何媒体上得知这些。这是我们亲眼目睹的。
您信任我们足够使用我们的程序,我们请求您再次信任我们。我们需要您的帮助。走出家门,抗议这场无意义的战争。停止杀戮。说“停止战争!”
🇺🇸 致俄罗斯公民
我们Laminas的成员来自世界各地。我们中许多人有在俄罗斯和乌克兰的朋友、家人和同事。我们中的一些人出生在俄罗斯。我们中的一些人现在住在俄罗斯。我们中的一些人的祖父母在二战中与纳粹作战。在这里,没有人支持法西斯主义。
我们中的一员有一个乌克兰亲戚,她和儿子一起逃离了家园。火车因前方道路上的轰炸而延误。我们有朋友躲在防空洞里。我们在空袭后焦急地等待他们的消息,空袭无差别地袭击医院、学校、幼儿园和住宅。我们不是从任何媒体上得知这些。这是我们亲眼目睹的。
您信任我们足够使用我们的软件。我们要求您信任我们说出真相。我们需要您的帮助。走出家门,抗议这场无意义的战争。停止杀戮。说“停止战争!”
这个库提供了从数组参数中的查询构建器指令。这个库被设计用来将HTTP请求中的过滤器应用于API,以提供流畅的过滤和排序方言。
哲学
给定开发者识别A和B:A == B关于过滤和排序实体数据的能力和意愿。
要共享的Doctrine实体包含
id integer,
name string,
startAt datetime,
endAt datetime,
开发者A或B编写API。资源是一个单一的Doctrine实体,数据使用Doctrine QueryBuilder $objectManager->createQueryBuilder()
进行查询。此模块给其他开发者提供与Doctrine查询构建器相同的过滤和排序能力,但通过请求参数访问,如同API作者。例如,startAt between('2015-01-09', '2015-01-11');
和name like ('%arlie')
不是手工制作的API的常见过滤器,也许如果没有这个模块,API作者可能不会出于某种原因选择实现它。借助此模块,API开发者可以轻松实现资源的复杂查询性,从而保持A == B。
安装
此模块的安装使用composer。有关composer文档,请参阅getcomposer.org。
$ composer require laminas-api-tools/api-tools-doctrine-querybuilder
安装完成后,将 Laminas\ApiTools\Doctrine\QueryBuilder
添加到 config/application.config.php
文件中的模块列表中。
laminas-component-installer
如果您使用 laminas-component-installer,该插件会为您将 api-tools-doctrine-querybuilder 作为模块安装。
配置模块
将 config/api-tools-doctrine-querybuilder.global.php.dist
复制到 config/autoload/api-tools-doctrine-querybuilder.global.php
,并编辑.orm 和.odm 的别名列表,以启用默认的别名。
与 Laminas API Tools Doctrine 一起使用
要启用所有过滤器,您可以覆盖 api-tools-doctrine
中的默认查询提供者。将以下内容添加到您的 api-tools-doctrine-querybuilder.global.php
配置文件中,如果请求中存在 $_GET['filter']
或 $_GET['order-by']
,则将应用过滤器和排序。这些 $_GET
键可以通过 api-tools-doctrine-querybuilder-options
进行自定义。
'api-tools-doctrine-query-provider' => [ 'aliases' => [ 'default_orm' => \Laminas\ApiTools\Doctrine\QueryBuilder\Query\Provider\DefaultOrm::class, 'default_odm' => \Laminas\ApiTools\Doctrine\QueryBuilder\Query\Provider\DefaultOdm::class, ], 'factories' => [ \Laminas\ApiTools\Doctrine\QueryBuilder\Query\Provider\DefaultOrm::class => \Laminas\ApiTools\Doctrine\QueryBuilder\Query\Provider\DefaultOrmFactory::class, \Laminas\ApiTools\Doctrine\QueryBuilder\Query\Provider\DefaultOdm::class => \Laminas\ApiTools\Doctrine\QueryBuilder\Query\Provider\DefaultOdmFactory::class, ], ],
使用
配置示例
'api-tools-doctrine-querybuilder-orderby-orm' => [ 'aliases' => [ 'field' => \Laminas\ApiTools\Doctrine\QueryBuilder\OrderBy\ORM\Field::class, ], 'factories' => [ \Laminas\ApiTools\Doctrine\QueryBuilder\OrderBy\ORM\Field::class => \Laminas\ServiceManager\Factory\InvokableFactory::class, ], ], 'api-tools-doctrine-querybuilder-filter-orm' => [ 'aliases' => [ 'eq' => \Laminas\ApiTools\Doctrine\QueryBuilder\Filter\ORM\Equals::class, ], 'factories' => [ \Laminas\ApiTools\Doctrine\QueryBuilder\Filter\ORM\Equals::class => \Laminas\ServiceManager\Factory\InvokableFactory::class, ], ],
请求示例
$_GET = [ 'filter' => [ [ 'type' => 'eq', 'field' => 'name', 'value' => 'Tom', ], ], 'order-by' => [ [ 'type' => 'field', 'field' => 'startAt', 'direction' => 'desc', ], ], ];
资源示例
$serviceLocator = $this->getApplication()->getServiceLocator(); $objectManager = $serviceLocator->get('doctrine.entitymanager.orm_default'); $filterManager = $serviceLocator->get('LaminasDoctrineQueryBuilderFilterManagerOrm'); $orderByManager = $serviceLocator->get('LaminasDoctrineQueryBuilderOrderByManagerOrm'); $queryBuilder = $objectManager->createQueryBuilder(); $queryBuilder->select('row') ->from($entity, 'row') ; $metadata = $objectManager->getMetadataFactory()->getMetadataFor(ENTITY_NAME); // $e->getEntity() using doctrine resource event $filterManager->filter($queryBuilder, $metadata, $_GET['filter']); $orderByManager->orderBy($queryBuilder, $metadata, $_GET['order-by']); $result = $queryBuilder->getQuery()->getResult();
过滤器
过滤器不是简单的键/值对。过滤器是一个无键的过滤器定义数组。每个过滤器定义都是一个数组,数组值因过滤器类型而异。
每个过滤器定义至少需要有一个 'type',它引用配置键,如 'eq'、'neq'、'between'。
每个过滤器定义至少需要有一个 'field',这是目标实体上的字段名称。
每个过滤器定义可以指定 'where',值为 'and' 或 'or'。
支持通过 AndX 和 OrX 过滤器类型来实现嵌套逻辑,如 and(x or y)。
构建 HTTP GET 查询
JavaScript 示例
$(function () { $.ajax({ url: "http://localhost:8081/api/db/entity/user_data", type: "GET", data: { 'filter': [ { 'field': 'cycle', 'where': 'or', 'type': 'between', 'from': '1', 'to': '100' }, { 'field': 'cycle', 'where': 'or', 'type': 'gte', 'value': '1000' } ] }, dataType: "json" }); });
查询关系
单值
可以通过关系查询集合 - 只需提供关系名称作为 fieldName
和标识符作为 value
。
假设我们定义了 2 个实体,User
和 UserGroup
...
/** * @Entity */ class User { /** * @ManyToOne(targetEntity="UserGroup") * @var UserGroup */ protected $group; }
/** * @Entity */ class UserGroup {}
通过以下过滤器查询用户资源,以查找属于 UserGroup id #1 的所有用户
['type' => 'eq', 'field' => 'group', 'value' => '1']
集合值
要匹配具有实体 B 的集合中的实体 A,请使用 ismemberof
。假设 User
与 UserGroup
有 ManyToMany(或 OneToMany)关联...
/** * @Entity */ class User { /** * @ManyToMany(targetEntity="UserGroup") * @var UserGroup[]|ArrayCollection */ protected $groups; }
通过以下过滤器查询用户资源,以查找属于 UserGroup id #1 的所有用户
['type' => 'ismemberof', 'field' => 'groups', 'value' => '1']
日期字段格式
当日期字段涉及过滤器时,您可以使用 PHP 日期格式选项指定日期格式。默认日期格式是 Y-m-d H:i:s
如果您有一个日期字段,其格式仅为 Y-m-d
,则将格式添加到过滤器中。有关完整的日期格式选项,请参阅 DateTime::createFromFormat
[ 'format' => 'Y-m-d', 'value' => '2014-02-04', ]
连接实体和别名查询
有一个内联 ORM 查询类型用于内连接,因此对于每种过滤器类型都有一个可选的 alias
。默认别名为 'row',指的是 REST 资源核心的实体。没有过滤器可以添加其他实体到返回数据中。也就是说,默认情况下,只有原始目标资源('row')将返回,无论应用了什么过滤器或排序。
内连接默认不包含在 api-tools-doctrine-querybuilder.global.php.dist
中。
此示例通过在行实体上已定义的内连接连接报告字段,然后过滤 r.id = 2
['type' => 'innerjoin', 'field' => 'report', 'alias' => 'r'], ['type' => 'eq', 'alias' => 'r', 'field' => 'id', 'value' => '2']
您可以使用 parentAlias
从内连接连接内连接的表
['type' => 'innerjoin', 'parentAlias' => 'r', 'field' => 'owner', 'alias' => 'o'],
内连接默认在 api-tools-doctrine-querybuilder.global.php.dist
中被注释。
还有一个 ORM 查询类型为 LeftJoin。此连接类型通常用于获取关系的空右侧。
LeftJoin 默认在 api-tools-doctrine-querybuilder.global.php.dist
中被注释。
['type' => 'leftjoin', 'field' => 'report', 'alias' => 'r'], ['type' => 'isnull', 'alias' => 'r', 'field' => 'id']
包含的过滤器类型
ORM 和 ODM
等于
['type' => 'eq', 'field' => 'fieldName', 'value' => 'matchValue']
不等于
['type' => 'neq', 'field' => 'fieldName', 'value' => 'matchValue']
小于
['type' => 'lt', 'field' => 'fieldName', 'value' => 'matchValue']
小于或等于
['type' => 'lte', 'field' => 'fieldName', 'value' => 'matchValue']
大于
['type' => 'gt', 'field' => 'fieldName', 'value' => 'matchValue']
大于等于
['type' => 'gte', 'field' => 'fieldName', 'value' => 'matchValue']
为空
['type' => 'isnull', 'field' => 'fieldName']
不为空
['type' => 'isnotnull', 'field' => 'fieldName']
注意:在In和NotIn过滤器中,日期不作为日期处理。建议您使用多个等于语句而不是这些过滤器来处理日期数据类型。
在...
['type' => 'in', 'field' => 'fieldName', 'values' => [1, 2, 3]]
不在...
['type' => 'notin', 'field' => 'fieldName', 'values' => [1, 2, 3]]
介于...
['type' => 'between', 'field' => 'fieldName', 'from' => 'startValue', 'to' => 'endValue']
类似(%
用作通配符)
['type' => 'like', 'field' => 'fieldName', 'value' => 'like%search']
仅ORM
是成员之一
['type' => 'ismemberof', 'field' => 'fieldName', 'value' => 1]
AndX
在AndX查询中,conditions
是一个数组,包含此处描述的任何过滤类型。连接始终是and
,因此条件内部的where
参数被忽略。AndX过滤器类型上的where
参数不会被忽略。
[ 'type' => 'andx', 'conditions' => [ ['field' =>'name', 'type'=>'eq', 'value' => 'ArtistOne'], ['field' =>'name', 'type'=>'eq', 'value' => 'ArtistTwo'], ], 'where' => 'and', ]
OrX
在OrX查询中,conditions
是一个数组,包含此处描述的任何过滤类型。连接始终是or
,因此条件内部的where
参数被忽略。OrX过滤器类型上的where
参数不会被忽略。
[ 'type' => 'orx', 'conditions' => [ ['field' =>'name', 'type'=>'eq', 'value' => 'ArtistOne'], ['field' =>'name', 'type'=>'eq', 'value' => 'ArtistTwo'], ], 'where' => 'and', ]
仅ODM
正则表达式
['type' => 'regex', 'field' => 'fieldName', 'value' => '/.*search.*/i']
包含排序类型
字段
['type' => 'field', 'field' => 'fieldName', 'direction' => 'desc']
自定义映射类型
如果您已配置自定义映射类型,您可以替换提供的Laminas\ApiTools\Doctrine\QueryBuilder\Filter\TypeCastInterface
实现,用您自己的实现。
例如,给定以下自定义类型转换器实现
namespace My\Custom; class TypeCaster implements \Laminas\ApiTools\Doctrine\QueryBuilder\Filter\TypeCastInterface { public function typeCastField($metadata, $field, $value, $format = null, $doNotTypecastDatetime = false) { // implement your type casting logic } }
然后您将提供您实现的工厂,并将包别名TypeCastInterface
指向它
// config/autoload/api-tools-doctrine-querybuilder-global.php use Laminas\ApiTools\Doctrine\QueryBuilder\Filter\TypeCastInterface; use Laminas\ServiceManager\Factory\InvokableFactory; use My\Custom\TypeCaster; return [ 'service_manager => [ 'aliases' => [ TypeCastInterface::class => TypeCaster::class, ], 'factories' => [ TypeCaster::class => InvokableFactory::class, ], ], ];