簡體   English   中英

用Laravel Eloquent加入同一台服務器上不同數據庫中的兩個MySQL表

[英]Join two MySQL tables in different databases on the same server with Laravel Eloquent

我在兩個不同的數據庫中有兩個表。 兩個數據庫都托管在同一個 AWS RDS 服務器上。 我有一個可以訪問兩個數據庫的用戶帳戶。 我在 config\database.php 中定義了兩個不同的連接:

return array(
    'default' => 'mysql',
    'connections' => array(
        # Our primary database connection
        'mysql' => array(
            'driver'    => 'mysql',
            'host'      => 'samehost',
            'database'  => 'database1',
            'username'  => 'user1',
            'password'  => 'pass1'
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),
        # Our secondary database connection
        'mysql2' => array(
            'driver'    => 'mysql',
            'host'      => 'samehost',
            'database'  => 'database2',
            'username'  => 'user2',
            'password'  => 'pass2'
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),
    ),
);

我有兩個模型table1連接到database1table2連接到database2 兩個表都有一個列id 如何為具有相同id的行加入 Eloquent 模型的查詢?

這個解決方案對我有用:

Model1::where('postID',$postID)
      ->join('database2.table2 as db2','Model1.id','=','db2.id')
      ->select(['Model1.*','db2.firstName','db2.lastName'])
      ->orderBy('score','desc')
      ->get();

如果您在同一連接上有兩個數據庫並設置為默認值,您可以嘗試這種方式。

$query = DB::table('database1.table1 as dt1')->leftjoin('database2.table2 as dt2', 'dt2.ID', '=', 'dt1.ID');        
$output = $query->select(['dt1.*','dt2.*'])->get();

我已經在我的本地主機上嘗試過它的工作。

這很棘手,但可以實現。 然而,有一些限制,無論如何都可能導致原始解決方案。

這是您需要的,假設 db1 是默認值:

// class ModelOne
public function modelTwo()
{
return $this->hasOne('ModelTwo', 'id');
}

//class ModelTwo
protected $table = 'db2.model_two_table';

public function modelOne()
{
return $this->belongsTo('ModelOne', 'id');
}
// then
$model1 = ModelOne::with('modelTwo')->get();
$model1 = ModelOne::has('modelTwo')->first(); 
// and so on

請注意,您不能在 db 配置中為表使用前綴。 此外,如果您在其中一個模型上定義非默認連接,則需要為兩者調整 $table。

您還可以為每個模型使用不同的連接,許多功能都可以這樣工作,但是您不能依賴 Eloquent 構建的連接:

ModelOne::with('modelTwo')->get(); // works as expected - this is what you asked for
ModelOne::has('modelTwo')->get(); // error, no table found

當然,除非您有相同的架構,但無論如何這都不是您想要的。

到目前為止,有些答案是正確的,我只是添加這個以防萬一有人正在尋找完整的動態解決方案(只需確保您的數據庫都在同一台服務器上並且您的帳戶可以訪問它們)(對於這個答案,我假設您已經設置了您的配置文件和模型文件)

$databaseName1 = (new Model1())->getConnection()->getDatabaseName();
$tableName1 = (new Model1())->getTable();
$tableName2 = (new Model2())->getTable();

然后你可以用 Laravel 提供的任何連接方法做任何你想要的連接方法,我看到很多人犯的另一個錯誤是他們堅持使用 DB Facade 來啟動查詢,事實並非如此

$databaseName2 = (new Model2())->getConnection()->getDatabaseName();
DB::join($databaseName1 . '.' . $tableName1, function($join) use ($databaseName1, $tableName1, $databaseName2, $tableName2) {
    $join->on($databaseName1 . '.' . $tableName1 . '.id', $databaseName2 . '.' . $tableName2 . '.table_id');
})->...

Model2::join($databaseName1 . '.' . $tableName1, function($join) use ($databaseName1, $tableName1, $tableName2) {
    $join->on($databaseName1 . '.' . $tableName1 . '.id', $tableName2 . '.table_id');
})->...

對於第二種方法,您不需要第二個連接,因為 Laravel 將根據您模型的連接選擇默認連接,所有其他相關子句(例如 where()、groupBy())中的數據也是如此。 我通常根據它們的模型名稱來命名變量。

連接不同數據庫的兩個模型的簡單雄辯方式

class User extends Model {

  public function Company()
  {
    return $this->hasOne(Company::class);
  }
}

class Company extends Model {
  protected $connection = 'mysql2';

  public function User()
  {
    return $this->belongsTo(User::class);
  }
}

使用上面的混合技術,我得到了以下使用 Laravel 的關系方法為我工作的方法。 我在基本(默認)數據庫中有股票 Laravel Users model。 我在同一台服務器上也有一個名為client的數據庫連接,它自己分片每個客戶端數據庫。 Client的頂部。 模型,我指定連接:

protected $connection = 'client';

然后,利用客戶端數據庫中的屬性 model 以及連接表 property_user,我可以使用 Eloquent 將屬性連接到用戶,反之亦然:

return $this->belongsToMany(
        'App\Models\User',
        $this->getConnection()->getDatabaseName().'.property_user',
        'property_id',
        'user_id'
    );

希望這可以幫助嘗試做同樣事情的人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM