查看 Eloquent 模型關(guān)聯(lián)時執(zhí)行的 SQL 語句

本文目的是查看 Eloquent 在執(zhí)行模型關(guān)聯(lián)時運(yùn)行的 SQL 語句

環(huán)境

  • PHP 7
  • Laravel 5.1

簡介

數(shù)據(jù)表之間經(jīng)常會互相進(jìn)行關(guān)聯(lián)。例如,一篇博客文章可能會有多條評論,或是一張訂單可能對應(yīng)一個下單客戶。Eloquent 讓管理和處理這些關(guān)聯(lián)變得很容易,同時也支持多種類型的關(guān)聯(lián):

  • 一對一
  • 一對多
  • 多對多
  • 遠(yuǎn)層一對多
  • 多態(tài)關(guān)聯(lián)
  • 多態(tài)多對多關(guān)聯(lián)

接下來,我會根據(jù)公司項(xiàng)目的數(shù)據(jù)庫結(jié)構(gòu),進(jìn)行舉例說明

準(zhǔn)備

新增控制器

php artisan make:controller EloquentController

新增路由

Route::get('/', function () {
    return view('welcome');
});

// 一對一
Route::get('eloquent/one-to-one', [
    'as'   => 'eloquent.one.to.one',
    'uses' => 'EloquentController@oneToOne',
]);

// 一對多
Route::get('eloquent/one-to-many', [
    'as'   => 'eloquent.one.to.many',
    'uses' => 'EloquentController@oneToMany',
]);

// 多對多
Route::get('eloquent/many-to-many', [
    'as'   => 'eloquent.many.to.many',
    'uses' => 'EloquentController@manyToMany',
]);

// 遠(yuǎn)程一對多
Route::get('eloquent/has-many-through', [
    'as'   => 'eloquent.has.many.through',
    'uses' => 'EloquentController@hasManyThrough',
]);

// 多態(tài)關(guān)聯(lián)
Route::get('eloquent/polymorphic-relations', [
    'as'   => 'eloquent.polymorphic.relations',
    'uses' => 'EloquentController@polymorphicRelations',
]);

// 多對多多態(tài)管理
Route::get('eloquent/many-to-many-polymorphic-relations', [
    'as'   => 'eloquent.many.to.many.polymorphic.relations',
    'uses' => 'EloquentController@manyToManyPolymorphicRelations',
]);

一對一

場景是如每一名加盟商都對應(yīng)著一份加盟商配置

新增模型

php artisan make:model Models/League
php artisan make:model Models/LeagueConfig

League 模型添加代碼如下

// League.php 一名加盟商有一份配置
public function config()
{
    return $this->hasOne('App\Models\LeagueConfig');
}

LeagueConfig 模型添加代碼如下

// LeagueConfig.php 一份配置對應(yīng)一名加盟商
public function league()
{
    return $this->hasOne('App\Models\League');
}

控制器新增代碼如下

public function oneToOne(Request $request)
{
    DB::enableQueryLog();
    $data = League::find(8)->config;
    foreach (DB::getQueryLog() as $sql) {
        dump($sql['query']);
    }
    dump($data);
}

查看 SQL

SELECT
    *
FROM
    `z_league`
WHERE
    `z_league`.`id` = 8
LIMIT 1;


SELECT
    *
FROM
    `z_leagueconfig`
WHERE
    `z_leagueconfig`.`league_id` = 8
AND `z_leagueconfig`.`league_id` IS NOT NULL
LIMIT 1;

一對多

場景是倉庫一種 SKU 的水果能被多名加盟商進(jìn)貨

新增模型

php artisan make:model Models/Product
php artisan make:model Models/ProductLeague

Product 模型中添加代碼

 public function league()
{
    return $this->hasMany('App\Models\ProductLeague', 'pid');
}

控制器新增代碼如下:

 public function oneToMany(Request $request)
{
    DB::enableQueryLog();
    $data = Product::find(3062)->league;
    foreach (DB::getQueryLog() as $sql) {
        dump($sql['query']);
    }

    dump($data);
}

查看 SQL

SELECT
    *
FROM
    `z_product`
WHERE
    `z_product`.`id` = 3062
LIMIT 1;

SELECT
    *
FROM
    `z_productleague`
WHERE
    `z_productleague`.`pid` = 3062
AND `z_productleague`.`pid` IS NOT NULL;

多對多

場景是一名用戶使用多張不同種類的優(yōu)惠券,一種優(yōu)惠券被不同的用戶使用

新增模型

