studiomado/query-bundle

该软件包最新版本(v2.4.23)没有提供许可证信息。

安装次数: 7,285

依赖项: 0

建议者: 0

安全: 0

星标: 13

关注者: 8

分支: 5

开放性问题: 12

类型:symfony-bundle

v2.4.23 2018-09-20 14:32 UTC

README

最新稳定版本 Latest Stable Version

运行测试

  • ./runtests.sh 运行所有单元测试
  • ./agile.sh 生成测试文档
  • ./coverage.sh 生成和打开 HTML 覆盖率

Plain symfony project for query-bundle

该项目的目的是了解如何将 studiomado/query-bundle 安装在普通的 symfony 项目中。

  • 数据库配置
  • 安装 query-bundle
  • 创建至少一个实体

数据库配置

请记住更新 parameter.yml 文件、parameter.yml.dist 和 config.yml 文件。在 config.yml 文件中,请记住驱动必须从 pdo_sqlite 更改为启用 doctrine 与此数据库协同工作。

这只是个示例:在这个例子中我们使用 sqlite,但在生产中您可以使用 mysql 或 postgres 或任何 doctrine 支持的数据库。

prompt> ./bin/console doctrine:database:create
Created database /path/to/project/var/data/data.sqlite for connection named default

安装 query-bundle

prompt> composer require studiomado/query-bundle

创建至少一个实体

创建至少一个实体 ...

prompt> ./bin/console doctrine:generate:entity

在这个例子中,我创建了一个实体 Task,按照以下命令步骤。

created ./src/AppBundle/Entity/
created ./src/AppBundle/Entity/Task.php
> Generating entity class src/AppBundle/Entity/Task.php: OK!
> > Generating repository class src/AppBundle/Repository/TaskRepository.php: OK!

... 并更新模式 ...

	prompt> ./bin/console doctrine:schema:update
	ATTENTION: This operation should not be executed in a production environment.
						 Use the incremental update to detect changes during development and use
						 the SQL DDL provided to manually update your database in production.

	The Schema-Tool would execute "1" queries to update the database.
	Please run the operation by passing one - or both - of the following options:
			doctrine:schema:update --force to execute the command
			doctrine:schema:update --dump-sql to dump the SQL statements to the screen

只有使用 force 选项,模式更新才有效

prompt> ./bin/console doctrine:schema:update --force
Updating database schema...
Database schema updated successfully! "1" query was executed

只需查看数据库内容(现在它是空的)。

prompt> ./bin/console doctrine:query:dql "select t from AppBundle:Task t"

查询将返回一个空的结果数组

 array (size=0)
   empty

只需添加第一个任务 ...

prompt> ./bin/console doctrine:query:sql "insert into task values (null, 'complete this guide', 'todo') "

并查看内容

prompt> ./bin/console doctrine:query:dql "select t from AppBundle:Task t"

array (size=1)
  0 =>
    object(stdClass)[507]
      public '__CLASS__' => string 'AppBundle\Entity\Task' (length=21)
      public 'id' => int 1
      public 'description' => string 'complete this guide' (length=19)
      public 'status' => string 'todo' (length=4)

完成安装

首先安装供应商

prompt> composer require jms/serializer-bundle
prompt> composer require willdurand/hateoas-bundle
prompt> composer require white-october/pagerfanta-bundle
prompt> composer require friendsofsymfony/rest-bundle

然后,... 在您的 app/AppKernel 中添加供应商

new FOS\RestBundle\FOSRestBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
new Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle(),

完成配置并使用包

一旦完成,您可以使用 query-bundle 添加新端点以查询数据库。

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class DefaultController extends Controller
{
    /** @Route("/", name="homepage") */
    public function indexAction(
        Request $request,
        \Doctrine\ORM\EntityManager $em,
        \JMS\Serializer\Serializer $serializer
    ) {
        $data = $em->getRepository('AppBundle:Task')
            ->setRequest($request)
            ->findAllPaginated();

        $content = $serializer->serialize($data, 'json');

        return new Response($content, 200);
    }
}

配置实体存储库

现在请确保您的存储库扩展了正确的 BaseRepository。

namespace AppBundle\Repository;

class TaskRepository extends \Mado\QueryBundle\Repositories\BaseRepository
{
    // to do …
}
namespace AppBundle\Entity;

