上一篇文章我们理了一下Yii2的MVCFormsLayouts,这篇文章就直接按照约定来说说Yii2与数据库相关的一些事情,如果你觉得不够的话,不急,更具体的用法我会在后续的教程给出,并且这里也会介绍Yii2的代码生成工具:强大的Gii

你可以直接到Github下载项目源码:https://github.com/JellyBool/helloYii,这样你就可以直接跟上我的进度了,每一次我写完一个教程,我都会将代码push到Github,所以,你想偷懒的话,这是一个不错的方法。

接着上一篇文章,我们的初衷还是没有改变:创建一个可以发表状态(status)的web小应用,你可以看成是QQ空间的说说的mini版,只不过之前我们没有将数据存在数据库里面而已。

创建一个数据库

由于我平时开发基本都是使用Mysql,而且数据库管理工具我比较喜欢Sequel Pro,所以,我就直接在Sequel Pro里面创建一个hello的数据库。当然,你也可以直接用命令行来创建数据库,大概是这样的:

CREATE DATABASE hello;

有了数据库之后,我们就可以将我们的Yii应用与数据库进行连接了,Yii2的数据库配置文件位于/config/db.php中,我们可以打开它来进行相应的配置,请注意根据自己的实际情况进行相应的修改:

<?php

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

创建Migration

这里直接使用了migration这个单词,其实我不知道该翻译成什么才比较确切;所以本文就直接使用migration这个单词了,如果你知道有特别贴切的翻译,请大声对我说。其实migration的最大目的可能就是创建数据表了,但是我们为什么还要使用migration了?这可能都是受到Rails大法的影响,因为这样的好处其实很多,migration不仅可以让开发人员动态创建和更新一个数据库表的schema,还可以应对多个服务器的时候环境不同的问题,直接就避免导入sql文件的各种坑。

至于在代码中我们该怎么命名我们的数据表,我比较喜欢的是直接跟Model一样,如果是单复数问题也无所谓,这看个人,所以这里,我会选择创建一个status表,iTerm命令行执行:

cd Desktop/helloYii/

./yii migrate/create create_status_table

过程当中会询问是否创建migration,果断yes,然后完成之后大概是这样的:

这条命令会在项目目录下创建一个migrations/目录,里面就有刚刚我们创建的migration文件,名字大概是这样的:m150804_035107_create_status_table.php,然后我们就可以打开这个文件来一睹芳容了:

<?php

use yii\db\Schema;
use yii\db\Migration; class m150804_035107_create_status_table extends Migration
{
public function up()
{ } public function down()
{
echo "m150804_035107_create_status_table cannot be reverted.\n"; return false;
}

嗯,大概就是这样,up()方法是我们后面执行./yii migrate/up命令的时候触发的,这里一般都是负责创建一个表,我们可以将表的schema写在这个方法里面。

创建status表

有了上面的migration之后,我们可以直接在up()方法写上一些我们的字段和配置:

public function up()
{
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
} $this->createTable('{{%status}}', [
'id' => Schema::TYPE_PK,
'message' => Schema::TYPE_TEXT.' NOT NULL DEFAULT ""',
'permissions' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 0',
'created_at' => Schema::TYPE_INTEGER . ' NOT NULL',
'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL',
], $tableOptions);
} public function down()
{
$this->dropTable('{{%status}}');
}

这里我们的status会有5个字段,id为主键,messagepermissions就是上一篇我们的文本输入框输入的文本内容和下拉选择框的内容;这里我们还要两个created_atupdated_at字段,呃,你可以说我被Laravel洗脑了。

down()方法与up()相对应,用来删除数据表的,我希望你不会用到。

更多详细内容参考这里:

http://www.yiiframework.com/doc-2.0/guide-db-migrations.html

有了表的schema之后,我们就可以来执行我们的migrate命令了,命令行执行:

    ./yii migrate/up

过程中还是果断yes,然后完成之后你就可以到到hello数据库去看status表了:

