hibernate - una - ¿Diferencia entre Uno-a-Muchos, Muchos-a-Uno y Muchos-a-Muchos?
relacion uno a varios ejemplos (6)
Ok, esta es probablemente una pregunta trivial, pero estoy teniendo problemas para visualizar y entender las diferencias y cuándo usar cada una. También estoy un poco confuso en cuanto a cómo los conceptos como 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é? Las respuestas a este ejemplo específico son definitivamente apreciadas, pero también me gustaría tener una idea general de cuándo usar uno-a-muchos y muchos-a-muchos y cuándo usar una tabla de unión versus una columna de unión y unidireccional versus bidireccional.
1) Los círculos son Entidades / POJO / Frijoles
2) deg es la abreviatura de grado como en los gráficos (número de aristas)
PK = clave principal, FK = clave externa
Tenga en cuenta la contradicción entre el grado y el nombre del lado. Muchos corresponden al grado = 1 mientras que Uno corresponde al grado> 1.
Antes que nada, lea toda la letra pequeña. Tenga en cuenta que NHibernate (así, supongo, Hibernate también) mapeo relacional tiene una correspondencia graciosa con DB y mapeo de gráfico de objetos. Por ejemplo, las relaciones uno-a-uno a menudo se implementan como una relación de 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 DB. En particular, ¿puede una sola Habilidad ser poseída por múltiples 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 varios directamente, sino modelar la "tabla de unión" en su modelo de dominio, es decir, tratarla como una entidad, como esta:
class PersonSkill
{
Person person;
Skill skill;
}
Entonces, ¿ves lo que tienes? Tienes dos relaciones uno a muchos. (En este caso, Person puede tener una colección de PersonSkills, pero no tendría una colección de Skills). Sin embargo, algunos preferirán usar la relación muchos a muchos (entre Person y Skill); esto es controversial
En cuarto lugar, si tiene relaciones bidireccionales (por ejemplo, no solo tiene una colección de habilidades, sino que también tiene una colección de personas), NHibernate no impone la bidireccionalidad en su BL para usted; solo entiende la bidireccionalidad de las relaciones para fines de persistencia.
En quinto lugar, muchos a uno es mucho más fácil de usar correctamente en NHibernate (y supongo que Hibernate) que uno a muchos (mapeo de colecciones).
¡Buena suerte!
Eche un vistazo a este artículo: Mapeo de relaciones entre objetos
Hay dos categorías de relaciones de objeto con las que debe preocuparse al mapear. La primera categoría se basa en la multiplicidad e incluye tres tipos:
*One-to-one relationships. This is a relationship where the maximums of each of its multiplicities is one, an example of which is holds relationship between Employee and Position in Figure 11. An employee holds one and only one position and a position may be held by one employee (some positions go unfilled).
*One-to-many relationships. Also known as a many-to-one relationship, this occurs when the maximum of one multiplicity is one and the other is greater than one. An example is the works in relationship between Employee and Division. An employee works in one division and any given division has one or more employees working in it.
*Many-to-many relationships. This is a relationship where the maximum of both multiplicities is greater than one, an example of which is the assigned relationship between Employee and Task. An employee is assigned one or more tasks and each task is assigned to zero or more employees.
La segunda categoría se basa en la direccionalidad y contiene dos tipos, relaciones unidireccionales y relaciones bidireccionales.
*Uni-directional relationships. A uni-directional relationship when an object knows about the object(s) it is related to but the other object(s) do not know of the original object. An example of which is the holds relationship between Employee and Position in Figure 11, indicated by the line with an open arrowhead on it. Employee objects know about the position that they hold, but Position objects do not know which employee holds it (there was no requirement to do so). As you will soon see, uni-directional relationships are easier to implement than bi-directional relationships.
*Bi-directional relationships. A bi-directional relationship exists when the objects on both end of the relationship know of each other, an example of which is the works in relationship between Employee and Division. Employee objects know what division they work in and Division objects know what employees work in them.
Parece que todos responden One-to-many
vs Many-to-many
:
La diferencia entre One-to-many
, Many-to-one
y Many-to-Many
es:
One-to-many
vs Many-to-one
es una cuestión de perspectiva . Unidirectional
vs Bidirectional
no afectará el mapeo, pero hará la diferencia sobre cómo puede acceder a sus datos.
- En
One-to-many
losmany
lados mantendrán la referencia deone
lado. Un buen ejemplo es "Una persona tiene muchas habilidades". En este caso, laPerson
es un lado y laSkill
es el lado múltiple. Habrá una columnaperson_id
en lasskills
la mesa.
En clase de
Person
unidireccional tendráList<Skill> skills
peroSkill
no tendráPerson person
. En bidireccional se agregan ambas propiedades y le permite acceder a unaPerson
otorgado una habilidad (es decir,skill.person
).
- En
Many-to-one
los muchos lados serán nuestro punto de referencia. Por ejemplo, "Un usuario tiene una dirección". En nuestro sistema, muchos usuarios pueden compartir una dirección (por ejemplo, varias personas pueden compartir el mismo número de bloque). En ese caso, la columnaaddress_id
en la tabla deusers
será compartida por más de una fila deusers
. En este caso, decimos que losusers
y lasaddresses
tienenMany-to-one
relación deMany-to-one
.
En unidireccional, un
User
tendráAddress address
. Bidireccional tendrá unList<User> users
adicional deList<User> users
en la claseAddress
.
- En
Many-to-Many
miembros de cada parte pueden mantener referencia a una cantidad arbitraria de miembros de la otra parte. Para lograr esto, se usa una tabla de búsqueda . Ejemplo de esto es la relación entre médicos y pacientes. Un médico puede tener muchos pacientes y viceversa.
esto probablemente requeriría una relación de muchos a muchos de la siguiente manera
public class Person{
private Long personId;
@manytomany
private Set skills;
//Getters and setters
}
public class Skill{
private Long skillId;
private String skillName;
@manyToMany(MappedBy="skills,targetClass="Person")
private Set persons; // (people would not be a good convenion)
//Getters and setters
}
es posible que necesite definir un joinTable + JoinColumn, pero también funcionará sin ...
Uno a muchos : una persona tiene muchas habilidades, una habilidad no se reutiliza entre las personas
- Unidireccional : una persona puede hacer referencia directa a las habilidades a través de su conjunto
- Bidireccional : cada Habilidad "infantil" tiene un único puntero hacia la Persona (que no se muestra en el código)
Muchos a muchos : una persona tiene muchas habilidades, una habilidad se reutiliza entre personas
- Unidireccional : una persona puede hacer referencia directa a las habilidades a través de su conjunto
- Bidireccional : una Habilidad tiene un Conjunto de Persona (s) que se relacionan con ella.
En una relación One-To-Many, un objeto es el "padre" y el otro es el "niño". El padre controla la existencia del niño. En Many-To-Many, la existencia de cualquier tipo depende de algo que está fuera de ambos (en el contexto de la aplicación más grande).
El tema (dominio) debe determinar si la relación es de Uno a Muchos o de Muchos a Muchos. Sin embargo, considero que hacer que la relación sea unidireccional o bidireccional es una decisión de ingeniería que intercambia memoria, procesamiento y desempeño. , etc.
Lo que puede ser confuso es que una relación bidireccional de muchos a muchos no tiene que ser simétrica. Es decir, un grupo de personas podría apuntar a una habilidad, pero la habilidad no necesita relacionarse solo con esas personas. Normalmente lo haría, pero dicha simetría no es un requisito. Toma el amor, por ejemplo, es bidireccional ("I-Love", "Loves-Me"), pero a menudo asimétrico ("¡La amo, pero ella no me ama")!
Todos estos son bien compatibles con Hibernate y JPA. Solo recuerda que a Hibernate u a cualquier otro ORM no le importa mucho mantener la simetría cuando gestiona relaciones bidireccionales de muchos a muchos ... eso depende de la aplicación.