mysql - 在 Laravel 5.2 中使用多个 MySQL 数据库连接查询关系是否存在

标签 mysql laravel eloquent eager-loading relationships

我正在处理以下情况:我有两个模型,一个是带有 idname 字段的 Employee 和一个 Telephone idemployee_idflag 字段。这两个模型之间还存在着一对多的关系,即一个员工可能有多个电话,一个电话可能属于一个员工。

class Employee extends Model
{
    public function telephones()
    {
        return $this->hasMany(Telephone::class);
    }
}



class Telephone extends Model
{
        public function employee()
    {
        return $this->belongsTo(Employee::class);
    }
}

Employee 模型引用名为 mydb1 的数据库模式中存在的表 employees,而 Telephone 模型与存在于名为 mydb2 的不同数据库模式中的 telephones 表相关。

我想要的是使用 Eloquent 仅获取具有至少一部电话的特定标志eager loaded的员工并且(如果可能)不是查询构建器

我到目前为止没有成功的尝试是:

1) 在Controller中使用whereHas方法

$employees = Employee::whereHas('telephones', function ($query) {

    $query->where('flag', 1); //Fetch only the employees with telephones of flag=1

})->with([

    'telephones' => function ($query) { //Eager load only the telephones of flag=1

        $query->where('flag', 1);
    }

])->get();

我在这里尝试做的是,首先仅检索拥有 flag=1 的电话的员工,其次仅急切加载这些电话,但我得到以下查询异常,因为不同的使用的数据库连接:

未找到基表或 View :表 mydb1.telephones 不存在(这是真的,telephones 存在于 mydb2 中)

2) Controller 中带有约束的预加载

$employees = Employee::with([

    'telephones' => function ($query) {

        $query->where('flag', 1);
    },

])->get();

此方法急切地加载带有 flag=1 的电话,但它返回所有 员工实例,这不是我真正想要的。我想收集 只有有电话的员工模型 flag = 1,不包括 telephones = []

最佳答案

考虑到this post , this post和@Giedrius Kiršys 在下面的回答,我终于想出了一个适合我需要的解决方案,使用以下步骤:

  1. 创建一个返回模型中的关系对象的方法
  2. eager load Controller 中的这种新关系
  3. 使用模型中的查询范围过滤掉标记为 != 1 的电话

员工模型中

/**
 * This is the new relationship
 *
 */
public function flaggedTelephones()
{
    return $this->telephones()
        ->where('flag', 1); //this will return a relation object
}



/**
 *  This is the query scope that filters the flagged telephones
 *
 *    This is the raw query performed:
 *    select * from mydb1.employees where exists (
 *    select * from mydb2.telephones
 *    where telephones.employee_id = employee.id
 *    and flag = 1);
 *
 */    
public function scopeHasFlaggedTelephones($query, $id)
{
    return $query->whereExists(function ($query) use ($id) {
        $query->select(DB::raw('*'))
            ->from('mydb2.telephones')
            ->where('telephones.flag', $flag)
            ->whereRaw('telephones.employee_id = employees.id');
    });
}

在 Controller 中

现在我可以使用这种优雅的语法,就像 Eloquent 一样

$employees = Employee::with('flaggedTelephones')->hasFlaggedTelephones()->get();

读起来像“获取所有带有已标记电话的员工,然后只获取至少拥有一部已标记电话的员工”

编辑:

在与 Laravel 框架打交道一段时间后(当前版本使用 5.2.39),我想,事实上,如果关系模型存在于使用 from() 方法的不同数据库,如下所示:

$employees = Employee::whereHas('telephones', function($query){

    $query->from('mydb2.telephones')->where('flag', 1);

})->get();

@Rob Contreras 声明了 from() 方法的使用,但看起来该方法需要将数据库和表作为参数。

关于mysql - 在 Laravel 5.2 中使用多个 MySQL 数据库连接查询关系是否存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36500518/

相关文章:

laravel - createMany 相当于 updateOrCreate

php - Laravel Eloquent 关系 findMany 或 find

php - 寻找包含以下技术 ColdFusion、PHP、MS SQL Server、MySQL 的 Web 服务器

php - 为什么在 codeigniter 中秒和分钟不能正确计算?

php - 如何使用 PHP 添加保持登录状态?

php - Laravel 中的表关系

php - Laravel 队列 :restart is not killing workers

mysql - 我如何选择喜欢mysql中的通配符

php - Laravel OpenAI 客户端无法处理列表结果

php - Laravel 5.1 ACL 使用 spatie/laravel-permission