4 关注者

使用数据库

本节将介绍如何创建一个新页面,该页面显示从名为 country 的数据库表中获取的国家数据。为了实现这个目标,您将配置一个数据库连接,创建一个 Active Record 类,定义一个 操作,并创建一个 视图

通过本教程,您将学习如何

  • 配置数据库连接,
  • 定义 Active Record 类,
  • 使用 Active Record 类查询数据,
  • 以分页方式在视图中显示数据。

请注意,为了完成本节,您应该具备使用数据库的基本知识和经验。特别是,您应该知道如何创建数据库,以及如何使用数据库客户端工具执行 SQL 语句。

准备数据库

首先,创建一个名为 yii2basic 的数据库,您将在应用程序中从该数据库获取数据。您可以创建 SQLite、MySQL、PostgreSQL、MSSQL 或 Oracle 数据库,因为 Yii 对许多数据库应用程序都提供了内置支持。为简便起见,以下描述将假定使用 MySQL。

信息: 虽然 MariaDB 曾经是 MySQL 的直接替代品,但这现在不再完全正确。如果您希望使用 JSON 支持等高级功能,请检查下面列出的 MariaDB 扩展。

接下来,在数据库中创建一个名为 country 的表,并插入一些示例数据。您可以运行以下 SQL 语句来完成此操作

