开放的编程资料库

当前位置:我爱分享网 > PHP教程 > 正文

Doctrine DBAL QueryBuilder

DoctrineDBALQueryBuilder教程展示了如何使用Doctrine的QueryBuilder在PHP中对数据库进行编程。

学说

Doctrine是一组PHP库,主要专注于在PHP中提供持久性服务。它的主要项目是对象关系映射器(ORM)和数据库抽象层(DBAL)。Doctrine是一个开源项目,在MIT许可下免费提供。

Doctrine查询生成器

DoctrineQueryBuilder提供了一个方便、流畅的界面来创建和运行数据库查询。它是对运行SQL语句的低级细节的抽象。它使程序员免受复杂过程的影响。

Doctrine有两种查询构建器;一个用于ORM,一个用于DBAL。在本教程中,我们介绍了DBAL的QueryBuilder。

Doctrine数据库抽象层(DBAL)是一个位于PDO之上的抽象层,它提供了一个直观且灵活的API,用于与最流行的关系数据库进行通信。

PostgreSQL数据库

在本教程中,我们使用PostgreSQL数据库。

-- cars.sql for PostgreSQL database

DROP TABLE IF EXISTS cars;
CREATE TABLE cars(id SERIAL PRIMARY KEY, name VARCHAR(255), price INT);
INSERT INTO cars(name, price) VALUES('Audi',52642);
INSERT INTO cars(name, price) VALUES('Mercedes',57127);
INSERT INTO cars(name, price) VALUES('Skoda',9000);
INSERT INTO cars(name, price) VALUES('Volvo',29000);
INSERT INTO cars(name, price) VALUES('Bentley',350000);
INSERT INTO cars(name, price) VALUES('Citroen',21000);
INSERT INTO cars(name, price) VALUES('Hummer',41400);
INSERT INTO cars(name, price) VALUES('Volkswagen',21600);

这些SQL命令创建了一个cars表。

学说安装

我们安装了Doctrine和一些辅助工具。

$ composer req doctrine/dbal

我们安装Doctrine。请注意,DBAL层包含在doctrine/dbal包中。

$ composer req symfony/var-dumper
$ composer req tightenco/collect

我们安装Symfony的dumper和Laravel集合。我们将在示例中使用它们。

$ composer dumpautoload

我们生成需要包含在项目中的所有类的列表。composer重新读取composer.json文件以构建文件列表自动加载。

引导DoctrineCLI示例

我们创建了一个将包含在所有示例中的引导文件。

<?php

require_once "vendor/autoload.php";

use Doctrine\DBAL\DriverManager;

$attrs = ['driver' => 'pdo_pgsql', 'host' => 'localhost', 'dbname' => 'testdb', 
    'port' => 5432, 'user' => 'postgres', 'password' => 's$cret'];

$conn = DriverManager::getConnection($attrs);

在引导文件中,我们包含自动加载文件并设置与PostgreSQL数据库的连接。

获取PostgreSQL版本

在第一个示例中,我们获取了PostgreSQL的版本。

<?php

require_once "bootstrap.php";

$queryBuilder = $conn->createQueryBuilder();
$queryBuilder = $queryBuilder->select('version()');

$version = $queryBuilder->execute()->fetchColumn(0);
echo $version . "\n";

该示例打印PostgreSQL数据库的版本。

$queryBuilder = $conn->createQueryBuilder();

从连接对象,我们使用createQueryBuilder()创建一个查询生成器。

$queryBuilder = $queryBuilder->select('version()');

我们使用select()执行version()函数。

$version = $queryBuilder->execute()->fetchColumn(0);

我们执行查询并使用fetchColumn()获取结果。注意方法调用的链接;这称为流畅的API。

$ php version.php
PostgreSQL 11.1, compiled by Visual C++ build 1914, 64-bit

这是输出。

DoctrineQueryBuilderfetchall

fetchall()方法返回表中的所有行。

<?php

require_once "bootstrap.php";

$queryBuilder = $conn->createQueryBuilder();
$queryBuilder->select('*')->from('cars');

