Ich bin neu im Winterschlaf und muss Eins-zu-Viele- und Viele-zu-Eins-Beziehungen verwenden. Es ist eine bidirektionale Beziehung in meinen Objekten, so dass ich aus beiden Richtungen durchqueren kann. mappedBy
ist der empfohlene Weg, aber ich konnte es nicht verstehen. Kann jemand erklären:
- Was ist die empfohlene Art, es zu verwenden?
- Welchen Zweck löst es?
Für mein Beispiel sind hier meine Klassen mit Anmerkungen:
Airline
BESITZT vieleAirlineFlights
- Viele
AirlineFlights
gehören zu EINEMAirline
Fluggesellschaft :
@Entity
@Table(name="Airline")
public class Airline {
private Integer idAirline;
private String name;
private String code;
private String aliasName;
private Set<AirlineFlight> airlineFlights = new HashSet<AirlineFlight>(0);
public Airline(){}
public Airline(String name, String code, String aliasName, Set<AirlineFlight> flights) {
setName(name);
setCode(code);
setAliasName(aliasName);
setAirlineFlights(flights);
}
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="IDAIRLINE", nullable=false)
public Integer getIdAirline() {
return idAirline;
}
private void setIdAirline(Integer idAirline) {
this.idAirline = idAirline;
}
@Column(name="NAME", nullable=false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = DAOUtil.convertToDBString(name);
}
@Column(name="CODE", nullable=false, length=3)
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = DAOUtil.convertToDBString(code);
}
@Column(name="ALIAS", nullable=true)
public String getAliasName() {
return aliasName;
}
public void setAliasName(String aliasName) {
if(aliasName != null)
this.aliasName = DAOUtil.convertToDBString(aliasName);
}
@OneToMany(fetch=FetchType.LAZY, cascade = {CascadeType.ALL})
@JoinColumn(name="IDAIRLINE")
public Set<AirlineFlight> getAirlineFlights() {
return airlineFlights;
}
public void setAirlineFlights(Set<AirlineFlight> flights) {
this.airlineFlights = flights;
}
}
AirlineFlights:
@Entity
@Table(name="AirlineFlight")
public class AirlineFlight {
private Integer idAirlineFlight;
private Airline airline;
private String flightNumber;
public AirlineFlight(){}
public AirlineFlight(Airline airline, String flightNumber) {
setAirline(airline);
setFlightNumber(flightNumber);
}
@Id
@GeneratedValue(generator="identity")
@GenericGenerator(name="identity", strategy="identity")
@Column(name="IDAIRLINEFLIGHT", nullable=false)
public Integer getIdAirlineFlight() {
return idAirlineFlight;
}
private void setIdAirlineFlight(Integer idAirlineFlight) {
this.idAirlineFlight = idAirlineFlight;
}
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="IDAIRLINE", nullable=false)
public Airline getAirline() {
return airline;
}
public void setAirline(Airline airline) {
this.airline = airline;
}
@Column(name="FLIGHTNUMBER", nullable=false)
public String getFlightNumber() {
return flightNumber;
}
public void setFlightNumber(String flightNumber) {
this.flightNumber = DAOUtil.convertToDBString(flightNumber);
}
}
BEARBEITEN:
Datenbankschema:
AirlineFlights hat die IDAirline als ForeignKey und Airline hat keine IDAirlineFlights. Dies macht AirlineFlights als Eigentümer / identifizierende Einheit?
Theoretisch möchte ich, dass die Fluggesellschaft Eigentümerin von airlineFlights ist.
quelle
@ManyToOne
Seite, richtig?MappedBy-Signale halten den Ruhezustand fest, dass sich der Schlüssel für die Beziehung auf der anderen Seite befindet.
Dies bedeutet, dass, obwohl Sie zwei Tabellen miteinander verknüpfen, nur eine dieser Tabellen eine Fremdschlüsseleinschränkung für die andere hat. Mit MappedBy können Sie weiterhin eine Verknüpfung von der Tabelle, die die Einschränkung enthält, zur anderen Tabelle herstellen.
quelle
mappedBy
eine bidirektionale Definition verwenden, anstatt sie einzuschränken (mit Foreign_key-Einschränkungen auf jeder Seite)?mappedby
spricht für sich selbst, es sagt dem Ruhezustand, dieses Feld nicht zuzuordnen. Es wird bereits von diesem Feld zugeordnet [name = "field"].Feld ist in der anderen Entität
(name of the variable in the class not the table in the database)
..Daher müssen wir den Ruhezustand anweisen, das Mapping nur auf einer Seite durchzuführen und zwischen ihnen zu koordinieren.
quelle
mappedBy
undinversedBy
. Andere ORMs verwenden viel intelligenterbelongsToMany
,hasMany
Attribute.mappedby = "Objekt einer Entität derselben Klasse, die in einer anderen Klasse erstellt wurde"
Hinweis: -Mapped by kann nur in einer Klasse verwendet werden, da eine Tabelle eine Fremdschlüsseleinschränkung enthalten muss. Wenn die Zuordnung von auf beiden Seiten angewendet werden kann, wird der Fremdschlüssel aus beiden Tabellen entfernt, und ohne Fremdschlüssel besteht keine Beziehung zwischen zwei Tabellen.
Hinweis: - Es kann für folgende Anmerkungen verwendet werden: - 1. @ OneTone 2. @ OneToMany 3. @ ManyToMany
Hinweis --- Es kann nicht für folgende Anmerkungen verwendet werden: - 1. @ ManyToOne
Eins zu eins: - Führen Sie auf jeder Seite des Mappings durch, aber nur auf einer Seite. Dadurch wird die zusätzliche Spalte der Fremdschlüsseleinschränkung in der Tabelle entfernt, auf die die Klasse angewendet wird.
Zum Beispiel. Wenn wir die Zuordnung von in der Employee-Klasse auf das Mitarbeiterobjekt anwenden, wird der Fremdschlüssel aus der Employee-Tabelle entfernt.
quelle
Tabellenbeziehung vs. Entitätsbeziehung
In einem relationalen Datenbanksystem sieht eine
one-to-many
Tabellenbeziehung wie folgt aus:Beachten Sie, dass die Beziehung auf der Spalte Fremdschlüssel (z. B.
post_id
) in der untergeordneten Tabelle basiert .Es gibt also eine einzige Quelle der Wahrheit, wenn es darum geht, eine
one-to-many
Tabellenbeziehung zu verwalten.Wenn Sie nun eine bidirektionale Entitätsbeziehung verwenden, die der
one-to-many
zuvor gesehenen Tabellenbeziehung zugeordnet ist:Wenn Sie sich das obige Diagramm ansehen, sehen Sie, dass es zwei Möglichkeiten gibt, diese Beziehung zu verwalten.
In der
Post
Entität haben Sie diecomments
Sammlung:In der
PostComment
wird diepost
Zuordnung wie folgt zugeordnet:Da es zwei Möglichkeiten gibt, die Fremdschlüsselspalte darzustellen, müssen Sie definieren, welche Quelle die Wahrheit ist, wenn es darum geht, die Zuordnungsstatusänderung in die entsprechende Änderung des Fremdschlüsselspaltenwerts zu übersetzen.
MappedBy
Das
mappedBy
Attribut gibt an, dass die@ManyToOne
Seite für die Verwaltung der Fremdschlüsselspalte verantwortlich ist. Die Auflistung wird nur zum Abrufen der untergeordneten Entitäten und zum Kaskadieren von Statusänderungen der übergeordneten Entität an untergeordnete Entitäten verwendet (z. B. sollte durch Entfernen der übergeordneten Entitäten auch die untergeordneten Entitäten entfernt werden).Synchronisieren Sie beide Seiten einer bidirektionalen Zuordnung
Selbst wenn Sie das
mappedBy
Attribut definiert haben und die untergeordnete@ManyToOne
Zuordnung die Spalte Fremdschlüssel verwaltet, müssen Sie jetzt beide Seiten der bidirektionalen Zuordnung synchronisieren.Der beste Weg, dies zu tun, besteht darin, diese beiden Dienstprogrammmethoden hinzuzufügen:
Die Methoden
addComment
und stellenremoveComment
sicher, dass beide Seiten synchronisiert sind. Wenn wir also eine untergeordnete Entität hinzufügen, muss die untergeordnete Entität auf die übergeordnete Entität verweisen, und die übergeordnete Entität sollte das untergeordnete Element in der untergeordneten Sammlung enthalten.quelle
Sie haben mit der ManyToOne-Zuordnung begonnen und dann die OneToMany-Zuordnung auch für die biDirektionale Methode festgelegt. Dann müssen Sie auf der OneToMany-Seite (normalerweise Ihre übergeordnete Tabelle / Klasse) "mappedBy" erwähnen (die Zuordnung erfolgt durch und in der untergeordneten Tabelle / Klasse), damit im Ruhezustand keine EXTRA-Zuordnungstabelle in der Datenbank erstellt wird (wie TableName = parent_child).
quelle