chrisandchris/symfony-rowmapper

此包已被弃用且不再维护。作者建议使用 chrisandchris/passive-record-orm 包代替。

为您的 PHP 应用程序提供数据库层、被动记录和 ORM 抽象层。


README

Build Status Code Climate Test Coverage Version Downloads Licence

尽管它的包名是,但这不仅仅是一个行映射器。而且它不仅仅是为 Symfony 设计的。该项目是一个 查询构建器SQL 结果集映射器,两者结合但仍然非常独立,因此您可以独立使用它们。

<?php

use ChrisAndChris\Common\RowMapperBundle\Services\Model\ConcreteModel;

class DemoRepo {
    /** @var ConcreteModel  */
    private $model;
    
    public function __construct(ConcreteModel $model){
        $this->model = $model;
    }
    
    public function getCustomerName($customerId) {
        $query = $this->model->getDependencyProvider()->getBuilder()->select()
            ->field('customer_name')
            ->table('customer')
            ->where()
                ->field('customer_id')->equals()->value($customerId)
            ->close()
            ->getSqlQuery();

        return $this->model->runWithFirstKeyFirstValue($query);
    }
}

此文档简要概述了此包提供的所有功能。我们将内容持续移动到 doc/ 目录中,因此请在那里查找更详细的信息。

它所做

  • 打开并处理 MySQL 连接
  • 提供简单的接口来构建预处理语句和查询数据库
  • 提供简单的接口来将结果映射到类

内部结构

基本内部原则如下

  • 存在类型(简单的键值类),它们代表语句的一部分
  • 使用解析器解析查询,并使用同名的片段(它们包含 SQL)
  • 返回查询

如何使用

## 配置 按照您通常的方式配置您的 symfony2 项目。该组件使用存储在 parameters.yml 中的数据库信息,并自动连接到指定的数据库。

实际上,没有其他配置选项。

简单查询

创建一个服务定义

services:
    project.demo_repo:
        class: DemoRepo
        arguments: ['@common_rowmapper.model']

创建仓库

<?php

use ChrisAndChris\Common\RowMapperBundle\Services\Model\ConcreteModel;

class DemoRepo {
    /** @var ConcreteModel  */
    private $model;
    
    public function __construct(ConcreteModel $model){
        $this->model = $model;
    }
    
    public function getCustomerName($customerId) {
        $query = $this->model->getDependencyProvider()->getBuilder()->select()
            ->field('customer_name')
            ->table('customer')
            ->where()
                ->field('customer_id')->equals()->value($customerId)
            ->close()
            ->getSqlQuery();

        return $this->model->runWithFirstKeyFirstValue($query);
    }
}

如果您想将更复杂的查询映射到类,可以使用类似以下的方法

<?php

use ChrisAndChris\Common\RowMapperBundle\Entity\Entity;

class CustomerEntity implements Entity {
    public $customerId;
    public $name;
    public $street;
    public $zip;
    public $city;
}

映射时使用此方法

<?php

use ChrisAndChris\Common\RowMapperBundle\Services\Model\ConcreteModel;

class DemoModel {
    
    /** @var ConcreteModel  */
    private $model;
    
    public function __construct(ConcreteModel $model){
        $this->model = $model;
    }
    
    public function getCustomer($customerId) {
        $query = $this->model->getDependencyProvider()->getBuilder()->select()
            ->fieldlist([
                'customer_id' => 'customerId',
                'cus_name' => 'name',
                'street',
                'zip',
                'city'
            ])
            ->table('customer')
            ->where()
                ->field('customer_id')->equals()->value($customerId)
            ->close()
            ->getSqlQuery();

        return $this->model->run($query, new SomeEntity());
    }
}

更多信息

field() 方法

您可以使用数组来分隔数据库、表、字段

field(['database', 'table', 'field'])`

如果您获取单个字段,您必须自己添加逗号

->field('field1')->c()
->field('field2')->c()

您也可以将闭包作为参数传递

->field(function () { return $value; });

value() 方法

使用此方法将参数附加到查询

->value($someValue);
->value(function () { return $someValue; });

fieldlist() 方法

此方法更加强大,以下是如何使用它的示例

简单的键值使用

fieldlist([
    'field' => 'alias',
    'customer_id' => 'customerId',
    'cus_name' => 'name'
])

指定数据库、表、字段

fieldlist([
    'database:table:field' => 'alias'
]);

混合任何内容

fieldlist([
    'database:table:field' => 'alias',
    'field1', // fetched by real field name
    'field2' => 'alias1'
]);

f(), where(), order(), groupBy()

这四种类型中的任何一种都会打开所谓的“大括号”。大括号代表一种子查询,它与之前的查询完全独立。在内部,在解析此子查询时,解析器原则上无法访问其他语句。

因此,如果您完成其中一个,只需调用 close() 或 end() 来关闭大括号即可。

->where()
    ->field('field1')->equals()->value(true)
->close()

raw() 方法

由于时间不足和满足任何需求,我简单地实现了 raw 方法。幸运的是,此方法能够使用参数 :D

->raw('SELECT customer_id FROM customer WHERE customer_name LIKE ?', [
    '%github%'
]);

in()

您可以使用以下两种方法简单地构建 IN 子句:

// option a
->in([1, 2, 3, 4, 5, 6])
// option b
->in()
    ->select()
    ->value(1)
->close()

选项 A 使用了全程的预处理语句,数组中的任何值都作为参数传递给数据库。

条件追加

有三种方法提供条件追加:

  • _if()
  • _else()
  • _end()

您可以嵌套 if,并且可以将闭包作为参数推送到 if 中。

->_if($condition === true)
    ->where()
    ->_if(function() { return $condition === true; })
        // ...
    ->_end()
        // ...
    ->close()
->_else()
    //
->_end()

其他方法

  • f() - 用于函数
  • where() - 构建 where 子句
  • any() - 一个受祝福的星号(邪恶的 SELECT *
  • value() - 参数
  • null() - sql 中的 NULL
  • isNull() - 使用 IS NULL 进行 null 比较
  • join() - 连接表
  • using() - 连接表的 using 子句
  • on() - 连接表的 on 子句
  • union() - 创建 UNION 语句
  • asLong() - 创建 while 循环
  • each() - 创建 each 循环