Одной из целей в программировании является представление моделей из реального мира. Очень часто приложению необходимо моделировать отношения между сущностями. В последней статье об ассоциациях Hibernate я описал правила настройки отношений «один к одному». Сегодня я собираюсь показать вам, как настроить двунаправленную связь « один ко многим » и « многие ко одному ». Этот пример будет основан на предыдущих уроках Hibernate .
В начале я должен сказать, что мой пример кода будет основан на простой ситуации. Давайте представим футбольную лигу. В каждой лиге есть команды, и в команде могут играть несколько игроков. Итак, итог таков: одна команда имеет много игроков, один игрок может играть за одну команду. Таким образом, мы получаем очевидные отношения « один ко многим » и « многие к одному ».
Я использую MySQL в качестве базы данных в этом примере. Вот скрипты для создания таблиц:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
CREATE TABLE `teams` ( `id` int(6) NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;CREATE TABLE `players` ( `id` int(6) NOT NULL AUTO_INCREMENT, `lastname` varchar(20) NOT NULL, `team_id` int(6) NOT NULL, PRIMARY KEY (`id`), KEY `player's team` (`team_id`), CONSTRAINT `player's team` FOREIGN KEY (`team_id`) REFERENCES `teams` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; |
Следующим шагом является создание POJO:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
import java.util.Set;import javax.persistence.*;@Entity@Table(name = 'teams')public class Team { @Id @GeneratedValue private Integer id; private String name; @OneToMany(mappedBy='team', cascade=CascadeType.ALL) private Set players; public Team(String name) { this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set getPlayers() { return players; } public void setPlayers(Set players) { this.players = players; }} |
Я использовал @OneToMany, потому что в одной команде может быть много игроков. В следующем POJO ассоциация будет @ManyToOne, так как многие игроки могут играть за одну команду.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
import javax.persistence.*;@Entity@Table(name = 'players')public class Player { @Id @GeneratedValue private Integer id; private String lastname; @ManyToOne @JoinColumn(name = 'team_id') private Team team; public Player(String lastname) { this.lastname = lastname; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public Team getTeam() { return team; } public void setTeam(Team team) { this.team = team; }} |
Здесь я указываю столбец ( team_id ), который будет объединен со стороны владельца ( команды ). Обратите внимание, что я не объявляю поле team_id в POJO. Если мне нужно сменить команду для игрока, мне просто нужно использовать сеттер setTeam (Team team) .
После того, как POJO были объявлены, я могу продемонстрировать, как их сохранить:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
... public static void main(String[] args) { SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session = sessionFactory.openSession(); session.beginTransaction(); Team team = new Team('Barcelona'); Set players = new HashSet (); Player p1 = new Player('Messi'); Player p2 = new Player('Xavi'); p1.setTeam(team); p2.setTeam(team); players.add(p1); players.add(p2); team.setPlayers(players); session.save(team); session.getTransaction().commit(); session.close(); }... |
Результат выполнения кода:
Hibernate: вставить в команды (имя) значения (?)
Hibernate: вставить в игроков (фамилия, team_id) значения (?,?)
Hibernate: вставить в игроков (фамилия, team_id) значения (?,?)
Вот и все, в этом уроке я продемонстрировал, как настроить двунаправленную связь « один ко многим » и « один ко многим ». Я не вижу смысла в том же учебнике с примером однонаправленной ассоциации. Потому что у Hibernate есть свои лучшие практики:
Однонаправленные ассоциации сложнее запрашивать. В большом приложении почти все ассоциации должны быть ориентированы в обоих направлениях в запросах.
Ссылка: двунаправленная ассоциация @OneToMany / @ManyToOne от нашего партнера по JCG Алекса Фрузенштейна в блоге заметок Фрузенштейна .