#java #spring-boot #hibernate #spring-data-jpa
#java #весенняя загрузка #впасть в спящий режим #spring-data-jpa
Вопрос:
У меня уже есть модель пользователя. Теперь я создал модель фильма, мое требование состоит в том, что всякий раз, когда какой-либо существующий пользователь собирается добавить какой-либо фильм, в это время user_id и movie_id будут храниться в таблице movie_added_by.
Здесь пользовательская модель должна сопоставить один ко многим с movie_added_by, и аналогично фильм будет сопоставлен с movie_added_by.
Для лучшего понимания вы можете обратиться к схеме базы данных.
Я действительно не знаю, как я могу это сделать, используя аннотацию гибернации
Модель пользователя выглядит следующим образом:
@Getter
@Setter
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id", unique = true, nullable = false)
private Integer user_id;
private String name;
}
Модель фильма выглядит следующим образом:
@Getter
@Setter
public class Movie implements Serializable
{
private static final long serialVersionUID = -6790693372846798580L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "movie_id", unique = true, nullable = false)
private Integer movie_id;
private String movie_name;
}
Ответ №1:
Вероятно, вы хотите создать связь @ManyToMany между объектами. Есть 2 способа сделать это (с помощью промежуточной таблицы, созданной явно или с помощью гибернации.
При простом подходе ваши объекты будут выглядеть следующим образом:
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id", unique = true, nullable = false)
private Integer user_id;
private String name;
@ManyToMany(cascade = CascadeType.Persist)
@JoinTable(name="user_movie",
joinColumns = {@JoinColumn(name="user_id")},
inverseJoinColumns = {@JoinColumn(name="movie_id)})
private Set<Movie> movies = new HashSet<>();
}
public class Movie implements Serializable
{
private static final long serialVersionUID = -6790693372846798580L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "movie_id", unique = true, nullable = false)
private Integer movie_id;
private String movie_name;
@ManyToMany(cascade = CascadeType.Persist, mappedBy = "movies" //field from the user class responsible for mapping)
private Set<User> users = new HashSet<>()
}
Итак, в основном здесь вы указываете Hibernate создать промежуточную таблицу и сохранить там соответствующие идентификаторы этих 2 объектов. Пара других заметок здесь:
a) возможно, вам захочется изменить тип переменной id с Integer на Long на случай, если ваши объекты растут;
б) Если вы аннотировали столбец с помощью @Id, вам не нужно использовать unique= true и nullable = false в аннотации столбца;
c) помните о реализации конструктора без аргументов;
d) не забудьте исключить файлы отношений из методов equals(), hashCode() и toString();
Существует другой способ, при котором вы явно создаете модель для связей, сохраняемых в таблице. Это может пригодиться, когда выяснится, что вам нужно хранить больше данных в «таблице отношений». В этом случае ваши объекты будут выглядеть следующим образом:
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id", unique = true, nullable = false)
private Integer user_id;
private String name;
@OnetToMany(cascade = CascadeType.PERSIST, mappedBy = "user")
private Set<AddedMovie> addedMovies = new HashSet<>()
}
public class Movie implements Serializable
{
private static final long serialVersionUID = -6790693372846798580L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "movie_id", unique = true, nullable = false)
private Integer movie_id;
private String movie_name;
@OneToMany(cascade = CascadeType.PERSIST, mappedBy = "movie")
private Set<AddedMovie> moviesAddedByUser = new HashSet<>();
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
public class AddedMovie{
@Id
@GeneratedValue
private Long id;
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "user_id")
private User user;
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "movie_id")
private Movie movie;
// sine this entity has now its own lifecycle, you can add more fields here
private Integer rating;
private LocalDateTime movieAddedOn;
}
Комментарии:
1. Спасибо за подробную информацию. Я проверю и сообщу yiu
2. да, это работает, просто внесите некоторые незначительные изменения