Ok, esta es probablemente una pregunta trivial, pero tengo problemas para visualizar y comprender las diferencias y cuándo usar cada una. Tampoco estoy un poco claro sobre cómo los conceptos como los mapeos unidireccionales y bidireccionales afectan las relaciones uno a muchos / muchos a muchos. Estoy usando Hibernate en este momento, por lo que cualquier explicación relacionada con ORM será útil.
Como ejemplo, digamos que tengo la siguiente configuración:
public class Person{
private Long personId;
private Set<Skill> skills;
//Getters and setters
}
public class Skill{
private Long skillId;
private String skillName;
//Getters and setters
}
Entonces, en este caso, ¿qué tipo de mapeo tendría? Las respuestas a este ejemplo específico son definitivamente apreciadas, pero también me gustaría una visión general de cuándo usar uno a muchos y muchos a muchos y cuándo usar una tabla de unión frente a una columna de unión y unidireccional versus bidireccional.
fuente
Respuestas:
Uno a muchos : una persona tiene muchas habilidades, una habilidad no se reutiliza entre personas
Muchos a muchos : una persona tiene muchas habilidades, una habilidad se reutiliza entre personas
En una relación Uno a Muchos, un objeto es el "padre" y el otro es el "hijo". El padre controla la existencia del niño. En un Many-To-Many, la existencia de cualquiera de los dos tipos depende de algo externo a ambos (en el contexto de aplicación más amplio).
Su tema (dominio) debe dictar si la relación es de uno a muchos o de muchos a muchos; sin embargo, creo que hacer que la relación sea unidireccional o bidireccional es una decisión de ingeniería que intercambia memoria, procesamiento y rendimiento. etc.
¡Lo que puede ser confuso es que una relación bidireccional de muchos a muchos no necesita ser simétrica! Es decir, un grupo de personas podría señalar una habilidad, pero la habilidad no necesita relacionarse solo con esas personas. Típicamente lo haría, pero tal simetría no es un requisito. Tomemos el amor, por ejemplo, es bidireccional ("I-Love", "Loves-Me"), pero a menudo asimétrico ("La amo, pero ella no me ama").
Todos estos están bien respaldados por Hibernate y JPA. Solo recuerde que Hibernate o cualquier otro ORM no se preocupa por mantener la simetría al administrar relaciones bidireccionales de muchos a muchos ... eso depende de la aplicación.
fuente
Se parece a todo el mundo está respondiendo
One-to-many
frente aMany-to-many
:La diferencia entre
One-to-many
,Many-to-one
yMany-to-Many
es:One-to-many
vsMany-to-one
es una cuestión de perspectiva .Unidirectional
vsBidirectional
no afectará la asignación, pero hará una diferencia en cómo puede acceder a sus datos.Many-to-one
elmany
lado mantendrá la referencia delone
lado. Un buen ejemplo es "Un estado tiene ciudades". En este casoState
es el lado uno yCity
es el lado múltiple. Habrá una columnastate_id
en la tablacities
.One-to-Many
un lado estará nuestro punto de referencia. Por ejemplo, "Un usuario tiene una dirección". En este caso, podríamos tener tres columnasaddress_1_id
,address_2_id
y /address_3_id
o una tabla de búsqueda con restricción única enuser_id
yaddress_id
.Many-to-Many
miembros de cada parte se puede hacer referencia al número arbitrario de miembros de la otra parte. Para lograr esto, se utiliza una tabla de consulta . Ejemplo de esto es la relación entre médicos y pacientes. Un médico puede tener muchos pacientes y viceversa.fuente
s.persons
, ya que solo hays.person
One-to-many
relación como la describe es unaMany-to-many
relación porqueperson
tiene una referencia a muchosskills
peroskill
no mantiene una referencia a una persona en particular y muchospersons
pueden tener una referencia igualskill
. Y suMany-to-one
relación es en realidadOne-to-many
porque cada habilidad tiene una referencia solo a una,person
ya que un niño solo tiene una madre.skills
tieneperson_id
), entonces lo llamas Uno a muchos, pero cuando es uno, el lado "Muchos" (usuarios y direcciones,users
tieneaddress_id
), entonces lo llamas Muchos a uno. Pero estructuralmente ambos casos son idénticos y se llaman Uno a muchos.1) Los círculos son Entidades / POJO / Frijoles
2) deg es una abreviatura de grado como en gráficos (número de aristas)
PK = Clave primaria, FK = Clave externa
Tenga en cuenta la contradicción entre el grado y el nombre del lado. Muchos corresponde a grado = 1 mientras que Uno corresponde a grado> 1.
fuente
Eche un vistazo a este artículo: Asignación de relaciones de objetos
fuente
this occurs when the maximum of one multiplicity is one and the other is greater than one
lolwut?Uno a muchos
La relación de la tabla uno a muchos se ve de la siguiente manera:
En un sistema de base de datos relacional, una relación de tabla de uno a muchos vincula dos tablas basadas en una
Foreign Key
columna en el elemento secundario que hace referencia a laPrimary Key
fila de la tabla principal.En el diagrama de la tabla anterior, la
post_id
columna en lapost_comment
tabla tiene unaForeign Key
relación con la columna depost
id de la tablaPrimary Key
:Anotación @ManyToOne
La mejor manera de mapear la relación de la tabla uno a muchos es usar la
@ManyToOne
anotación.En nuestro caso, la entidad secundaria
PostComment
asigna lapost_id
columna Clave externa utilizando la@ManyToOne
anotación:Usando la
@OneToMany
anotación JPAEl hecho de que tenga la opción de usar la
@OneToMany
anotación, no significa que esta debería ser la opción predeterminada para cada relación de base de datos de uno a muchos . El problema con las colecciones es que solo podemos usarlas cuando el número de registros secundarios es bastante limitado.La mejor manera de mapear una
@OneToMany
asociación es confiar en el@ManyToOne
lado para propagar todos los cambios de estado de la entidad:La entidad principal
Post
, presenta dos métodos de utilidad (por ejemplo,addComment
yremoveComment
) que se utilizan para sincronizar ambos lados de la asociación bidireccional. Siempre debe proporcionar estos métodos siempre que trabaje con una asociación bidireccional ya que, de lo contrario, corre el riesgo de tener problemas de propagación de estado muy sutiles .La
@OneToMany
asociación unidireccional debe evitarse ya que es menos eficiente que usar@ManyToOne
o la@OneToMany
asociación bidireccional .Doce y cincuenta y nueve de la noche
La relación de la tabla uno a uno se ve de la siguiente manera:
En un sistema de base de datos relacional, una relación de tabla uno a uno vincula dos tablas basadas en una
Primary Key
columna en el elemento secundario que también haceForeign Key
referencia a laPrimary Key
fila de la tabla principal.Por lo tanto, podemos decir que la tabla secundaria comparte
Primary Key
con la tabla primaria.En el diagrama de la tabla anterior, la
id
columna de lapost_details
tabla también tiene unaForeign Key
relación con la columna de lapost
tablaid
Primary Key
:Usando el JPA
@OneToOne
con@MapsId
anotacionesLa mejor manera de mapear una
@OneToOne
relación es usarla@MapsId
. De esta manera, ni siquiera necesita una asociación bidireccional, ya que siempre puede buscar laPostDetails
entidad utilizando elPost
identificador de entidad.El mapeo se ve así:
[code language = "java"] @Entity (name = "PostDetails") @Table (name = "post_details") clase pública PostDetails {
} [/ código]
De esta manera, la
id
propiedad sirve como clave principal y clave externa. Notará que la@Id
columna ya no usa una@GeneratedValue
anotación ya que el identificador se llena con el identificador de lapost
asociación.Muchos a muchos
La relación de tabla de muchos a muchos tiene el siguiente aspecto:
En un sistema de base de datos relacional, una relación de tabla de muchos a muchos vincula dos tablas principales a través de una tabla secundaria que contiene dos
Foreign Key
columnas que hacen referencia a lasPrimary Key
columnas de las dos tablas principales.En el diagrama de la tabla anterior, la
post_id
columna de lapost_tag
tabla también tiene unaForeign Key
relación con la columna depost
ID de la tablaPrimary Key
:Y, la
tag_id
columna en lapost_tag
tabla tiene unaForeign Key
relación con la columna detag
id de la tablaPrimary Key
:Usando el
@ManyToMany
mapeo JPAAsí es como puede mapear la
many-to-many
relación de la tabla con JPA e Hibernate:tags
asociación en laPost
entidad solo define los tiposPERSIST
yMERGE
cascada. Como se explica en este artículo , laREMOVE
transición del estado de la entidad no tiene ningún sentido para una@ManyToMany
asociación JPA, ya que podría desencadenar una eliminación de la cadena que finalmente eliminaría ambos lados de la asociación.Post
entidad utiliza el identificador de entidad para la igualdad, ya que carece de una clave comercial única. Como se explica en este artículo , puede usar el identificador de entidad para la igualdad siempre que se asegure de que sea coherente en todas las transiciones de estado de entidad .Tag
entidad tiene una clave comercial única que está marcada con la@NaturalId
anotación específica de Hibernate . Cuando ese es el caso, la clave comercial única es el mejor candidato para los controles de igualdad .mappedBy
atributo de laposts
asociación en laTag
entidad marca que, en esta relación bidireccional, laPost
entidad posee la asociación. Esto es necesario ya que solo un lado puede ser dueño de una relación, y los cambios solo se propagan a la base de datos desde este lado en particular.Set
es preferible, ya que usar unList
con@ManyToMany
es menos eficiente.fuente
esto probablemente requeriría una relación de muchos a muchos de la siguiente manera
Es posible que deba definir un joinTable + JoinColumn, pero es posible que funcione también sin ...
fuente
Yo explicaría de esa manera:
OneToOne - OneToOne relación
OneToMany - ManyToOne relación
ManyToMany - Relación ManyToMany
fuente
En primer lugar, lea toda la letra pequeña. Tenga en cuenta que el mapeo relacional de NHibernate (por lo tanto, supongo, Hibernate también) tiene una correspondencia divertida con DB y el mapeo de gráficos de objetos. Por ejemplo, las relaciones uno a uno a menudo se implementan como una relación muchos a uno.
En segundo lugar, antes de que podamos decirle cómo debe escribir su mapa O / R, también tenemos que ver su base de datos. En particular, ¿puede una sola habilidad ser poseída por varias personas? Si es así, tienes una relación de muchos a muchos; de lo contrario, es muchos a uno.
En tercer lugar, prefiero no implementar relaciones de muchos a muchos directamente, sino modelar la "tabla de unión" en su modelo de dominio, es decir, tratarla como una entidad, como esta:
¿Entonces ves lo que tienes? Tienes dos relaciones uno a muchos. (En este caso, la Persona puede tener una colección de Habilidades Personales, pero no tendría una colección de Habilidades). Sin embargo, algunos preferirán usar una relación de muchos a muchos (entre Persona y Habilidad); Esto es controvertido.
Cuarto, si tiene relaciones bidireccionales (por ejemplo, la Persona no solo tiene una colección de Habilidades, sino que también tiene una colección de Personas), NHibernate no aplica la bidireccionalidad en su BL para usted; solo comprende la bidireccionalidad de las relaciones con fines de persistencia.
Quinto, muchos a uno es mucho más fácil de usar correctamente en NHibernate (y supongo que Hibernate) que uno a muchos (mapeo de colección).
¡Buena suerte!
fuente