Laravel教程 四:數據庫和Eloquent


Laravel教程 四:數據庫和Eloquent

此文章為原創文章,未經同意,禁止轉載。

上一篇寫了一些Laravel Blade的基本用法和給視圖傳遞變量的幾種方式,

這一節我們來說說跟數據庫打交道的數據庫配置和Laravel強大的Eloquent。

Laravel的數據庫配置

本部分內容為下節做准備

Laravel的配置文件都是在項目目錄的config/文件夾之下,這里也就是在blog/config文件夾之下,你可以打開這個文件夾看看,你面有很多配置文件:如mail.php(配置郵件發送服務的)database.php(配置數據庫的),我們這里就是來看看這個database.php配置文件:


 'connections' => [ 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', 'localhost'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'strict' => false, ] //... ] 

打開文件,你可以看到里面只是返回簡單地php數組而已,我們目前只是關心connections這個數組。上面的代碼並沒給出所有的數據庫配置,你可以自己看,由於博主使用的是mysql,所以這里會給出mysql的配置,其他數據庫你可以參照着來,后續的教材博主也會依舊使用mysql。

那這里說到的配置,基本上就是對下面四個變量的配置:

'host' => env('DB_HOST', 'localhost'), //如果.env文件沒有DB_HOST配置,則取localhost,后面的一樣 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 

這里的env()方法是讀取到.env (位於blog/.env) 這個文件里面的配置項

替代文字

打開這個文件,你可以看到一些常用的配置,包括debug模式和開發環境,你也可以看到我們下面這幾個需要操作的選項:

DB_HOST=localhost DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret 

由於這里我使用的是Homestead的開發環境,所以才有了上面的配置(Homestead的默認用戶名和密碼為homestead和secret),如果你是直接使用php artisan serve這種方式開啟服務來開發的話,相應地修改你的配置。

Laravel為什么要采取這樣的配置呢?很大的一個原因可能就是考慮到文件的安全性和便捷性,這樣我們在需要將代碼推送到coding或者Github的時候,我們可以直接ignore這個.env文件,不必擔心我們的核心信息唄泄露。在部署應用的時候,我們可以直接在服務器創建一個.env文件,寫上對應的配置項就OK了。

就這樣,只要我們正確配置信息,我們就連接上數據庫了,當然,你得首先創建一個homestead數據庫。

使用Migration

連接好數據庫之后,我們就需要創建相對應的數據表了,在沒有使用Laravel之前,你可能都是直接手動創建數據表的,比如我們這個blog項目,你會到數據庫中手動創建一個articles數據表,但是在Laravel的項目中,我極力推薦你使用Migration,這樣有什么好處呢?其實你可以將Migration看做一個數據庫的版本管理工具,就如git對於我們的項目文件的版本管理,你可以rollback,你可以reset等,它給予你一種代碼實現和命令行結合的方式來管理你的數據庫,如果你在blog/目錄下,命令行執行 php artisan ,你可以看到很多命令行,下面這幾個就是我們這里談到的rollbackreset等:

替代文字

紅色框框這幾個基本就是比較常用的,如果這里我還沒有說服使用migration,那么我們來將這個過程走一遍:

首先,我們創建一個migration文件,也就是定義一張表的schema,命令行執行:

php artisan make:migration create_articles_table --create='articles' 

替代文字

順利執行之后,我們會得到一個migration文件,這個文件位於database/migrations/下面,打開這個文件夾,你可以看到Laravel本來就有兩個migration文件,users表和password-reset表,我們在這個項目中目前還不用這兩個文件。所以可以直接刪掉,然后打開我們剛剛生成的migration文件:create_articles_table這個文件

 public function up() { Schema::create('articles', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('articles'); } 

這里有兩個方法:up()down()up()方法是執行php artisan migrate的時候調用的,這個方法會創建一個articles數據表,而down()方法則是在php artisan migrate:rollback的使用執行的,這里會直接刪除articles這個數據表。

但是,這里先不要急着執行php artisan migrate,我們還需要為articles的增加幾個字段:

public function up() { Schema::create('articles', function (Blueprint $table) { $table->increments('id');// 主鍵 自增 $table->string('title'); $table->text('intro'); $table->text('content'); $table->timestamp('published_at'); $table->timestamps(); // 自動創建的兩個字段:created_at 和 updated_at }); } 

這里我們的intro字段是文章的簡介,published_at字段是文章的發表日期,這樣做對我們寫博客有很大的好處,你可以將博客的發表日期控制起來,因為有一些我寫好的但是還沒有到發表日期的,還不想讓用戶看到的文章我就可以用published_at來控制了。這樣之后,我們來執行一下php artisan migrate

替代文字

然后,articles這個表就創建成功了。

替代文字

這個時候你可能還沒有體會到migration的好處,想象下面兩個場景:


1. 在進行團隊開發的時候,團隊成員將我們的代碼pull下來之后,怎么可以拿到一樣的數據庫表設計呢?難道要我們將表 export 出來,給每一個成員import一次?這顯然不夠明智,如果使用的migration,就一行命令,直接`php artisan migrate`,就可以拿到一樣的數據庫表了。 2. 如果這個時候我們發現articles這個表的有一個字段寫錯了,比如我們的intro字段寫錯,它應該命名為introduction的,這個時候,我們怎么辦?直接手動改數據庫的表?那么回到第一個場景,你的團隊成員也需要手動改?這顯然也不是我們喜歡的方式,這個時候,migration的優勢就來了 

比如我們這里演示一下怎么解決第二個場景:

我們只需要命令行執行:

php artisan migrate:rollback 

替代文字

然后修改up()方法的intro字段:

$table->text('introduction'); 

然后再執行php artisan migrate

替代文字

大工告成,更多特性請看文檔:

http://laravel.com/docs/5.1/migrations

使用Eloquent

上面我們創建好了articles數據表之后,我們就可以為這個表寫一個Model類了,你可以手動創建,也可以使用artisan命令行來創建一個model,比如你在命令行敲php artisan,你會看到make下面會有很多命令,而make:model就是我們需要使用的命令:

替代文字

就像解釋的一樣:Create a new Eloquent model class

很多時候,在Laravel中,我們在創建一個model的時候都會有一些約定俗成的命名方法:

如果說我們有一個articles數據表,我們的model相對應就命名為Article;

如果說我們有一個users的數據表,我們的model對應就命名為User;

就是基本上遵守數據表復數而model單數大寫就可以了。

所以根據這個規律我們來創建我們的Article Model,使用的是make:model命令:

php artisan make:model Article 

替代文字

這樣一來,我們的Article Model就創建成功了,這個文件位於blog/app/Article.php,打開之,可以看到我們Laravel為我們生成的內容:

<?php namespace App; use Illuminate\Database\Eloquent\Model; class Article extends Model { // } 

注意到Article這個類是繼承與我們的Eloquent\Model 類,由於這個Eloquent\Model類實現了很多非常棒的方法供我們使用,我們可以來愉快地玩耍了。

首先開始玩耍的是,使用 php artisan tinker這個工具來play around,tinker提供了一個Eloquent跟數據庫表交互的命令行界面,你可以在上面寫一些簡單地php操作,比如:

替代文字

所以,我們來實例化一個Article吧:

$article = new App\Article 

替代文字

這樣就相當於我們實例化了一個Article類了,我們可以在后面的操作中進行字段具體化。

在上面我們創建表的時候,我們有以下幾個字段:

$table->increments('id'); $table->string('title'); $table->text('intro'); $table->text('content'); $table->timestamp('published_at'); $table->timestamps(); 

於是我們可以用tinker來設置以下上面的$article的各個字段,就如設置屬性一樣簡單。

比如設置$articletitle可以這樣:

$article->title = 'Router Views Controllers'; 

替代文字

同理,我們也可以將introcontent字段設置:

$article->intro = 'Article 1 Intro'; $article->content = 'Article 1 Content'; 

不過這里需要注意的是published_at這個字段,這里我推薦使用一個很棒的時間處理庫Carbon,因為像created_at和 updated_at這兩個字段也是使用的Carbon類,這樣在后面的處理中,我們會有很多好處,這里我們先直接使用Carbon:

$article->published_at = Carbon\Carbon::now(); 

替代文字

而對於$table->timestamps()這個,Laravel會在我們插入數據的時候自動完成的,所以這里我們每個字段都賦值完畢之后,我們可以使用Eloquentsave()方法來向數據庫的articles表插入一條數據了:

$article->save(); 

替代文字

返回一個true的時候,表示我們成功插入數據了,我們來看看數據庫:

替代文字

以上,就是一個簡單而完整的使用tinker給Eloquent賦值的玩耍過程。

下面我們再來玩耍一會:

all()方法

all()方法會返回Article的所有記錄:

$articles = App\Article::all(); 

替代文字

find(),接受一個參數$id,比如查找id為1的一條記錄:

$article = App\Article::find(1); 

你也可以傳入一個$id的數組,查找多條記錄,不過這里我們只有一條數據,所以就這樣了。不過我們也可以這樣玩玩:

toArray()方法:

將一個Eloquent的對象轉為數組:

$article = App\Article::find(1)->toArray(); 

替代文字

toJson()方法

將一個Eloquent的對象轉為json字串:

$article = App\Article::find(1)->toJson(); 

替代文字

如果就簡簡單單這樣的話,Eloquent也不能算很強大,我們在寫代碼過程中的where語句呢,這個也沒有么?

不用擔心,這個馬上就有:

where()方法

$article = App\Article::where('title','=','Router Views Controllers')->get(); 

替代文字

在使用where()的時候,往往需要用get()來獲取記錄集,這個返回的是一個Eloquent\Collection結果集,但是如果我就是想要滿足條件的第一天記錄呢,不需要結果集呢?

使用first()方法,在上面的基礎上,get()換成first()

$article = App\Article::where('title','=','Router Views Controllers')->first(); 

替代文字

到這里,一些簡單地查找工作就可以告一段落了,而對於update呢,我們可以這樣:

$article = App\Article::find(1); $article->intro = 'Article 1 Intro Update!'; $article->save(); 

替代文字

我們來看看有沒有更新:

$article = App\Article::find(1); 

替代文字

也可以使用update()方法:

$article->update(['content'=>'Article 1 Content Update']); 

正常情況下我們會得到一個MassAssignmentException with message

替代文字

文檔看這里: http://laravel.com/docs/5.1/eloquent#mass-assignment

這個是因為Eloquent默認是不允許我們直接更新我們的數據的,這是出於可能出現數據覆蓋的情況,但是如果我們確實是先要實現這樣的功能,我們可以在Article這個model文件里面加一個$fillable數組:

class Article extends Model { protected $fillable = ['content']; } 

然后再執行一次看看:

替代文字

這里需要Ctrl + C 退出tinker在重新進來一次。

查找,更新之后,借着我們在聊到MassAssignment這個概念的時候,我們可以來聊聊create()這個方法了,這個方法可以在不用聲明new Article()的情況下創建一條數據,比如:

 App\Article::create(['title'=>'Article 2','intro'=>'intro 2','content'=>'Article 2 content','published_at'=>Carbon\Carbon::now()]); 

然后我們會看到一個奇怪的現象,我們並沒有得到我們想要的結果:

替代文字

我們只有content這個字段正確有了值,titleintropublished_at都沒有值,這是為什么了?其實也是因為MassAssignment的緣故,我們可以參照content的時候,在Article里面的$fillable設置我們的可以填充的字段:

class Article extends Model { protected $fillable = [ 'title', 'intro', 'content', 'published_at' ]; } 

然后再執行一次:

替代文字

成功創建了一條數據,然后我們發現第二條其實並不是我們想要的,我們來刪除它:

使用delete()方法:

$article = App\Article::find(2); $article->delete(); 

替代文字

我們用all()來檢查一下:

替代文字

這里也可以使用destroy(),這個方法可以接受一個$id或者一個數組$ids:

App\Article::destroy(3); 

替代文字

最后還是放一下官方文檔:http://laravel.com/docs/5.1/eloquent

下一節

到這里基本的Eloquent也就介紹到這里了,鑒於這一節說了Model,前面也都接觸過Views和Controllers,下一節打算說說Model Views Controllers的基本流程。

Happy Hacking


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM