Yii2学习笔记系列5——Working With Database(使用数据库)

五 08 四月 2016

Yii2笔记系列5——Working With Database(使用数据库)

上一篇中我们学习了如何使用Form表单,掌握了Form表单的提交以及在Yii中通过视图展示提交内容的技能,这一篇我们来学习一下如何创建一个从数据表country中读取国家数据并显示出来的页面,为此,我们需要配置一个数据库连接,创建一个活动记录类,并且创建一个操作和一个视图。

通过这篇,我们将会学习到的:

  • 配置一个数据库连接
  • 定义一个活动记录类
  • 使用活动记录类从数据库中查询数据
  • 以分页的方式在视图中显示数据

准备数据库

首先创建一个名为yii2basic的数据库,应用将从这个数据库中读取数据,Yii中内置了多种数据库支持,这里我们使用最常见的MySQL数据库。以下是MySQL的建表语句:

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','澳大利亚',18886000);
INSERT INTO `country` VALUES ('BR','巴西',170115000);
INSERT INTO `country` VALUES ('CA','加拿大',1147000);
INSERT INTO `country` VALUES ('CN','中国',1277558000);
INSERT INTO `country` VALUES ('DE','德国',82164700);
INSERT INTO `country` VALUES ('FR','法国',59225700);
INSERT INTO `country` VALUES ('GB','英国',59623400);
INSERT INTO `country` VALUES ('IN','印度',1013662000);
INSERT INTO `country` VALUES ('RU','俄罗斯',146934000);
INSERT INTO `country` VALUES ('US','美国',278357000);

配置数据库连接

在开始之前,需要首先确保你已经安装了PHP PDO 扩展,以及你所使用的数据库的PDO驱动(例如MySQL的话就是pdo_mysql)。

然后打开config/db.php,修改其中的数据库配置,代码如下:

<?php

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

config/db.php是一个典型的基于文件的配置工具,这个文件配置了数据库连接yii\db\Connection的创建和初始化参数,应用的SQL查询便基于这个数据库进行操作。

上面配置的数据库连接可以在应用里通过Yii::$app->db访问,另外就是Yii2中我们也可以配置多个数据库,当然,在后面我们接触到模块之后,我们甚至可以为每个模块配置单独的数据库连接,这个是后话,按下不表。

创建活动记录

创建一个继承自活动记录类的类Country,保存为models/Country.php文件,用来表示读取的country表的数据。

<?php
/**
 * Created by PhpStorm.
 * User: 赵振棠
 * Date: 16/4/8
 * Time: 下午10:21
 */

namespace app\models;

use yii\db\ActiveRecord;

class Country extends ActiveRecord
{

}

这个Country类继承自yii\db\ActiveRecord,我们可以不需要在其中写任何代码,Yii会自动根据类名匹配相对应的数据表名,但如果你的类名和数据表名不能直接对应,可以通过重写yii\db\ActiveRecord::tableName()方法显式指定相关表名。

创建操作

与之前的直接在site控制器中添加操作不同,我们这里单独为所有和Country有关的数据新建一个控制器更加合理,新控制器名为CountryController,保存在controllers/CountryController.php文件中,并在其中创建一个index操作,代码如下:

<?php
/**
 * Created by PhpStorm.
 * User: 赵振棠
 * Date: 16/4/8
 * Time: 下午10:29
 */

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,
        ]);
    }
}

index操作调用了活动记录Country::find()方法,生成MySQL查询语句并从country表中取回所有数据,为了限定每个请求所返回的国家数量,我们使用yii\data\Pagination对象进行分页。Pagination对象主要有两点用处: - 为SQL查询语句设置offsetlimit从句,确保每个请求只返回一页数据,例如在当前这个例子中是5条记录。 - 在视图中显示一个由页面列表组成的分页器,这点会在后面解释。

在代码的末尾,index操作渲染一个名为index的视图,并传递国家数据和分页信息进去。

创建视图

views目录下先创建一个country子目录,这个目录将被用来存储所有由country控制器渲染的视图,在views/country目录下创建一个名为index.php的视图文件,内容如下:

<?php
/**
 * Created by PhpStorm.
 * User: 赵振棠
 * Date: 16/4/8
 * Time: 下午10:46
 */
use yii\helpers\Html;
use yii\widgets\LinkPager;

?>
    <h2>国家列表</h2>
    <ul>
        <?php foreach ($countries as $country): ?>
            <li>
                <?= Html::encode("{$country->name} ({$country->code})") ?>
                <?= $country->population ?>
            </li>
        <?php endforeach; ?>
    </ul>

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

这个视图主要包含两部分用以显示国家数据,第一部分遍历国家数据并以无序HTML列表渲染出来,第二部分使用yii\widgets\LinkPager去渲染从操作中传来的分页信息。小部件LinkPager显示一个分页按钮的列表,点击按钮会跳转到对应的分页。

接下来我们测试一下,在浏览器中访问下面的URL,看看是否可以工作:

http://hostname/web/index.php?r=country

img

首先你会看到显示有五个国家的列表页面,同时,下面还能看到一个包含四个按钮的分页器,如果点击按钮2,将会跳转到显示另外五个国家的页面,也就是第二页记录,这时如果你查看一下浏览器的URL会发现变成了

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

在这个场景中,yii\data\Pagination提供了为数据结果集分页的功能:

  • 首先yii\data\Pagination把SELECT的子查询LIMIT 5 OFFSET 0数据表示成第一页,因此会取出开头的五条数据并显示。
  • 然后小部件yii\widgets\LinkPager使用yii\data\Pagination::createUrl()方法生成的URL去渲染翻页按钮,URL中包含必要参数page才能查询不同的页面编号。
  • 当你点击按钮2时,会发起一个路由为country\index的新请求,yii\data\Pagination接收到URL中的page参数,把当前的页码设置为2,之后,请求数据库并且以LIMIT 5 OFFSET 5查询并且显示后五条数据。

小结

本章节中我们学习了如何使用数据库,如何取出数据并使用yii\data\Paginationyii\widgets\LinkPager显示数据,下一张,我们将会学习如何使用Yii中强大的代码生成器Gii,它会帮助我们实现一些常用的功能需求,例如常见的CRUD(即增查改删)等。

Category: PHP Develop

Comments