php artisan make:model Models/User
php artisan make:model Models/Voucher
php artisan make:model Models/VoucherRecord

User 模型添加代碼如下

public function voucher()
{
    return $this->belongsToMany('App\Models\Voucher', 'z_voucher_record', 'uid', 'vid');
}

Voucher 模型添加代碼如下

public function user()
{
    return $this->belongsToMany('App\Models\User', 'z_voucher_record', 'vid', 'uid');
}

控制器新增代碼如下

public function manyToMany(Request $request)
{
    DB::enableQueryLog();
    $vouchers = User::find(412115)->voucher;
    foreach (DB::getQueryLog() as $sql) {
        dump($sql['query']);
    }
    dump($vouchers);

    DB::enableQueryLog();
    $user = Voucher::find(395)->user;
    foreach (DB::getQueryLog() as $sql) {
        dump($sql['query']);
    }
    dump($user);
}

查看 SQL

# 查詢 ID 為 42115 的用戶使用過的優(yōu)惠券
SELECT
    *
FROM
    `z_user`
WHERE
    `z_user`.`id` = 412115;

LIMIT 1 SELECT
    `z_voucher`.*, `z_voucher_record`.`uid` AS `pivot_uid` ,
    `z_voucher_record`.`vid` AS `pivot_vid`
FROM
    `z_voucher`
INNER JOIN `z_voucher_record` ON `z_voucher`.`id` = `z_voucher_record`.`vid`
WHERE
    `z_voucher_record`.`uid` = 412115;

# 查詢 ID 為 395 的優(yōu)惠券被哪些用戶使用過

SELECT
    *
FROM
    `z_voucher`
WHERE
    `z_voucher`.`id` = 395;

LIMIT 1 SELECT
    `z_user`.*, `z_voucher_record`.`vid` AS `pivot_vid` ,
    `z_voucher_record`.`uid` AS `pivot_uid`
FROM
    `z_user`
INNER JOIN `z_voucher_record` ON `z_user`.`id` = `z_voucher_record`.`uid`
WHERE
    `z_voucher_record`.`vid` = 395;

遠(yuǎn)程一對多

新增模型

php artisan make:model Models/Order

Order 模型新增代碼如下

 public function order()
{
    return $this->hasManyThrough('App\Models\Order', 'App\Models\User', 'league_id', 'uid');
}

控制器新增代碼如下

public function hasManyThrough(Request $request)
{
    DB::enableQueryLog();
    $data = League::find(20)->order;
    foreach (DB::getQueryLog() as $sql) {
        dump($sql['query']);
    }

    dump($data);
}

查看 SQL

# 查詢 ID 為 20 的加盟商旗下用戶的商品訂單
SELECT
    *
FROM
    `z_league`
WHERE
    `z_league`.`id` = 20
LIMIT 1;

SELECT
    `z_order`.*, `z_user`.`league_id`
FROM
    `z_order`
INNER JOIN `z_user` ON `z_user`.`id` = `z_order`.`uid`
WHERE
    `z_user`.`league_id` = 20;

多態(tài)關(guān)聯(lián)

新增模型如下

php artisan make:model Models/Staff
php artisan make:model Models/photos
php artisan make:model Models/Products

控制器新增代碼如下

public function polymorphicRelations(Request $request)
{
    DB::enableQueryLog();
    $staff = Staff::find(8)->photos;
    foreach (DB::getQueryLog() as $sql) {
        dump($sql['query']);
    }

    dump($staff);

    DB::enableQueryLog();
    $products = Products::find(1)->photos;
    foreach (DB::getQueryLog() as $sql) {
        dump($sql['query']);
    }

    dump($products);
}

查看 SQL

# 查看 ID 為 8 的職員的所有照片
SELECT
    *
FROM
    `eloquent_staff`
WHERE
    `eloquent_staff`.`id` = 8
LIMIT 1;

SELECT
    *
FROM
    `eloquent_photos`
WHERE
    `eloquent_photos`.`imageable_id` = 8
AND `eloquent_photos`.`imageable_id` IS NOT NULL
AND `eloquent_photos`.`imageable_type` = "App\Models\Staff";

# 查看 ID 為 1 的產(chǎn)品的所有圖片
SELECT
    *
FROM
    `eloquent_products`
WHERE
    `eloquent_products`.`id` = 1
LIMIT 1;

SELECT
    *
FROM
    `eloquent_photos`
WHERE
    `eloquent_photos`.`imageable_id` = 1
