美文网首页PHP经验分享Laravel开发实践PHP实战
Laravel5.4~5.*使用DB门面实现【单一数据表的&qu

Laravel5.4~5.*使用DB门面实现【单一数据表的&qu

作者: 我爱余倩 | 来源:发表于2019-02-10 14:21 被阅读9次

一、前言

  1. 前段时间有小白问到,Laravel 下的 DB 操作 MySQL 如何实现表的自连接。
  2. 当然,我也是第一时间翻阅了 Laravel 的源码,成功的通过 DB 门面,实现了单一数据表的"自连接"查询。
  3. 所以说看源码很重要。

二、说明

  1. LaravelDB 门面提供了 toSql() 函数,以便调试时输出原生的 SQL 语句。
  2. 相信通过在下的提示,越来越多的同学可以学会使用 LaravelDB 门面实现更多的高级 SQL 语句。
  3. 本文以【社交应用】为背景。在用户关注表 'tb_user_follows' 中查询出 两个互相关注的(即好友)用户 的数据。
  4. 实际上机制的同学是很容易发现,后文使用的思想是非常简单的 SQL 查询。而本人如此赘述的原因,是在于给后面即将推出的 Laravel业务篇 系列的教程做铺垫,希望借此契机,循序渐进地让大家体会到 Laravel 的优雅。

三、实现

  1. 创建用户表 'tb_users' 和用户关注表 'tb_user_follows' 如下:
    tb_users && tb_user_follows
  1. 用到了几个简单的表字段,很容易理解。用户关注表 'tb_user_follows' 中的 'user_id''user_follow_id' 字段均是来自用户表 'tb_users' 的主键ID,这里我也是添加了外键约束,让两个表的关联更加明显。

  2. 说到这里,为了回顾一下 LaravelArtisan 指令,我们使用模型工厂(Factory) 和模型填充器(Seeder),优雅地制造一些测试数据:

php artisan make:model UserModel
php artisan make:factory UserFactory
php artisan make:seeder UserSeeder
  1. 上述指令分别生成 'UserModel.php''UserFactory.php''UserSeeder.php'三个文件,稍作修改就变成:
# Dir: @/app/UserModel.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

/**
 * @author AdamTyn
 * @description <用户>数据模型
 */
class UserModel extends Model
{
    /**
     * 绑定数据表
     * @var string
     */
    protected $table = 'tb_users';

    /**
     * 禁用自带的时间字段
     * @var bool
     */
    public $timestamps = false;

    /**
     * 使用模型时可以访问的字段
     * @var array
     */
    protected $fillable = [
        'name', // 用户名称
    ];

    /**
     * 使用模型时禁止修改的字段
     * @var array
     */
    protected $guarded = [
        'id',
    ];
}

# Dir: @/database/factories/UserFactory.php
<?php

use Faker\Generator as Faker;

$factory->define(\App\UserModel::class, function (Faker $faker) {
    return [
        'name' => $faker->name
    ];
});

# Dir: @/database/seeds/UserSeeder.php
<?php

use Illuminate\Database\Seeder;

/**
 * @author AdamTyn
 * @description <用户>数据填充器
 */
class UserSeeder extends Seeder
{
    public function run()
    {
        factory(\App\UserModel::class, 10)->create(['created_at' => time()]);
    }
}

当然,仅仅添加了用户表 'tb_users' 的数据还不够,再到数据库中,插入用户关注表 'tb_user_follows' 的几条数据:

tb_user_follows
  1. 接着添加一条路由规则:
    Route::get('friends/{user_id}', '\App\Http\Controllers\SocialController@friends');

  2. 最后,编写 'SocialController.php'文件如下:

# Dir: @/app/Http/SocialController.php
<?php

namespace App\Http\Controllers;

use DB;

/**
 * @author AdamTyn
 * @description <用户社交相关>控制器
 */
class SocialController extends Controller
{
    /**
     * @author AdamTyn
     * @description 获取好友列表
     * @get('friends/{user_id}')
     *
     * @param int|string $userId
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
     */
    public function friends($userId)
    {
        if (!is_numeric($userId) || $userId < 1) {
            return response()->json(['status_code' => 404, 'data' => null]);
        }

        # ⑴获取好友列表的ID
        $friendIds = DB::query()->sharedLock() # 启用共享锁
            ->selectRaw('t2.user_id from tb_user_follows as t1,tb_user_follows as t2') # 和平时SQL语句一样
            # 实际上是两表联查,并非真的自连接
            ->whereRaw('t1.user_id = t2.user_follow_id and t1.user_follow_id = t2.user_id and t1.user_id = ' . $userId)
            ->whereNull('t1.deleted_at')
            ->whereNull('t2.deleted_at')
            ->orderByDesc('t2.created_at')
            ->get();

        $bool = $friendIds->isNotEmpty(); # 集合类的方法

        # ⑵获取好友列表的详细信息
        $friends = $bool ? DB::table('tb_users')->whereIn('id',
            $friendIds->pluck('user_id')->toArray() # 集合类的方法
        )->whereNull('deleted_at')->get(['id', 'name']) : collect();

        return response()->json(['status_code' => 200, 'data' => $friends]);
    }
}

  1. 打开 PostMan,熟练地敲击键盘输入路由地址,不出意外可以成功返回:
HTTP/1.1 200 OK
{
    "status_code": 200,
    "data": [
        {
            "id": 2,
            "name": "Alexandrine Orn V"
        }
    ]
}

四、结语

  1. 本教程面向新手,更多教程会在日后给出。
  2. 随着系统升级,软件更新,以后的配置可能有所变化,在下会第一时间测试并且更新教程;
  3. 欢迎联系在下,讨论建议都可以,之后会发布其它的教程。
  4. 后面紧锣密鼓地将会推出 Laravel业务篇 系列的教程,敬请期待。

相关文章

网友评论

    本文标题:Laravel5.4~5.*使用DB门面实现【单一数据表的&qu

    本文链接:https://www.haomeiwen.com/subject/pjcpbftx.html