1. 数据查询

Doctrine 2.1 附带了SQL语言的一个强大的查询构建器,这个查询构建器有方法添加部分的SQL语句,如果你建立了完整的状态,你可以使用它生成的链接来执行它,它的接口大致和DQL查询构建器的接口相同

你可以访问查询构建器,通过调用 Doctrine\DBAL\Connection#createQueryBuilder:

<?php
public function setUp()
{
    $connectionParams = config::get('database.connections.default');
    $this->conn = DriverManager::getConnection($connectionParams, new Configuration);
}


$conn = db::connection();
$qb = $conn->createQueryBuilder();

1.1.1. 5.1 安全:安全防范SQL注入

了解查询生成器如何防止SQL注入这是很重要的,因为SQL表达式几乎允许每一个条件和定位Doctrine查询构建器,要能防止SQL注入,只有通过调用方法setFirstResult()setMaxResults()

其他所有方法都无法区分用户和开发者的输入,因此有受到SQL注入的可能性。

为了和查询生成器一起安全的运行,你千万不要将用户的输入传递给任何查询生成器并使用占位符的方法,或名称语法相结合 $qb->setParameter($placeholder, $value)替代:

<?php

$qb->select('id', 'name')
    ->from('users')
    ->where('email = ?')
    ->createPositionalParameter(0, $userInputEmail);

注:由于一个API设计错误数值参数在查询生成器, API开始指向0,而不是1的PDO API。这是非常不幸的,但我们没有发现BC方式来解决这个问题。

1.1.2. 5.2 构建查询

\Doctrine\DBAL\Query\QueryBuilder 支持创建 SELECTINSERTUPDATE,和DELETE 查询,使用哪种类型的查询取决于您正在使用的方法。

SELECT 查询 :在你调用select()方法时开始

<?php

$qb->select('id', 'name')
    ->from('users');

INSERT, UPDATEDELETE查询:你可以通过表名 insert($tableName)update($tableName)delete($tableName)

<?php

$qb->insert('users');


$qb->update('users');


$qb->delete('users');

你可以将查询构建器转换为它的SQL字符串表示,通过调用$qb -> getSQL()或对象的字符串。

5.2.1 WHERE 子句

SELECTUPDATEDELETE查询类型允许使用以下API:where子句

<?php

$qb->select('id', 'name')
    ->from('users')
    ->where('email = ?');

调用where()覆盖前面的条件子句,你可以防止这样通过表达式结合引入andWhere()orWhere()方法,或者可以使用表达式来生成where子句

5.2.2 表别名

from()方法 接受一个可选的第二个参数指定一个表别名。

<?php

$qb->select('u.id', 'u.name')
    ->from('users', 'u')
    ->where('u.email = ?');

5.2.3 GROUP BY 和 HAVING

SELECT语句可以指定GROUP BY子句和 HAVING 子句,使用 having()的效果和使用 where()一样,有一致的的andhaving()orhaving()方法来结合谓词,对于GROUP BY,你可以使用groupBy()方法,取代之前的表达式或使用addGroupBy()来添加:

<?php
$qb->select('DATE(last_login) as date', 'COUNT(id) AS users')
    ->from('users')
    ->groupBy('DATE(last_login)')
    ->having('users > 10');

5.2.4 加入条件

对于SELECT子句可以产生不同类型的连接:INNER, LEFT and RIGHT,正确的连接是不跨所有平台移植(例如Sqlite不支持)。

联接总是属于from子句的一部分。这就是为什么你必须指定别名的联接部分属于作为第一个参数。第二个和第三个参数你可以指定名称和连接表的别名,第四个参数包含在ON条款。

<?php
$qb->select('u.id', 'u.name', 'p.number')
    ->from('users', 'u')
    ->innerJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');

join()方法的用法说明,innerJoin(),leftJoin()rightJoin()是相同的,join()是一个innerjoin()速记语法。

5.2.5 Order-By

orderBy($sort, $order = null)方法添加order BY子句的表达。注意:可选$order参数是不安全的用户输入和接受SQL表达式。

<?php
$qb->select('id', 'name')
    ->from('users')
    ->orderBy('username', 'ASC')
    ->addOrderBy('last_login', 'ASC NULLS FIRST');

使用addOrderBy方法添加,而不是取代orderBy条款。

5.2.6 限制条款

只有几个数据库厂商的限制条款从MySQL已知,但我们支持此功能对所有供应商使用工作区。使用这个功能,你必须调用方法setFirstResult($offset)设置偏移量和setMaxResults($limit)设置限制返回的结果。

<?php
$qb->select('id', 'name')
    ->from('users')
    ->setFirstResult(10)
    ->setMaxResults(20);

5.2.7 VALUES

INSERT条款设置列的值而插入的值可以用values()方法查询构建器:

<?php

$qb->insert('users')
    ->values(
        array(
            'name' => '?',
            'password' => '?'
        )
    )
    ->createPositionalParameter(0, $username)
    ->createPositionalParameter(1, $password);

每个后续的调用 values()覆盖任何先前的设置值。设置单个值,而不是一次设置全部用setValue()方法也是可能的:

<?php

$qb->insert('users')
    ->setValue('name', '?')
    ->setValue('password', '?')
    ->createPositionalParameter(0, $username)
    ->createPositionalParameter(1, $password);

// INSERT INTO users (name, password) VALUES (?, ?)

当然你也可以使用这两种方法结合在一起:

<?php

$qb->insert('users')
    ->values(
        array(
            'name' => '?'
        )
    )
    ->createPositionalParameter(0, $username);

// INSERT INTO users (name) VALUES (?)

if ($password) {
    $qb->setValue('password', '?')
        ->createPositionalParameter(1, $password) ;

    // INSERT INTO users (name, password) VALUES (?, ?)
}

没有设置任何值,将导致空插入语句:

<?php

$qb->insert('users');

// INSERT INTO users () VALUES ()

5.2.8 设置条款

为更新的条款列设置为新值是必要的,可以用一组set()方法查询生成器。请注意,第二个参数允许用户输入的表达式,它是不安全的用户输入:

<?php

$qb->update('users', 'u')
    ->set('u.logins', 'u.logins + 1')
    ->set('u.last_login', '?')
    ->createPositionalParameter(0, $userInputLastLogin);

1.1.3. 5.3 构建表达式

对于更复杂的WHERE, HAVING或其他条款可以使用表达式构建这些查询部分。您可以借助表达式API,通过调用$qb -> expr(),然后调用辅助方法。

最值得注意的是您可以使用表达式来建立嵌套 And-/Or语句:

<?php

$qb->select('id', 'name')
    ->from('users')
    ->where(
            $qb->expr()->andX(
            $qb->expr()->eq('username', '?'),
            $qb->expr()->eq('email', '?')
        )
    );

andX()orX()方法接受一个任意数量的参数,可以相互嵌套。

这有一些方法来创建的比较和其他SQL表达式对象上的片段,你可以在API文档上看到。

1.1.4. 5.4 绑定参数占位符

通常在构建一个查询的时候没有必要知道的确切占位符的名字。您可以使用两个助手方法来将一个值绑定到一个占位符和直接使用查询的返回值的占位符:

<?php

$qb->select('id', 'name')
    ->from('users')
    ->where('email = ' .  $qb->createNamedParameter($userInputEmail));

// SELECT id, name FROM users WHERE email = :dcValue1

$qb->select('id', 'name')
    ->from('users')
    ->where('email = ' . $qb->createPositionalParameter($userInputEmail));

// SELECT id, name FROM users WHERE email = ?

results matching ""

    No results matching ""