$stm = $queryBuilder->execute();
$data = $stm->fetchAll();

$coll = collect($data);
$sorted = $coll->sortBy('price');

$sorted->each(function($item, $key) {
    echo sprintf("Id: %d Name: %s Price: %d\n", $item['id'], $item['name'], $item['price']);
});

该示例从cars表中检索所有行。

$queryBuilder->select('*')->from('cars');

我们从cars表中选择所有行。select()将列名显示为参数。

$stm = $queryBuilder->execute();
$data = $stm->fetchAll();

我们执行查询并使用fetchAll()获取所有行。

$coll = collect($data);
$sorted = $coll->sortBy('price');

我们使用Laravel集合对数据进行排序。

$sorted->each(function($item, $key) {
    echo sprintf("Id: %d Name: %s Price: %d\n", $item['id'], $item['name'], $item['price']);
});

排序后的数据打印到控制台。

$ php fetch_all.php
Id: 3 Name: Skoda Price: 9000
Id: 6 Name: Citroen Price: 21000
Id: 8 Name: Volkswagen Price: 21600
Id: 4 Name: Volvo Price: 29000
Id: 7 Name: Hummer Price: 41400
Id: 1 Name: Audi Price: 52642
Id: 2 Name: Mercedes Price: 57127
Id: 5 Name: Bentley Price: 350000

这是输出。数据按price列排序。

DoctrineQueryBuilder表别名

我们可以给数据库表起别名。当表名很长并且我们使用多个表时,这很有用。

<?php

require_once "bootstrap.php";

$queryBuilder = $conn->createQueryBuilder();

$queryBuilder = $queryBuilder->select('*')->from('cars', 'c')
    ->where('c.price < 30000');

$selected = $queryBuilder->execute()->fetchAll();
dump($selected);

该示例打印所有价格低于30000的汽车。

$queryBuilder = $queryBuilder->select('*')->from('cars', 'c')
    ->where('c.price < 30000');

我们给cars表别名c。稍后,我们通过别名引用该表。

dump($selected);

我们用dump()输出数据。

$ php table_alias.php
array:4 [
    0 => array:3 [
    "id" => 3
    "name" => "Skoda"
    "price" => 9000
    ]
    1 => array:3 [
    "id" => 4
    "name" => "Volvo"
    "price" => 29000
    ]
    2 => array:3 [
    "id" => 6
    "name" => "Citroen"
    "price" => 21000
    ]
    3 => array:3 [
    "id" => 8
    "name" => "Volkswagen"
    "price" => 21600
    ]
]

有四辆价格低于30000的汽车。输出使用Symfony的自卸车进行了很好的格式化。输出在终端上也是彩色的。

DoctrineQueryBuildersetParameter

setParameter()用于将参数设置为查询占位符。Doctrine支持位置参数和命名参数。

参数化查询用于保护代码免受SQL注入攻击并提高查询效率。

<?php

require_once "bootstrap.php";

$id = 6;

$queryBuilder = $conn->createQueryBuilder();

$queryBuilder = $queryBuilder->select('name')->from('cars')
    ->where('id = ?')->setParameter(0, $id);

$car_name = $queryBuilder->execute()->fetchColumn(0);
echo $car_name . "\n";

在示例中,我们获取了ID为6的行。我们使用参数化查询来获取该列。

$queryBuilder = $queryBuilder->select('name')->from('cars')
    ->where('id = ?')->setParameter(0, $id);

占位符用?字符标识。这种类型称为位置参数。使用setParameter(),我们将值映射到占位符。

$ php fetch_column.php
Citroen

这是输出。

DoctrineQueryBuilderorderBy

可以使用orderBy()对数据进行排序。有时我们无法控制数据发送给我们的方式;在这种情况下,我们可以使用LaravelCollections对数据进行排序,就像我们在fetchall示例中所做的那样。

<?php

require_once "bootstrap.php";

