2012-10-08 48 views
14

Comencé a jugar con Doctrine ORM library, y estoy aprendiendo sobre todas las asociaciones entre tablas.Doctrine - OneToOne Unidireccional vs OneToOne Bidireccional

Así que estoy atascado con las diferencias en relación bidireccional y bidireccional.

Según lo entiendo, la relación unidireccional tiene la tecla principal solo en un lado, y ese lado es el que posee el lado derecho? Y la relación bidireccional tiene una clave principal en ambas tablas y, por lo tanto, puede tener una relación desde ambos lados y establecer restricciones en ambos lados.

Ahora, estoy leyendo a través de la documentación de Doctrine sobre las relaciones y allí tienes: Unidirectional y Bidirectional asociaciones.

Pero producen el mismo SQL y las mismas tablas con las mismas claves primarias y restricciones. Así que realmente no veo ninguna diferencia en esos dos. Y ambos ejemplos tienen clave principal en un lado.

Según lo entiendo, la verdadera relación bidireccional debe tener claves primarias en ambas tablas apuntando a la otra tabla ¿verdad? Y con un ejemplo dado en la documentación de Doctrine, ese no es el caso. Ambos ejemplos dan el mismo resultado y son iguales.

Así que lo que hice, es esto, digamos que tengo Entidad de Usuario y Tarjeta, y quiero que la relación sea OneToOne Bidireccional.

/** 
* @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 diferencia aquí es que escribí @JoinColumn en ambos objetos/entidades. Y en el ejemplo de Doctrine solo hay uno. Ahora obtendría lo que creo que es relación bidireccional. Si miro el diagrama EER, puedo ver una línea que apunta de usuario a tarjeta, y la otra de tarjeta a usuario.

Así que, básicamente, lo hice bien? ¿La documentación de Doctrine está equivocada? : D ¿Cómo se vería la relación OneToOne bidireccional en el diagrama EER?

Gracias!

+0

¿Alguien? ¿Ninguno? :RE – otporan

Respuesta

12

la única diferencia está en la interfaz de la clase PHP, es decir, en presencia o ausencia de la propiedad que apunta de nuevo a la propietario (por ejemplo, el $customer propiedad en el ejemplo de Doctrine mencionado).En otras palabras, Doctrine solo necesita saber si debe ocuparse de una sola propiedad ($shipping) o dos propiedades ($cart y $customer). No hay otra diferencia. Por lo tanto, el código SQL es el mismo (porque una clave externa es suficiente para representar cualquier relación 1: N) y tampoco habría diferencia en el diagrama EER (porque en EER normalmente no se resuelven los detalles de implementación relacionados con PHP).

9

Unidireccional y bidireccional no tienen nada que ver con el algoritmo de fondo de cómo crear estas conexiones en la capa de la base de datos.

Todo lo que hablan es cómo se pueden usar las conexiones. En una relación unidireccional, puede acceder al objetivo solo desde un sitio. Una relación bidireccional permite llamar a la conexión desde dos (ambos) lados.

Así en unidir. Rel. model_a puede llegar a model_b, pero model_b no puede obtener model_a (sin trabajo adicional). Si ahora usa un bidir. rel ambos modelos pueden acceder a otra sin problemas

En cuanto a la doctrina, una relación unidireccional define un método $modelA->getModelB(), pero no es un método $modelB->getModelA(), mientras que una relación bidireccional define ambos métodos (o descriptores de acceso, como le quieran llamar)

en un diagrama UML que se vería así:

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

bidirectional 
modelA <--------> modelB 
Cuestiones relacionadas