jackdpeterson/psr7-doctrine-querybuilder

该包已被废弃,不再维护。未建议替代包。

PSR-7 Doctrine QueryBuilder模块 -- 使用PSR-7请求的$args操作Doctrine Query Builder实例

1.5.1 2016-11-14 18:11 UTC

README

此库提供从数组参数中查询构建器指令。此库旨在将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 jackdpeterson/psr7-doctrine-querybuilder

安装后,将jackdpeterson\Doctrine\QueryBuilder添加到config/application.config.php中的模块列表中。

zf-component-installer

如果您使用zf-component-installer,该插件将为您将zf-doctrine-querybuilder安装为模块。

配置模块

config/zf-doctrine-querybuilder.global.php.dist复制到config/autoload/zf-doctrine-querybuilder.global.php,并编辑orm和odm的别名列表以启用默认值。

与Slim框架一起使用

要启用所有过滤器,您可以覆盖默认的查询提供者在zf-apigility-doctrine中。将以下内容添加到您的zf-doctrine-querybuilder.global.php配置文件中,并且如果它们在$_GET['filter']$_GET['order-by']请求中,则将应用过滤器。这些$_GET键可以通过zf-doctrine-querybuilder-options自定义。

'zf-apigility-doctrine-query-provider' => [
    'aliases' => [
        'default_orm' => \jackdpeterson\Doctrine\QueryBuilder\Query\Provider\DefaultOrm::class,
        'default_odm' => \jackdpeterson\Doctrine\QueryBuilder\Query\Provider\DefaultOdm::class,
    ],
    'factories' => [
        \jackdpeterson\Doctrine\QueryBuilder\Query\Provider\DefaultOrm::class => \jackdpeterson\Doctrine\QueryBuilder\Query\Provider\DefaultOrmFactory::class,
        \jackdpeterson\Doctrine\QueryBuilder\Query\Provider\DefaultOdm::class => \jackdpeterson\Doctrine\QueryBuilder\Query\Provider\DefaultOdmFactory::class,
    ],
],

使用

配置示例

'zf-doctrine-querybuilder-orderby-orm' => [
    'aliases' => [
        'field' => \jackdpeterson\Doctrine\QueryBuilder\OrderBy\ORM\Field::class,
    ],
    'factories' => [
        \jackdpeterson\Doctrine\QueryBuilder\OrderBy\ORM\Field::class => \Zend\ServiceManager\Factory\InvokableFactory::class,
    ],
],
'zf-doctrine-querybuilder-filter-orm' => [
    'aliases' => [
        'eq' => \jackdpeterson\Doctrine\QueryBuilder\Filter\ORM\Equals::class,
    ],
    'factories' => [
        \jackdpeterson\Doctrine\QueryBuilder\Filter\ORM\Equals::class => \Zend\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('ZfDoctrineQueryBuilderFilterManagerOrm');
$orderByManager = $serviceLocator->get('ZfDoctrineQueryBuilderOrderByManagerOrm');

$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: "https://: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个实体,UserUserGroup...

/**
 * @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。假设UserUserGroup具有多对多(或一对多)关联...

/**
 * @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')会被返回,无论通过此模块应用了什么过滤器或排序。

默认情况下,内连接不包括在zf-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'],

要启用内连接,请将以下内容添加到您的配置中。

'zf-doctrine-querybuilder-filter-orm' => [
    'aliases' => [
        'innerjoin' => \jackdpeterson\Doctrine\QueryBuilder\Filter\ORM\InnerJoin::class,
    ],
    'factories' => [
        \jackdpeterson\Doctrine\QueryBuilder\Filter\ORM\InnerJoin => \Zend\ServiceManager\Factory\InvokableFactory::class,
    ],
],

包含的过滤器类型

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过滤器中,日期被视为非日期。建议您对于日期数据类型,使用多个Equals语句而不是这些过滤器。

In

['type' => 'in', 'field' => 'fieldName', 'values' => [1, 2, 3]]

NotIn

['type' => 'notin', 'field' => 'fieldName', 'values' => [1, 2, 3]]

Between

['type' => 'between', 'field' => 'fieldName', 'from' => 'startValue', 'to' => 'endValue']

Like(使用%作为通配符)

['type' => 'like', 'field' => 'fieldName', 'value' => 'like%search']

ORM 仅

是成员

['type' => 'ismemberof', 'field' => 'fieldName', 'value' => 1]

AndX

在AndX查询中,conditions是这里描述的任何过滤器类型的数组。连接始终是and,所以where参数在conditions内部被忽略。AndX过滤器类型上的where参数不会被忽略。

[
    'type' => 'andx',
    'conditions' => [
        ['field' =>'name', 'type'=>'eq', 'value' => 'ArtistOne'],
        ['field' =>'name', 'type'=>'eq', 'value' => 'ArtistTwo'],
    ],
    'where' => 'and',
]

OrX

在OrX查询中,conditions是这里描述的任何过滤器类型的数组。连接始终是or,所以where参数在conditions内部被忽略。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']