$queryBuilder = $conn->createQueryBuilder();
$queryBuilder
    ->select('*')
    ->from('cars')
    ->orderBy('name', 'desc');

$stm = $queryBuilder->execute();
$data = $stm->fetchAll();

$coll = collect($data);

$coll->each(function($item, $key) {
    echo sprintf("id: %d name: %s price: %d\n", $item['id'], $item['name'], $item['price']);
});

该示例从cars表中检索所有行,并按汽车名称降序对它们进行排序。

$queryBuilder
    ->select('*')
    ->from('cars')
    ->orderBy('name', 'desc');

数据被选择和排序。

$ php order_by.php
id: 4 name: Volvo price: 29000
id: 8 name: Volkswagen price: 21600
id: 3 name: Skoda price: 9000
id: 2 name: Mercedes price: 57127
id: 7 name: Hummer price: 41400
id: 6 name: Citroen price: 21000
id: 5 name: Bentley price: 350000
id: 1 name: Audi price: 52642

这是输出。

(adsbygoogle=window.adsbygoogle||[]).push({});

DoctrineQueryBuilder在哪里

以下示例显示如何使用WHEREIN子句构建查询。

<?php

require_once "bootstrap.php";

use Doctrine\DBAL\Connection;

$ids = [2, 4, 6];

$queryBuilder = $conn->createQueryBuilder();

$queryBuilder->select('*')->from('cars')
    ->where('id IN (?)')->setParameter(0, $ids, Connection::PARAM_INT_ARRAY);
$cars = $queryBuilder->execute()->fetchAll();

$data = collect($cars);

$data->each(function ($e) {
    dump($e);
});

该示例打印具有指定ID的汽车:2、4和6。

$queryBuilder->select('*')->from('cars')
    ->where('id IN (?)')->setParameter(0, $ids, Connection::PARAM_INT_ARRAY);

我们需要告诉Doctrine我们使用一个数组作为带有Connection::PARAM_INT_ARRAY标志的参数。

$ php where_in.php
array:3 [
    "id" => 2
    "name" => "Mercedes"
    "price" => 57127
]
array:3 [
    "id" => 4
    "name" => "Volvo"
    "price" => 29000
]
array:3 [
    "id" => 6
    "name" => "Citroen"
    "price" => 21000
]

这是输出。

结合WHERE子句的DoctrineQueryBuilder

我们可以通过添加andWhere()来组合WHERE子句。

<?php

require_once "bootstrap.php";

$minPrice = 10000;
$maxPrice = 50000;

$queryBuilder = $conn->createQueryBuilder();
$queryBuilder
    ->select('*')
    ->from('cars')
    ->where('price > ?')
    ->andWhere('price < ?')
    ->setParameter(0, $minPrice)
    ->setParameter(1, $maxPrice);

$stm = $queryBuilder->execute();
$data = $stm->fetchAll();

$coll = collect($data);

$coll->each(function($item, $key) {
    echo sprintf("id: %d name: %s price: %d\n", $item['id'], $item['name'], $item['price']);
});

该示例显示了价格介于给定的最低价和最高价之间的所有汽车。

$ php and_where.php
id: 4 name: Volvo price: 29000
id: 6 name: Citroen price: 21000
id: 7 name: Hummer price: 41400
id: 8 name: Volkswagen price: 21600

有四辆车满足条件。

DoctrineQueryBuilder插入行

使用insert()values()插入新行。

<?php

require_once "bootstrap.php";

$name = 'Oldsmobile';
$price = 28800;

$queryBuilder = $conn->createQueryBuilder();

$queryBuilder = $queryBuilder->insert('cars')
    ->values(['name' => '?', 'price' => '?'])
    ->setParameters([0 => $name, 1 => $price]);
$queryBuilder->execute();

$sql = $queryBuilder->getSQL();
echo "Executed: $sql\n";

该示例将一辆新车插入到cars表中。

$queryBuilder = $queryBuilder->insert('cars')
    ->values(['name' => '?', 'price' => '?'])
    ->setParameters([0 => $name, 1 => $price]);