这里你还会看到一个migration的表,这是Yii2的migrate自动生成了,它是用来管理我们自己创建的migration(这里指数据表),你可以不用关心它。

使用Yii2的migrate创建完数据表之后,我们下一步就来上手一下Yii2的代码生成工具Gii了,因为我们会通过Gii来生成我们的Model和Controller等文件。

使用Gii

Gii作为Yii的一大特性,很多人喜欢Yii可能就是因为这个,据说底层代码写得很棒,不过我还没有仔细看过源码。

首先我们来使用Gii来为每一个数据表生成一个Model,这里也就是生成Status这个模型。

怎么进入Gii的使用面板呢?直接在浏览器地址栏输入 http://localhost:8999/gii访问就可以了。大概是长这个样子:

点击Model Generator的按钮,然后在Table Name输入框填入表名:status

点击下方Preview 按钮,就可以看到Yii即将帮你生成的文件了models/Status.php,这里需要注意的一个地方是。因为在上一篇文章中我们手动创建了一个Status模型,所以这里请确定你将Overwrite这个选择框的小勾勾打上:

然后点击Generate按钮,生成的结果是这样的:

这时候打开models/Status.php,你会看到Yii会根据我们的数据表生成的验证规则和表单属性:

<?php

namespace app\models;

use Yii;