CREATE TABLE `country` (
  `code` CHAR(2) NOT NULL PRIMARY KEY,
  `name` CHAR(52) NOT NULL,
  `population` INT(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `country` VALUES ('AU','Australia',24016400);
INSERT INTO `country` VALUES ('BR','Brazil',205722000);
INSERT INTO `country` VALUES ('CA','Canada',35985751);
INSERT INTO `country` VALUES ('CN','China',1375210000);
INSERT INTO `country` VALUES ('DE','Germany',81459000);
INSERT INTO `country` VALUES ('FR','France',64513242);
INSERT INTO `country` VALUES ('GB','United Kingdom',65097000);
INSERT INTO `country` VALUES ('IN','India',1285400000);
INSERT INTO `country` VALUES ('RU','Russia',146519759);
INSERT INTO `country` VALUES ('US','United States',322976000);

此时,您拥有一个名为 yii2basic 的数据库,其中包含一个 country 表,该表包含三个列,包含十行数据。

配置数据库连接

在继续之前,请确保您已安装 PDO PHP 扩展和您正在使用的数据库的 PDO 驱动程序(例如,对于 MySQL 为 pdo_mysql)。这是您的应用程序使用关系型数据库时的基本要求。

安装完这些之后,打开文件 config/db.php 并更改参数以适合您的数据库。默认情况下,该文件包含以下内容

<?php

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];

config/db.php 文件是一个典型的基于文件的 配置 工具。此配置文件指定了创建和初始化 yii\db\Connection 实例所需的参数,您可以通过该实例对底层数据库执行 SQL 查询。

上述配置的 DB 连接可以通过表达式 Yii::$app->db 在应用程序代码中访问。

信息:config/db.php 文件将由主应用程序配置文件 config/web.php 包含,该配置文件指定了如何初始化 应用程序 实例。有关更多信息,请参阅 配置 部分。

如果您需要使用 Yii 未捆绑的数据库支持,请查看以下扩展

创建 Active Record

要表示和获取 country 表中的数据,请创建一个名为 CountryActive Record 派生类,并将其保存到文件 models/Country.php 中。

<?php

namespace app\models;

use yii\db\ActiveRecord;

class Country extends ActiveRecord
{
}

Country 类继承自 yii\db\ActiveRecord。您不需要在其中编写任何代码!有了上面的代码,Yii 将根据类名猜测关联的表名。

信息:如果无法从类名直接匹配到表名,您可以覆盖 yii\db\ActiveRecord::tableName() 方法来明确指定关联的表名。

使用 Country 类,您可以轻松地操作 country 表中的数据,如以下代码段所示

use app\models\Country;

// get all rows from the country table and order them by "name"
$countries = Country::find()->orderBy('name')->all();

// get the row whose primary key is "US"
$country = Country::findOne('US');

// displays "United States"
echo $country->name;

// modifies the country name to be "U.S.A." and save it to database
$country->name = 'U.S.A.';
$country->save();

信息:Active Record 是一种以面向对象的方式访问和操作数据库数据的强大方法。您可以在 Active Record 部分找到更多详细信息。或者,您也可以使用称为 Database Access Objects 的更底层的数据访问方法与数据库交互。

创建 Action

要将国家/地区数据公开给最终用户,您需要创建一个新的 Action。与在上一节中将新的 Action 放置在 site 控制器中不同,将所有与国家/地区数据相关的 Action 创建一个新的控制器更有意义。将此新控制器命名为 CountryController,并在其中创建一个 index Action,如下所示。

<?php

namespace app\controllers;

use yii\web\Controller;
use yii\data\Pagination;
use app\models\Country;

class CountryController extends Controller
{
    public function actionIndex()
    {
        $query = Country::find();

        $pagination = new Pagination([
            'defaultPageSize' => 5,
            'totalCount' => $query->count(),
        ]);

        $countries = $query->orderBy('name')
            ->offset($pagination->offset)
            ->limit($pagination->limit)
            ->all();

        return $this->render('index', [
            'countries' => $countries,
            'pagination' => $pagination,
        ]);
    }
}

将上面的代码保存在文件 controllers/CountryController.php 中。

首先,index Action 调用 Country::find()。此 find() 方法创建一个 ActiveQuery 查询对象,该对象提供从 country 表中访问数据的方法。

为了限制每个请求返回的国家/地区数量,查询对象使用 yii\data\Pagination 对象进行分页。Pagination 对象有两个目的

  • 为查询对象表示的 SQL 语句设置 offsetlimit 子句,以便它一次只返回一页数据(每页最多 5 行)。
  • 它用于视图中显示分页器,分页器包含一个页面按钮列表,将在下一小节中解释。

接下来,all() 返回基于查询结果的所有 country 记录。

在代码的最后,index Action 呈现一个名为 index 的视图,并将返回的国家/地区数据以及分页信息传递给它。

创建视图

views 目录下,首先创建一个名为 country 的子目录。此文件夹将用于保存 country 控制器呈现的所有视图。在 views/country 目录中,创建一个名为 index.php 的文件,其中包含以下内容

<?php
use yii\helpers\Html;
use yii\widgets\LinkPager;
?>
<h1>Countries</h1>
<ul>
<?php foreach ($countries as $country): ?>
    <li>
        <?= Html::encode("{$country->code} ({$country->name})") ?>:
        <?= $country->population ?>
    </li>
<?php endforeach; ?>
</ul>

<?= LinkPager::widget(['pagination' => $pagination]) ?>

视图有两部分与显示国家/地区数据相关。在第一部分中,遍历提供的国家/地区数据并将其呈现为无序 HTML 列表。在第二部分中,使用从 Action 传递的分页信息呈现 yii\widgets\LinkPager 小部件。LinkPager 小部件显示一个页面按钮列表。单击其中任何一个都会刷新相应页面中的国家/地区数据。

试用

要查看以上所有代码是如何工作的,请使用浏览器访问以下 URL

https://hostname/index.php?r=country%2Findex

Country List

首先,您将看到一个显示五个国家的页面。在国家/地区下方,您将看到一个带有四个按钮的分页器。如果您单击“2”按钮,您将看到页面显示数据库中的另外五个国家/地区:第二页记录。仔细观察,您会发现浏览器中的 URL 也更改为

https://hostname/index.php?r=country%2Findex&page=2

在幕后,Pagination 提供了对数据集进行分页的所有必要功能

  • 最初,Pagination 表示第一页,它反映了包含子句 LIMIT 5 OFFSET 0 的国家/地区 SELECT 查询。因此,将获取并显示前五个国家/地区。
  • LinkPager 小部件使用由 Pagination 创建的 URL 呈现页面按钮。URL 将包含查询参数 page,它表示不同的页码。
  • 如果您单击“2”页面按钮,将触发并处理对路由 country/index 的新请求。 Pagination 从 URL 中读取 page 查询参数并将当前页码设置为 2。因此,新的国家/地区查询将具有子句 LIMIT 5 OFFSET 5 并返回接下来的五个国家/地区以供显示。

总结

在本节中,您学习了如何使用数据库。您还学习了如何在 yii\data\Paginationyii\widgets\LinkPager 的帮助下获取和分页显示数据。

在下一节中,您将学习如何使用称为 Gii 的强大代码生成工具来帮助您快速实现一些常用的功能,例如用于操作数据库表中数据的创建-读取-更新-删除 (CRUD) 操作。事实上,您刚刚编写的代码都可以使用 Gii 工具在 Yii 中自动生成。

发现错别字或您认为此页面需要改进吗?
在 github 上编辑它 !