Symfony 2最佳实践DBAL没有对象原则

时间:2015-09-29 22:24:17

标签: php symfony pdo doctrine-orm doctrine

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

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

示例: Sql 1:Jo; DATE; Sql 2:客户端;汽车;时间

让我们告诉我,我不想创建一个实体来与教条一起使用......

我想使用DBAL(pdo doctrine sql query)来执行我的查询...就像在正常的PHP poo编程中一样。

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

提前感谢您的回答...... 我暂时避免学说,因为我原则上做了一些统计学,并且与symfony一起玩,并且逐渐增加了难度......

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

1 个答案:

答案 0 :(得分:3)

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

Entitydocs)是表示数据库表的对象。以后可以使用此对象在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 ]
    

    现在,只要您从$this->get('app.myservicename')致电Controller,您就会获得班级的实例。

  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');
    }
    
  3. 我建议你看看symfony best practices,看看哪些是解决常见问题的最佳方法。阅读main documentation也可以帮助您清除很多问题。