AND `eloquent_photos`.`imageable_id` IS NOT NULL
AND `eloquent_photos`.`imageable_type` = "App\Models\Products";

多態(tài)多對多關(guān)聯(lián)

新增模型如下

php artisan make:model Models/Tag
php artisan make:model Models/Post
php artisan make:model Models/Video

控制器新增代碼如下

public function manyToManyPolymorphicRelations(Request $request)
{
    DB::enableQueryLog();
    $post_tags = Post::find(8)->tags;
    foreach (DB::getQueryLog() as $sql) {
        dump($sql['query']);
    }

    dump($post_tags);

    DB::enableQueryLog();
    $video_tags = Video::find(8)->tags;
    foreach (DB::getQueryLog() as $sql) {
        dump($sql['query']);
    }

    dump($video_tags);

    DB::enableQueryLog();
    $posts = Tag::find(4)->posts;
    foreach (DB::getQueryLog() as $sql) {
        dump($sql['query']);
    }

    dump($posts);

    DB::enableQueryLog();
    $videos = Tag::find(4)->videos;
    foreach (DB::getQueryLog() as $sql) {
        dump($sql['query']);
    }

    dump($videos);
}

查看 SQL

# 查詢 ID 為 8 的文章所使用的標(biāo)簽
SELECT
    *
FROM
    `eloquent_posts`
WHERE
    `eloquent_posts`.`id` = 8
LIMIT 1;

SELECT
    `eloquent_tags`.*, `eloquent_taggables`.`taggable_id` AS `pivot_taggable_id` ,
    `eloquent_taggables`.`tag_id` AS `pivot_tag_id`
FROM
    `eloquent_tags`
INNER JOIN `eloquent_taggables` ON `eloquent_tags`.`id` = `eloquent_taggables`.`tag_id`
WHERE
    `eloquent_taggables`.`taggable_id` = 8
AND `eloquent_taggables`.`taggable_type` = "App\Models\Post";

# 查詢 ID 為 8 的視頻所使用的標(biāo)簽
SELECT
    *
FROM
    `eloquent_videos`
WHERE
    `eloquent_videos`.`id` = 8
LIMIT 1;

SELECT
    `eloquent_tags`.*, `eloquent_taggables`.`taggable_id` AS `pivot_taggable_id` ,
    `eloquent_taggables`.`tag_id` AS `pivot_tag_id`
FROM
    `eloquent_tags`
INNER JOIN `eloquent_taggables` ON `eloquent_tags`.`id` = `eloquent_taggables`.`tag_id`
WHERE
    `eloquent_taggables`.`taggable_id` = 8
AND `eloquent_taggables`.`taggable_type` = "App\Models\Video";

# 查詢 ID 為 4 的標(biāo)簽下的文章
SELECT
    *
FROM
    `eloquent_tags`
WHERE
    `eloquent_tags`.`id` = 4
LIMIT 1;

SELECT
    `eloquent_posts`.*, `eloquent_taggables`.`tag_id` AS `pivot_tag_id` ,
    `eloquent_taggables`.`taggable_id` AS `pivot_taggable_id`
FROM
    `eloquent_posts`
INNER JOIN `eloquent_taggables` ON `eloquent_posts`.`id` = `eloquent_taggables`.`taggable_id`
WHERE
    `eloquent_taggables`.`tag_id` = 4
AND `eloquent_taggables`.`taggable_type` = "App\Modes\Post";

# 查詢 ID 為 4 的標(biāo)簽下的視屏

SELECT
    *
FROM
    `eloquent_tags`
WHERE
    `eloquent_tags`.`id` = 4
LIMIT 1;

SELECT
    `eloquent_videos`.*, `eloquent_taggables`.`tag_id` AS `pivot_tag_id` ,
    `eloquent_taggables`.`taggable_id` AS `pivot_taggable_id`
FROM
    `eloquent_videos`
INNER JOIN `eloquent_taggables` ON `eloquent_videos`.`id` = `eloquent_taggables`.`taggable_id`
WHERE
    `eloquent_taggables`.`tag_id` = 4
AND `eloquent_taggables`.`taggable_type` = "App\Models\Video";
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,151評論 25 708
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,760評論 18 399
  • yj yj61949
    Emily的麻麻閱讀 308評論 0 0
  • 讓人絕望的不是現(xiàn)實(shí),而是期待與現(xiàn)實(shí)的落差。隨著互聯(lián)網(wǎng)的發(fā)展,信息傳播越來越快,人們互相共享生活的程度越來越高,但是...
    花花騷年閱讀 218評論 0 1