/**
* This is the model class for table "status".
*
* @property integer $id
* @property string $message
* @property integer $permissions
* @property integer $created_at
* @property integer $updated_at
*/
class Status extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'status';
} /**
* @inheritdoc
*/
public function rules()
{
return [
[['message', 'created_at', 'updated_at'], 'required'],
[['message'], 'string'],
[['permissions', 'created_at', 'updated_at'], 'integer']
];
} /**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'message' => 'Message',
'permissions' => 'Permissions',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
];
}
}

Status模型生成好之后,该为它生成相应的视图和控制器了,这时候需要使用到的是Gii 的CRUD Generator了,即:http://localhost:8999/gii/crud

在这个页面,分别填上对应的数据:

Model Class : app\models\Status

Search Model Class : app\models\StatusSearch

Controller Class : app\controllers\StatusController

View Path : 可以直接留空,默认就是 app/views/ControllerID

然后点击Preview预览一下,这里还是需要把overwrite勾选上,因为我们上一节也创建了两个同名的视图文件(create.php 和 view.php)

最后还是点击生成,你会看到类似下面这个图片的内容:

到了这里,我们基本上可以感觉到Gii的强大了,生成代码简直都不算事。这时候如果我们访问http://localhost:8999/status ,你会看到一个默认的Status的CRUD页面,因为我们的数据库里面还没有任何数据,所以这里看到的都是空的:

如果你还记得我们在上一篇在导航栏创建的create导航,点击create,你就会看到类似下面这个页面一样的内容:

到这里,有没有觉得Gii实在太厉害了!要是上一篇我们直接用Gii来生成这些代码,那开发效率实在不是一般高。

与上一篇的结合

虽然Gii足够强大为我们生成了很多代码,但是现在有一小部分代码并不符合我们的要求,我们不用这么复杂。所以下面先来把代码先过过,以便用于满足我们自己的要求。

首先是对创建Status的表单进行改造,我们并不希望用户需要输入created 和updated这两个字段,所以注释掉/views/Status/_form.php中的下面的代码:

<?= $form->field($model, 'created_at')->textInput() ?>

<?= $form->field($model, 'updated_at')->textInput() ?>

然后permissions字段输入我们希望这是一个下拉选择框,还是在同一个文件中修改:

<?=
$form->field($model, 'permissions')->dropDownList($model->getPermissions(),
['prompt'=>'- Choose Your Permissions -']) ?>

我们把原来permissionstextInput换成了上面的dropDownList,这里的dropDownList使用到getPermissions()这个方法,但是由于刚刚在生成Status这个模型的时候我们覆盖了原谅的Status,所以我们还是需要加上getPermissions()这个方法:

const PERMISSIONS_PRIVATE = 10;
const PERMISSIONS_PUBLIC = 20; // other codes ... public function getPermissions() {
return array (self::PERMISSIONS_PRIVATE=>'Private',self::PERMISSIONS_PUBLIC=>'Public');
} public function getPermissionsLabel($permissions) {
if ($permissions==self::PERMISSIONS_PUBLIC) {
return 'Public';
} else {
return 'Private';
}
}

像上一篇提到的一样,我们将这些代码又写到了Status.php这里。然后刷新一下:http://localhost:8999/status/create

到这里,我们的表单改造旧完成了,跟我们之前的长得差不多了。但是这还没有完,因为我们还需要对我们的controllers/StatusController.php做一些些小改动,主要是在actionCreate的改动:

public function actionCreate()
{
$model = new Status(); if ($model->load(Yii::$app->request->post())) {
$model->created_at = time();
$model->updated_at = time();
if ($model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
}
return $this->render('create', [
'model' => $model,
]);
}

在这里,我们添加下面这两行来保障我们在插入数据的时候,created_atupdated_at不为空。

$model->created_at = time();
$model->updated_at = time();

这里也是根据$model->load(Yii::$app->request->post())判断是否有post数据过来,然后如果数据成功保存到数据库,我们就使用return $this->redirect(['view', 'id' => $model->id])重定向到view方法(controllers/StatusController.php的actionView方法)。我们填上一些数据,然后创建一个status试试,不出意外你会看到这个可爱的页面:

终于到了这里了,我们现在再来修改一下我们的导航,在Status这个下来菜单下,我们增加一个菜单view,修改views/layouts/main.php文件的Nav::widget部分:

[
'label' => 'Status',
'items' => [
['label' => 'View', 'url' => ['/status/index']],
['label' => 'Create', 'url' => ['/status/create']],
],
],

就直接在Status的items里面加一行:['label' => 'View', 'url' => ['/status/index']],然后我们的导航栏就是这样的了:

点击下拉菜单的View,然后我们就会来到:http://localhost:8999/status/index,这里我们可以看到下面的页面了:

这个视图文件位于views/status/index.php,如果你想修改一下,你可以直接修改这个文件。

啊,感觉这一篇文章的路走得好长,不过其实真正编码的时间并不过,真正可能也就几分钟而已,我们实现了对数据库的一些基本操作和领略Gii的强大。这一篇就先写到这里了,下一篇打算会写一点关于用户注册和登录的基本功能。

源码会放在 Github:https://github.com/JellyBool/helloYii

最新文章

  1. 【.net深呼吸】WPF异步加载大批量图像
  2. 关于ADO.NET连接ORACLE,使用ODAC连接中的一些问题
  3. js String对象
  4. C语言字符串匹配函数
  5. 正则表达式 ——python 基础
  6. 【ZeroMQ】消息模式
  7. Jquery UI accordion手风琴菜单
  8. vim中的批量替换
  9. 2015 多校联赛 ——HDU5294(最短路,最小切割)
  10. C语言程序设计第二次作业1
  11. 【20190228】JavaScript-获取子元素
  12. VBA解析Json(转)
  13. C# show和showdialog区别
  14. CVE-2018-14424 use-after-free of disposed transient displays 分析报告
  15. (unittest之装饰器(@classmethod)) 让多个测试用例在一个浏览器里面跑 的方法
  16. 算法笔记_187:历届试题 网络寻路(Java)
  17. 关键业务系统的JVM参数推荐(2018仲夏版) (强烈推荐 唯品会)
  18. idea中java文件打包出去步骤
  19. Django模板语言与视图(view)
  20. 认识HttpContext.User

热门文章

  1. go开发
  2. IOS工程自动打包并发布脚本实现
  3. 使用bottle进行web开发(8):get的参数传递,form里的额数据传递等
  4. C#关于log4net(Log For Net)
  5. selenium Select用法笔记
  6. [UML] 如何找参与者、找用例
  7. 模板—数学—Exgcd
  8. [AGC025E]Walking on a Tree
  9. 1.9(java学习笔记)object类及toString()与equals()方法
  10. linux安装dubbo