可以使用setParameters()指定多个参数。

$sql = $queryBuilder->getSQL();

getSQL()获取Doctrine生成的SQL语句。

$ php insert_row.php
Executed: INSERT INTO cars (name, price) VALUES(?, ?)

输出显示生成的SQL语句。

DoctrineQueryBuilder删除

使用delete()删除数据。

<?php

require_once "bootstrap.php";

$name = 'Oldsmobile';
$price = 26600;

$queryBuilder = $conn->createQueryBuilder();

$queryBuilder = $queryBuilder->delete('cars')
    ->where('id IN (1, 2, 3)');

$n = $queryBuilder->execute();

echo "The query deleted $n rows\n";

该示例删除ID为1、2和3的行。

$n = $queryBuilder->execute();

execute()方法返回删除的行数。

$ php delete_rows.php
The query deleted 3 rows

这是输出。

DoctrineQueryBuilder更新行

使用udpate()set()更新一行。

<?php

require_once "bootstrap.php";

$name = 'Oldsmobile';
$price = 26600;

$queryBuilder = $conn->createQueryBuilder();

$queryBuilder = $queryBuilder->update('cars')
    ->set('price', $queryBuilder->createNamedParameter($price))
    ->where('id = 9');

$queryBuilder->execute();

$sql = $queryBuilder->getSQL();
echo "Executed: $sql\n";

该示例更新了ID为9的汽车的价格。

Symfony原则示例

以下示例是一个简单的Symfony网络应用程序。Symfony使用Doctrine来实现持久化。

$ composer create-project symfony/skeleton symfapp
$ cd symfapp

我们创建一个新的Symfony骨架应用程序。

$ composer require symfony/orm-pack

我们安装Doctrine。

$ composer require maker --dev
$ composer require server --dev

我们安装了makerserver组件。

doctrine:
    dbal:
        # configure these for your database server
        driver: pdo_pgsql
        charset: utf8

我们将Doctrine配置为使用PostgreSQL。默认情况下,Symfony具有MySQL的配置。

...
DATABASE_URL=pgsql://postgres:s$cret@127.0.0.1:5432/testdb

.env文件中,我们设置了DATABASE_URL

$ php bin/console doctrine:query:sql "select version()"
array(1) {
    [0]=>
    array(1) {
    ["version"]=>
    string(58) "PostgreSQL 11.1, compiled by Visual C++ build 1914, 64-bit"
    }
}

我们验证PostgreSQL设置。

$ php bin/console make:controller HomeController

通过maker,我们创建了一个新的控制器。

<?php

namespace App\Controller;

use Doctrine\DBAL\Connection;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class HomeController extends AbstractController
{
    /**
    * @Route("/home", name="home")
    */
    public function index(Connection $conn)
    {
        $queryBuilder = $conn->createQueryBuilder();
        $data = $queryBuilder->select('*')->from('cars')->execute()->fetchAll();

        return $this->json($data);
    }
}

index()方法返回数据库表中的所有行。请注意,为了简单起见,我们已将查询构建器放在控制器中。在生产应用程序中,还应该有一个服务层和一个存储库。

return $this->json($data);

数据以JSON格式发送回客户端。

$ php bin/console server:run

我们运行开发服务器。

$ curl localhost:8000/home
[{"id":4,"name":"Volvo","price":29000},{"id":5,"name":"Bentley","price":350000},
{"id":6,"name":"Citroen","price":21000},{"id":7,"name":"Hummer","price":41400},
{"id":8,"name":"Volkswagen","price":21600},{"id":9,"name":"Oldsmobile","price":26600}]

使用curl,我们向应用程序生成请求。

您可能还对以下相关教程感兴趣:PHPPDO教程、Symfony简介、PHP教程,或列出所有PHP教程。

(adsbygoogle=window.adsbygoogle||[]).push({});

在本教程中,我们使用了DoctrineQueryBuilder和PostgreSQL数据库。

未经允许不得转载:我爱分享网 » Doctrine DBAL QueryBuilder

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