/** @ORM\Entity(repositoryClass="AppBundle\Repository\TaskRepository") */
class Task
{
    // to do …
}

自定义实体序列化

现在,如果您想自定义响应,请添加

use JMS\Serializer\Annotation as JMS;

在您的实体上方并完成您的 JMS 配置。请参阅 JMS 文档以获取完整的文档。

这里有一些示例

查找所有(无分页)

BaseRepository 中添加了新方法
当您需要应用筛选和排序但没有分页的结果时

public function findAllNoPaginated();

这个功能是创建 Excel 报告所需的,将结果注入 Excel 报告

无分页示例

在控制器中

public function getTasksExcelReportAction(Request $request)
    {
        $tasks = $this->getDoctrine()
            ->getRepository('AppBundle:Task')
            ->findAllNoPaginated();
        
        $reportExcel = new TasksReport($tasks);
        $reportExcel->createReport();
        
        $excelContent = $reportExcel->printReport();
        
        return new Response(
            $excelContent,
            200, [
                'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            ]
        );        
    } 

分页示例

在控制器中

    public function getTasksAction(Request $request)
    {
        return $this->getDoctrine()
            ->getRepository('AppBundle:Task')
            ->setRequest($request)
            ->findAllPaginated();
    }

查询

AND 条件

如果您想使用这个库创建 AND 条件,例如,您可以从客户端创建,例如使用简单的 GET 请求,如下所示

/api/foo?filtering[name|eq]=bar&filtering[surname|eq]=bar

此请求将生成如下查询

SELECT f0_.id AS id_0, f0_.name AS name_1, f0_.surname AS surname_2" .
FROM foo f0_" .
WHERE f0_.name = "bar" AND f0_.surname = "bar"

OR 条件

如果您想使用这个库创建 OR 条件,例如,您可以从客户端创建,例如使用简单的 GET 请求,如下所示

/api/foo?filtering_or[name|eq]=bar&filtering_or[surname|eq]=bar

此请求将生成如下查询

SELECT f0_.id AS id_0, f0_.name AS name_1, f0_.surname AS surname_2" .
FROM foo f0_" .
WHERE ((f0_.name = "bar" OR f0_.surname = "bar"))

相反,如果您想要更多分开的 OR 条件,您可以这样做

/api/foo?filtering_or[name|eq|1]=bar&filtering_or[surname|eq|1]=bar&filtering_or[group|contains|2]=baz&filtering_or[role|contains|2]=baz

此请求将生成如下查询

SELECT f0_.id AS id_0, f0_.name AS name_1, f0_.surname AS surname_2, f0_.group AS group_3, f0_.role AS role_4" .
FROM foo f0_" .
WHERE (f0_.name = "bar" OR f0_.surname = "bar") AND (f0_.group LIKE "%baz%" OR f0_.role LIKE "%baz%")

这可以通过使用操作符后面的计数器来完成,操作符由 | 分隔

搜索关系

如果您想在包含另一个实体的条件所在的实体内部进行搜索,您可以这样做:

/api/users?filtering[_embedded.group.name|contains =bar

此请求将生成如下查询

SELECT u0_.id AS id_0 u0_.username AS username_1,  u0_.group_id AS group_id_2 " .
FROM User u0_
LEFT JOIN Group g1_ ON u0_.group_id = g1_.id " .
WHERE g1_.name LIKE "%bar%"

为此,您需要在用户实体内部添加一些Hateoas注解,如下所示:

 * @Hateoas\Relation(
 *     "groups",
 *     embedded = @Hateoas\Embedded(
 *         "expr(object.getGroups())",
 *          exclusion = @Hateoas\Exclusion(
 *              excludeIf = "expr(object.getGroups().isEmpty() === true)",
 *              groups={"groups"},
 *              maxDepth = 1
 *          )
 *     ),
 *     exclusion = @Hateoas\Exclusion(
 *              excludeIf = "expr(object.getGroups().isEmpty() === true)",
 *              groups={"groups"},
 *              maxDepth = 1
 *          )
 * )
 

如果您正确添加Hateoas注解,您可以搜索的范围将不仅仅局限于“一级”。以下是一个示例:

/api/users?filtering[_embedded.profile.location.country.name|contains]=italy

在这个示例中,您搜索所有拥有国家位置名称为意大利的配置文件的用户。
配置文件、位置和国家都是实体,名称是字段。

您还可以在过滤条件中使用_embedded过滤器。