5.1 Ulike former for en-til-en kommunikasjon
Det er et annet interessant og ganske spesifikt tilfelle av et forhold mellom to Entity-klasser - et en-til-en-forhold.
Jeg kaller dette tilfellet veldig spesifikt, da det handler mer om Java-objekter enn en database. I databasen er det bare to alternativer for forholdet mellom tabeller:
- Tabellraden inneholder en lenke til ID-en til en annen tabell.
- Tjenestetabellen brukes for mange-til-mange-relasjoner.
Når det gjelder enhetsklasser, kan det være alternativer som er beskrevet med flere merknader:
- @En del av
- Ensidig OneToOne
- Bilateral OneToOne
- @MapsId
Nedenfor vil vi vurdere de mest populære av dem.
5.2 Innebygd
Forresten, vi har allerede vurdert det enkleste en-til-en@Embedded
kommunikasjonsalternativet - dette er en merknad . I dette tilfellet har vi to klasser lagret i samme tabell i databasen.
La oss si at vi ønsker å lagre brukerens adresse i UserAddress- klassen :
@Embeddable
class UserAddress {
@Column(name="user_address_country")
public String country;
@Column(name="user_address_city")
public String city;
@Column(name="user_address_street")
public String street;
@Column(name="user_address_home")
public String home;
}
Da trenger vi bare å legge til et felt med denne adressen til brukerklassen :
@Entity
@Table(name="user")
class User {
@Column(name="id")
public Integer id;
@Embedded
public UserAddress address;
@Column(name="created_date")
public Date createdDate;
}
Hibernate vil gjøre resten: dataene vil bli lagret i én tabell, men når du skriver HQL-spørringer, må du operere på klassefelt.
Eksempel på HQL-søk:
select from User where address.city = 'Paris'
5.3 Ensidig OneToOne
Se for deg situasjonen nå: vi har en kildetabellansatt og en oppgave som refererer til ansatt. Men vi vet med sikkerhet at maksimalt én oppgave kan tildeles én bruker. Deretter kan vi bruke kommentaren til å beskrive denne situasjonen @OneToOne
.
Eksempel:
@Entity
@Table(name="task")
class EmployeeTask {
@Column(name="id")
public Integer id;
@Column(name="name")
public String description;
@OneToOne
@JoinColumn(name = "employee_id")
public Employee employee;
@Column(name="deadline")
public Date deadline;
}
Hibernate vil sørge for at ikke bare én oppgave har én bruker, men også at én bruker kun har én oppgave. Ellers er denne saken praktisk talt ikke forskjellig fra @ManyToOne
.
5.4 Bilateral OneToOne
Det forrige alternativet kan være litt upraktisk, fordi du ofte vil tilordne en ansatt ikke bare til en oppgave, men også tilordne en oppgave til en ansatt.
For å gjøre dette kan du legge til EmployeeTask-feltet i Employee-klassen og gi den de riktige merknadene.
@Entity
@Table(name="employee")
class Employee {
@Column(name="id")
public Integer id;
@OneToOne(cascade = CascadeType.ALL, mappedBy="employee")
private EmployeeTask task;
}
Viktig!Ansatttabellen har ikke et oppgave-id- felt , i stedet brukes feltet ansatt-id i oppgavetabellen til å etablere en relasjon mellom tabeller .
Å etablere en forbindelse mellom objekter ser slik ut:
Employee director = session.find(Employee.class, 4);
EmployeeTask task = session.find(EmployeeTask.class, 101);
task.employee = director;
director.task = task;
session.update(task);
session.flush();
For å fjerne koblingen, må koblingene også fjernes fra begge objektene:
Employee director = session.find(Employee.class, 4);
EmployeeTask task = director.task;
task.employee = null;
session.update(task);
director.task = null;
session.update(director);
session.flush();
GO TO FULL VERSION