mysql 2个数据库关联查询,在Laravel 5.2中使用多个MySQL数据库连接查询关系存在

I am dealing with the following situation: I have two models, an Employee with id and name fields and a Telephone with id, employee_id and flag fields. There is also an one-to-many relationship between these two models, that is an employee may have many telephones and a telephone may belong to a single employee.

class Employee extends Model

{

public function telephones()

{

return $this->hasMany(Telephone::class);

}

}

class Telephone extends Model

{

public function employee()

{

return $this->belongsTo(Employee::class);

}

}

The Employee model references a table employees that exists in database schema named mydb1, while the Telephone model is related to a telephones table that exists in a different database schema named mydb2.

What I want is to fetch only the employees with at least one telephone of a specific flag eager loaded, using Eloquent and (if possible) not the query builder

What I tried so far without success is:

1) use the whereHas method in the Controller

$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();

What I try to do here is first to retrieve only the employees that have telephones with flag=1 and second to eager load only these telephones, but I get the following query exception because of the different db connections used:

Base table or view not found: Table mydb1.telephones doesn't exist (this is true, telephones exists in mydb2)

2) Eager load with constrains in the Controller

$employees = Employee::with([

'telephones' => function ($query) {

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

},

])->get();

This method eager loads the telephones with flag=1, but it returns all the employee instances, which is not what I really want. I would like to have a collection of only the employee models that have telephones with flag = 1, excluding the models with telephones = []

解决方案

Taking into account this post, this post and @Giedrius Kiršys answer below, I finally came up with a solution that fits my needs, using the following steps:

create a method that returns a Relation object in the Model

eager load this new relationship in the Controller

filtered out the telephones of flag != 1 using a query scope in the Model

In Employee model

/**

* 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');

});

}

In the Controller

Now I may use this elegant syntax a’la Eloquent

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

which reads like "Fetch all the employees with flagged telephones eager loaded, and then take only the employees that have at least one flagged telephone"

EDIT:

After dealing with the Laravel framework for a while (current version used 5.2.39), I figured, that in fact, whereHas() clauses do work in case of the relationship model exists in a different database using the from() method, as it is depicted below:

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

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

})->get();

@Rob Contreras credits for stating the use of the from() method, however it looks like the method requires to take both the database and the table as an argument.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值