Eloquent 모델 관계
개요
관계형 데이터베이스 를 사용할 때 Eloquent ORM은 모델을 모델 클래스에 해당하는 테이블의 행으로 저장합니다. MongoDB 를 사용하는 경우 Laravel 통합은 모델 클래스에 해당하는 컬렉션에 모델을 문서로 저장합니다.
관계를 정의하려면 적절한 관계 메서드를 호출하는 함수를 모델 클래스에 추가합니다. 이 함수를 사용하면 관련 모델에 동적 속성 으로 액세스할 수 있습니다. 동적 속성을 사용하면 모델의 속성에 액세스하는 데 사용하는 것과 동일한 구문을 사용하여 관련 모델에 액세스할 수 있습니다.
다음 섹션에서는 Laravel 통합에서 사용할 수 있는 Laravel Eloquent와 MongoDB 관련 관계를 설명하고, 이를 정의하고 사용하는 방법에 대한 예를 보여줍니다.
일대일 관계
hasOne()
메서드와 그 역함수를 사용하여 생성된belongsTo()
일대다 관계,
hasMany()
와 그 역함수인belongsTo()
을(를) 사용하여 생성belongsToMany()
메서드를 사용하여 생성된 다대다 관계내장된 문서 패턴
embedsOne()
또는embedsMany()
메서드를 사용하여 생성된 일대일 또는 일대다 관계를 나타낼 수 있는 MongoDB 관련 관계입니다.데이터베이스 간 관계, MongoDB와 SQL 모델 간의 관계를 생성하려는 경우 필요합니다.
일대일 관계
모델 간의 일대일 관계는 정확히 하나의 다른 유형의 모델 레코드와 관련된 모델 레코드로 구성됩니다.
일대일 관계를 추가하면 Eloquent를 사용하여 동적 속성을 사용하여 모델에 액세스하고 모델의 문서 ID를 관련 모델에 저장할 수 있습니다.
Laravel MongoDB에서는 hasOne()
메서드 또는 belongsTo()
메서드를 사용하여 일대일 관계를 정의할 수 있습니다.
belongsTo()
메서드를 사용하여 관계의 역관계를 추가하면 Eloquent를 사용하면 동적 속성을 사용하여 모델에 액세스할 수 있지만 필드는 추가하지 않습니다.
일대일 관계에 학습 보려면 Laravel 문서에서 일대일 을 참조하세요.
일대일 예시
다음 예제 클래스는 메서드를 사용하여 HasOne
Planet
모델과 Orbit
모델 간의 일대일 관계를 정의하는 방법을 hasOne()
보여줍니다.
declare(strict_types=1); namespace App\Models; use MongoDB\Laravel\Eloquent\Model; use MongoDB\Laravel\Relations\HasOne; class Planet extends Model { protected $connection = 'mongodb'; public function orbit(): HasOne { return $this->hasOne(Orbit::class); } }
다음 예제 클래스에서는 belongsTo()
메서드를 사용하여 Orbit
와 Planet
간의 BelongsTo
역관계를 정의하는 방법을 보여 줍니다.
declare(strict_types=1); namespace App\Models; use MongoDB\Laravel\Eloquent\Model; use MongoDB\Laravel\Relations\BelongsTo; class Orbit extends Model { protected $connection = 'mongodb'; public function planet(): BelongsTo { return $this->belongsTo(Planet::class); } }
다음 샘플 코드는 각 클래스에 대한 모델을 인스턴스화하고 모델 간의 관계를 추가하는 방법을 보여줍니다. VIEW OUTPUT 버튼을 클릭하면 코드를 실행하여 생성된 데이터를 볼 수 있습니다.
$planet = new Planet(); $planet->name = 'Earth'; $planet->diameter_km = 12742; $planet->save(); $orbit = new Orbit(); $orbit->period = 365.26; $orbit->direction = 'counterclockwise'; $planet->orbit()->save($orbit);
// Document in the "planets" collection { _id: ObjectId('65de67fb2e59d63e6d07f8b8'), name: 'Earth', diameter_km: 12742, // ... } // Document in the "orbits" collection { _id: ObjectId('65de67fb2e59d63e6d07f8b9'), period: 365.26, direction: 'counterclockwise', planet_id: '65de67fb2e59d63e6d07f8b8', // ... }
다음 샘플 코드는 예제 클래스에 정의된 동적 속성을 사용하여 관련 모델에 액세스하는 방법을 보여줍니다.
$planet = Planet::first(); $relatedOrbit = $planet->orbit; $orbit = Orbit::first(); $relatedPlanet = $orbit->planet;
일대다 관계
모델 간의 일대다 관계는 상위 모델과 하나 이상의 관련 하위 모델 레코드로 구성됩니다.
일대다 관계 메서드를 추가하면 Eloquent를 사용하여 동적 속성을 사용하여 모델에 액세스하고 각 하위 모델 문서에 상위 모델의 문서 ID를 저장할 수 있습니다.
Laravel MongoDB에서는 상위 클래스에 hasMany()
메서드를 추가하고 선택적으로 하위 클래스에 belongsTo()
메서드를 추가하여 일대다 관계를 정의할 수 있습니다.
belongsTo()
메서드를 사용하여 관계의 역관계를 추가하면 Eloquent를 사용하면 필드를 추가하지 않고도 동적 속성을 사용하여 상위 모델에 액세스할 수 있습니다.
일대다 관계에 대해 자세히 알아보려면 일대 다를 참조하세요. Laravel 문서에서 확인할 수 있습니다.
일대다 예제
다음 예제 클래스는 hasMany()
메서드를 사용하여 Planet
상위 모델과 Moon
하위 모델 간의 HasMany
일대다 관계를 정의하는 방법을 보여줍니다.
declare(strict_types=1); namespace App\Models; use MongoDB\Laravel\Eloquent\Model; use MongoDB\Laravel\Relations\HasMany; class Planet extends Model { protected $connection = 'mongodb'; public function moons(): HasMany { return $this->hasMany(Moon::class); } }
다음 예제 클래스에서는 belongsTo()
메서드를 사용하여 Moon
하위 모델과 Planet
상위 모델 간의 BelongsTo
역관계를 정의하는 방법을 보여 줍니다.
declare(strict_types=1); namespace App\Models; use MongoDB\Laravel\Eloquent\Model; use MongoDB\Laravel\Relations\BelongsTo; class Moon extends Model { protected $connection = 'mongodb'; public function planet(): BelongsTo { return $this->belongsTo(Planet::class); } }
다음 샘플 코드는 각 클래스에 대한 모델을 인스턴스화하고 모델 간의 관계를 추가하는 방법을 보여줍니다. VIEW OUTPUT 버튼을 클릭하면 코드를 실행하여 생성된 데이터를 볼 수 있습니다.
$planet = new Planet(); $planet->name = 'Jupiter'; $planet->diameter_km = 142984; $planet->save(); $moon1 = new Moon(); $moon1->name = 'Ganymede'; $moon1->orbital_period = 7.15; $moon2 = new Moon(); $moon2->name = 'Europa'; $moon2->orbital_period = 3.55; $planet->moons()->save($moon1); $planet->moons()->save($moon2);
// Parent document in the "planets" collection { _id: ObjectId('65dfb0050e323bbef800f7b2'), name: 'Jupiter', diameter_km: 142984, // ... } // Child documents in the "moons" collection [ { _id: ObjectId('65dfb0050e323bbef800f7b3'), name: 'Ganymede', orbital_period: 7.15, planet_id: '65dfb0050e323bbef800f7b2', // ... }, { _id: ObjectId('65dfb0050e323bbef800f7b4'), name: 'Europa', orbital_period: 3.55, planet_id: '65dfb0050e323bbef800f7b2', // ... } ]
다음 샘플 코드는 예제 클래스에 정의된 동적 속성을 사용하여 관련 모델에 액세스하는 방법을 보여줍니다.
$planet = Planet::first(); $relatedMoons = $planet->moons; $moon = Moon::first(); $relatedPlanet = $moon->planet;
다대다 관계
다대다 관계는 서로 다른 두 모델 유형 간의 관계로 구성되며, 각 모델 유형에 대해 모델의 인스턴스가 다른 유형의 여러 인스턴스와 관련될 수 있습니다.
Laravel MongoDB에서는 두 관련 클래스에 belongsToMany()
메서드를 추가하여 다대다 관계를 정의할 수 있습니다.
관계형 데이터베이스 에서 다대다 관계 를 정의하면 Laravel은 관계를 추적 하기 위해 피벗 테이블을 생성합니다. Laravel 통합을 사용하면 피벗 테이블 생성이 생략되고 관련 모델 클래스 이름에서 파생된 문서 필드 에 관련 문서 ID가 추가됩니다.
팁
Laravel 통합은 피벗 테이블 대신 문서 필드 를 사용하므로 belongsToMany()
생성자에서 피벗 테이블 매개변수를 생략하거나 null
로 설정하다 합니다.
Laravel 의 다대다 관계에 대해 자세히 알아보려면 다대다를 참조하세요. Laravel 문서에서 확인할 수 있습니다.
다음 섹션에서는 모델 클래스 간에 다대다 관계를 만드는 방법의 예를 보여 줍니다.
다대다 예시
다음 예제 클래스는 메서드를 BelongsToMany
Planet
SpaceExplorer
사용하여 모델과 모델 간의 다대다 관계를 정의하는 방법을 belongsToMany()
보여줍니다.
declare(strict_types=1); namespace App\Models; use MongoDB\Laravel\Eloquent\Model; use MongoDB\Laravel\Relations\BelongsToMany; class Planet extends Model { protected $connection = 'mongodb'; public function visitors(): BelongsToMany { return $this->belongsToMany(SpaceExplorer::class); } }
다음 예제 클래스는 메서드를 사용하여 BelongsToMany
SpaceExplorer
모델과 Planet
모델 간의 역 다대다 관계를 정의하는 방법을 belongsToMany()
보여줍니다.
declare(strict_types=1); namespace App\Models; use MongoDB\Laravel\Eloquent\Model; use MongoDB\Laravel\Relations\BelongsToMany; class SpaceExplorer extends Model { protected $connection = 'mongodb'; public function planetsVisited(): BelongsToMany { return $this->belongsToMany(Planet::class); } }
다음 샘플 코드는 각 클래스에 대한 모델을 인스턴스화하고 모델 간의 관계를 추가하는 방법을 보여줍니다. VIEW OUTPUT 버튼을 클릭하면 코드를 실행하여 생성된 데이터를 볼 수 있습니다.
$planetEarth = new Planet(); $planetEarth->name = 'Earth'; $planetEarth->save(); $planetMars = new Planet(); $planetMars->name = 'Mars'; $planetMars->save(); $planetJupiter = new Planet(); $planetJupiter->name = 'Jupiter'; $planetJupiter->save(); $explorerTanya = new SpaceExplorer(); $explorerTanya->name = 'Tanya Kirbuk'; $explorerTanya->save(); $explorerMark = new SpaceExplorer(); $explorerMark->name = 'Mark Watney'; $explorerMark->save(); $explorerJeanluc = new SpaceExplorer(); $explorerJeanluc->name = 'Jean-Luc Picard'; $explorerJeanluc->save(); $explorerTanya->planetsVisited()->attach($planetEarth); $explorerTanya->planetsVisited()->attach($planetJupiter); $explorerMark->planetsVisited()->attach($planetEarth); $explorerMark->planetsVisited()->attach($planetMars); $explorerJeanluc->planetsVisited()->attach($planetEarth); $explorerJeanluc->planetsVisited()->attach($planetMars); $explorerJeanluc->planetsVisited()->attach($planetJupiter);
// Documents in the "planets" collection [ { _id: ObjectId('65e1043a5265269a03078ad0'), name: 'Earth', // ... space_explorer_ids: [ '65e1043b5265269a03078ad3', '65e1043b5265269a03078ad4', '65e1043b5265269a03078ad5' ], }, { _id: ObjectId('65e1043a5265269a03078ad1'), name: 'Mars', // ... space_explorer_ids: [ '65e1043b5265269a03078ad4', '65e1043b5265269a03078ad5' ] }, { _id: ObjectId('65e1043b5265269a03078ad2'), name: 'Jupiter', // ... space_explorer_ids: [ '65e1043b5265269a03078ad3', '65e1043b5265269a03078ad5' ] } ] // Documents in the "space_explorers" collection [ { _id: ObjectId('65e1043b5265269a03078ad3'), name: 'Tanya Kirbuk', // ... planet_ids: [ '65e1043a5265269a03078ad0', '65e1043b5265269a03078ad2' ] }, { _id: ObjectId('65e1043b5265269a03078ad4'), name: 'Mark Watney', // ... planet_ids: [ '65e1043a5265269a03078ad0', '65e1043a5265269a03078ad1' ] }, { _id: ObjectId('65e1043b5265269a03078ad5'), name: 'Jean-Luc Picard', // ... planet_ids: [ '65e1043a5265269a03078ad0', '65e1043a5265269a03078ad1', '65e1043b5265269a03078ad2' ] } ]
다음 샘플 코드는 예제 클래스에 정의된 동적 속성을 사용하여 관련 모델에 액세스하는 방법을 보여줍니다.
$planet = Planet::first(); $explorers = $planet->visitors; $spaceExplorer = SpaceExplorer::first(); $explored = $spaceExplorer->planetsVisited;
임베디드 문서 패턴
MongoDB에서 내장된 문서 패턴은 외래 키 참조를 유지하는 대신 관련 모델의 데이터를 상위 모델에 추가합니다. 이 패턴을 사용하여 다음 요구 사항 중 하나 이상을 충족합니다.
관련 데이터를 단일 컬렉션에 함께 보관
문서 및 관련 데이터의 여러 필드에 원자적 업데이트 수행
데이터를 가져오는 데 필요한 읽기 횟수 줄이기
Laravel MongoDB에서는 다음 메서드 중 하나를 추가하여 내장된 문서를 정의할 수 있습니다.
embedsOne()
단일 문서 포함embedsMany()
여러 문서를 포함하려면
참고
이러한 메서드는 쿼리 빌더 객체와 다른 Eloquent 컬렉션을 반환합니다.
MongoDB 내장된 문서 패턴 에 학습 보려면 다음 MongoDB Server 튜토리얼을 참조하세요.
다음 섹션에서는 내장된 문서 패턴을 사용하는 방법의 예를 보여줍니다.
내장된 문서 예시
다음 예제 클래스는 메서드를 사용하여 EmbedsMany
SpaceShip
모델과 Cargo
모델 간의 일대다 관계를 정의하는 방법을 embedsMany()
보여줍니다.
declare(strict_types=1); namespace App\Models; use MongoDB\Laravel\Eloquent\Model; use MongoDB\Laravel\Relations\EmbedsMany; class SpaceShip extends Model { protected $connection = 'mongodb'; public function cargo(): EmbedsMany { return $this->embedsMany(Cargo::class); } }
임베디드 모델 클래스는 다음 Cargo
모델 클래스에 표시된 대로 관계 정의를 생략합니다.
declare(strict_types=1); namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Cargo extends Model { protected $connection = 'mongodb'; }
다음 샘플 코드는 SpaceShip
모델을 만들고 여러 Cargo
모델과 코드를 실행하여 만든 MongoDB 문서를 임베드하는 방법을 보여줍니다. VIEW OUTPUT 버튼을 클릭하면 코드를 실행하여 생성된 데이터를 볼 수 있습니다.
$spaceship = new SpaceShip(); $spaceship->name = 'The Millenium Falcon'; $spaceship->save(); $cargoSpice = new Cargo(); $cargoSpice->name = 'spice'; $cargoSpice->weight = 50; $cargoHyperdrive = new Cargo(); $cargoHyperdrive->name = 'hyperdrive'; $cargoHyperdrive->weight = 25; $spaceship->cargo()->attach($cargoSpice); $spaceship->cargo()->attach($cargoHyperdrive);
// Document in the "space_ships" collection { _id: ObjectId('65e207b9aa167d29a3048853'), name: 'The Millenium Falcon', // ... cargo: [ { name: 'spice', weight: 50, // ... _id: ObjectId('65e207b9aa167d29a3048854') }, { name: 'hyperdrive', weight: 25, // ... _id: ObjectId('65e207b9aa167d29a3048855') } ] }
데이터베이스 간 관계
Laravel MongoDB 의 데이터베이스 간 관계는 관계형 데이터베이스에 저장된 모델과 MongoDB database 에 저장된 모델 간의 관계입니다.
데이터베이스 간 관계를 추가하면 Eloquent에서 동적 속성을 사용하여 관련 모델에 액세스할 수 있습니다.
Laravel 통합은 다음과 같은 데이터베이스 간 관계 메서드를 지원합니다.
hasOne()
hasMany()
belongsTo()
데이터베이스 간 관계를 정의하려면 관계형 데이터베이스에 저장된 클래스에서 MongoDB\Laravel\Eloquent\HybridRelations
패키지를 가져와야 합니다.
다음 섹션에서는 데이터베이스 간 관계를 정의하는 방법의 예를 보여줍니다.
데이터베이스 간 관계 예시
다음 예제 클래스는 관계형 데이터베이스에 저장된 SpaceShip
모델과 MongoDB database 에 저장된 Passenger
모델 간의 HasMany
관계를 정의하는 방법을 보여줍니다.
declare(strict_types=1); namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; use MongoDB\Laravel\Eloquent\HybridRelations; class SpaceShip extends Model { use HybridRelations; protected $connection = 'sqlite'; public function passengers(): HasMany { return $this->hasMany(Passenger::class); } }
다음 예제 클래스에서는 belongsTo()
메서드를 사용하여 Passenger
모델과 Spaceship
모델 간의 BelongsTo
역관계를 정의하는 방법을 보여 줍니다.
declare(strict_types=1); namespace App\Models; use Illuminate\Database\Eloquent\Relations\BelongsTo; use MongoDB\Laravel\Eloquent\Model; class Passenger extends Model { protected $connection = 'mongodb'; public function spaceship(): BelongsTo { return $this->belongsTo(SpaceShip::class); } }
팁
관계형 데이터베이스 테이블 스키마에 정의된 기본 키가 모델에서 사용하는 것과 일치하는지 확인합니다. Laravel 프라이머리 키 및 스키마 정의에 대해 자세히 알아보려면 Laravel 문서의 다음 페이지를 참조하세요.
다음 샘플 코드는 MySQL 데이터베이스에서 SpaceShip
모델을 생성하고 MongoDB database 에서 관련 Passenger
모델을 생성하는 방법 및 코드를 실행하여 생성된 데이터를 보여줍니다. VIEW OUTPUT 버튼을 클릭하면 코드를 실행하여 생성된 데이터를 볼 수 있습니다.
$spaceship = new SpaceShip(); $spaceship->id = 1234; $spaceship->name = 'Nostromo'; $spaceship->save(); $passengerEllen = new Passenger(); $passengerEllen->name = 'Ellen Ripley'; $passengerDwayne = new Passenger(); $passengerDwayne->name = 'Dwayne Hicks'; $spaceship->passengers()->save($passengerEllen); $spaceship->passengers()->save($passengerDwayne);
-- Row in the "space_ships" table +------+----------+ | id | name | +------+----------+ | 1234 | Nostromo | +------+----------+ // Document in the "passengers" collection [ { _id: ObjectId('65e625e74903fd63af0a5524'), name: 'Ellen Ripley', space_ship_id: 1234, // ... }, { _id: ObjectId('65e625e74903fd63af0a5525'), name: 'Dwayne Hicks', space_ship_id: 1234, // ... } ]