【问题标题】:Symfony 2 best practice DBAL without object doctrineSymfony 2 最佳实践 DBAL 无对象原则
【发布时间】:2015-09-29 22:24:17
【问题描述】:

好吧,我终于开始学习 Symfony,我想人们会理解我的问题(我希望)和我希望构建我的代码的愿望......

好吧,我想创建一个名为 Reception 的类,并且这个类在每个方法/函数中都有一个 sql。 each 和 evry 方法可以返回不同的列结果。

示例: Sql 1:乔;日期; Sql 2:客户端;汽车;时间

让我们告诉你,我不想创建一个实体来将它与学说一起使用......

我想使用 DBAL(pdo 学说 sql 查询)来执行我的查询……就像在普通的 PHP 便便编程中一样。

最后的问题是:我应该把这个类作为一个服务,实体吗?或者我可以简单地将 pdo 查询放在控制器中....

提前感谢您的回答... 我暂时避免教条,因为我主要做一些统计,也玩一些 symfony 并逐步提高难度...

感谢您的理解... 美好的一天

【问题讨论】:

    标签: php symfony pdo doctrine-orm doctrine


    【解决方案1】:

    Service (docs) 通常只是一个负责执行某些特定任务的类。假设您有一些统计数据需要在发生特定事件时更新(即文件被下载、喜欢等),并且您有多个控制器在这些不同事件发生的地方。简单地“复制粘贴”您的代码将是一个非常糟糕的主意。更好的方法是创建服务并调用它。

    Entity(docs) 是一个代表数据库表的对象。这个对象以后可以用来在 Symfony 中生成表单。创建Entity 后,您可以创建EntityRepository。它用于存储更全面的 sql 查询。例如,您可以使用这样的方法:

    public function findUsersWithOrders() {
        // Here you can:
        //  1. use queryBuilder, which generates the query for you
        //  2. write your DQL (Doctrine Query Language) manually
        //  3. write a plain SQL query and return the results
    }
    

    我强烈建议您使用这种方法 - 一旦您掌握它,它将为您节省大量时间,恕我直言,这是一种更好的编码实践。

    如果您仍然决定要追求将查询存储在类中的想法:

    1. 是的,您可以创建一个Service 并将其用于此目的。您应该使用 Symfony >= 2.3,因为 Lazy Services 可以优化服务加载。以下是您的服务的外观示例:

      // App\BaseBundle\Services\MyServiceName.php
      namespace App\BaseBundle\Services;
      
      use Doctrine\ORM\EntityManager;
      
      class MyServiceName {
      
          /**
           * @var \Doctrine\ORM\EntityManager
           */
          private $em;
      
          /**
           * @var \Doctrine\DBAL\Connection
           */
          private $connection;
      
          public function __construct(EntityManager $entityManager) {
              $this->em = $entityManager;
              $this->connection = $entityManager->getConnection();
          }
      
          public function getUsers(){
              // Update query
              $this->connection->query('UPDATE statistics SET counter=counter+1 WHERE id = 1')->execute();
      
              // Prepare (you can use just query() as well)
              $select = $this->connection->prepare('SELECT * FROM users WHERE username LIKE :username');
              $select->bindValue(':username', '%sample%');
              $select->execute();
      
              return $select->fetch(\PDO::FETCH_ASSOC);
          }
      }
      

      然后,在您的 services.yml 文件中,您需要输入以下内容:

      app.myservicename:
          class: App\BaseBundle\Services\MyServiceName
          arguments: [ @doctrine.orm.entity_manager ]
      

      现在,每当您从 Controller 调用 $this->get('app.myservicename') 时,您都会获得您的类的一个实例。

    2. 当然,您也可以将 sql 代码放入控制器中。这不是一个好的做法,但您应该避免这样做。这个例子向你展示了如何做到这一点:

      /**
       * @Route("/some/route")
       * @Template()
       */
      public function indexAction()
      {
      
          /**
           * @var \Doctrine\ORM\EntityManager $em
           */
          $em = $this->getDoctrine()->getManager();
      
          // some business logic ...
      
          try {
              $em->getConnection()->query('UPDATE statistics SET counter=counter+1 WHERE id = 1')->execute();
          } catch(\Doctrine\DBAL\DBALException $e){
              // the query might fail, catch the exception and do something with it.
          }
      
          // other business logic...
      
          return array('name' => 'Hello World');
      }
      

    我建议您查看symfony best practices,了解解决常见问题的最佳方法。另外阅读main documentation 会帮助你解决很多问题。

    【讨论】:

    • 你好 tfld ! ! !哇感谢您理解我的问题以及您完整而清晰的回答......它非常有用,我这个月使用了两次。我终于明白了实体、服务之间的区别以及如何构建我的代码效率! :) 美好的一天!
    • 我很高兴能帮上忙!我从经验中知道,当你刚开始使用 symfony 时,这有点令人困惑,但过了一段时间你就会意识到它有多大的潜力。干杯! :)
    猜你喜欢
    • 1970-01-01
    • 2011-07-12
    • 2011-12-27
    • 2021-07-18
    • 2012-02-19
    • 2015-01-13
    • 2014-06-16
    • 2021-07-31
    • 2010-10-04
    相关资源
    最近更新 更多