2012-10-08 2 views
14

Ho iniziato a giocare con la libreria Doctrine ORM e ho imparato a conoscere tutte le associazioni tra tabelle.Doctrine - OneToOne Unidirezionale vs OneToOne Bidirezionale

Quindi mi sono bloccato con le differenze nella relazione unidirezionale e bidirezionale.

Come ho capito, la relazione unidirezionale ha la chiave primaria solo su un lato, e quella parte sta possedendo il lato giusto? E la relazione bidirezionale ha la chiave primaria in entrambe le tabelle e quindi è possibile avere una relazione da entrambi i lati e impostare i vincoli su entrambi i lati.

Ora, sto leggendo la documentazione di Doctrine sulle relazioni e ci sono: Unidirectional e Bidirectional associazioni.

Ma producono lo stesso SQL e le stesse tabelle con le stesse chiavi e vincoli primari. Quindi non vedo davvero alcuna differenza in quei due. Ed entrambi gli esempi hanno la chiave primaria su un lato.

Come ho capito, la vera relazione bidirezionale dovrebbe avere le chiavi primarie in entrambe le tabelle che puntano all'altra tabella, giusto? E con un esempio dato sulla documentazione di Doctrine questo non è il caso. Entrambi gli esempi danno lo stesso risultato e sono uguali.

Quindi, quello che ho fatto, è questo, diciamo che ho User e Card Entity, e voglio che la relazione sia OneToOne Bidirezionale.

/** 
* @Entity 
* @Table(name="users") 
*/ 

class User 
{ 
    /** 
    * @Id 
    * @GeneratedValue 
    * @Column(type="bigint") 
    */ 
    protected $id; 

    /** 
    * @OneToOne(targetEntity="Card", mappedBy="User") 
    * @JoinColumn(name="card_id", referencedColumnName="id") 
    */ 
    protected $card; 

    /** 
    * @Column(name="user_name", type="string") 
    */ 
    protected $userName; 

    /** 
    * @Column(name="user_pass", type="string") 
    */ 
    protected $userPass; 
} 

    /** 
* @Entity 
* @Table(name="cards") 
*/ 

class Card 
{ 
    /** 
    * @Id 
    * @GeneratedValue 
    * @Column(type="bigint") 
    */ 
    protected $id; 

    /** 
    * @OneToOne(targetEntity="User", inversedBy="Card") 
    * @JoinColumn(name="user_id", referencedColumnName="id") 
    */ 
    protected $user; 

    /** 
    * @Column(name="post_title", type="string") 
    */ 
    protected $cardType; 
} 

La differenza qui è che ho scritto @JoinColumn in entrambi gli oggetti/entità. E nell'esempio di Doctrine ce n'è solo uno. Ora vorrei ottenere quello che penso sia una relazione bidirezionale. Se guardo il diagramma EER, posso vedere una linea che punta da utente a card e l'altra da carta a utente.

Quindi ho capito bene? La documentazione di Doctrine è errata? : D Come apparirebbe la relazione Bidirezionale OneToOne nel diagramma EER?

Grazie!

+0

Chiunque? Nessuno? : D – otporan

risposta

12

l'unica differenza è nell'interfaccia classe PHP, cioè in presenza o assenza della proprietà che punta al proprietario (ad esempio la $customer proprietà nell'esempio Doctrine menzionato).In altre parole, Doctrine ha solo bisogno di sapere se è necessario occuparsi di una singola proprietà ($shipping) o di due proprietà ($cart e $customer). Non c'è altra differenza. Pertanto, il codice SQL è lo stesso (poiché una chiave esterna è sufficiente per rappresentare una qualsiasi relazione 1: N) e non vi sarebbe alcuna differenza nemmeno nel diagramma EER (poiché in EER in genere non si risolvono i dettagli dell'implementazione relativi a PHP).

9

Unidirezionale e bidirezionale non hanno nulla a che fare con l'algoritmo in background su come creare queste connessioni nel livello del database.

Tutto ciò di cui parlano è come le connessioni possono essere utilizzate. In una relazione unidirezionale è possibile accedere alla destinazione solo da un sito. Una relazione bidirezionale consente di chiamare la connessione da due (entrambi) lati.

Quindi in un unidir. rel. model_a può arrivare a model_b, ma model_b non può arrivare a model_a (senza lavoro extra). Se ora usi un bidir. rel entrambi i modelli possono accedere reciprocamente senza problemi

In termini dottrina, un rapporto unidirezionale definisce un metodo $modelA->getModelB(), ma non un metodo $modelB->getModelA(), mentre un rapporto bidirezionale definisce sia metodi (o di accesso, come vuoi chiamarli)

in un diagramma UML sarebbe simile a questa:

unidirectional 
modelA --X------> modelB 

bidirectional 
modelA <--------> modelB