@drKR

Как в слое DAO при помощи JDBC получить корректную сущность?

Есть программа с сущностями Author, Book, Genre которые связанны друг с другом как многие ко многим.
В базе данных существуют таблицы для их хранения и обеспечения свяpи между ними.

В java коде:
spoiler
public class Author {
	...
    private List<Book> books;
    private List<Genre> genres;
}

public class Book {
	...
    private List<Author> authors;
    private List<Genre> genres;
}

public class Genre {
	...
    private List<Author> authors;
    private List<Book> books;
}

В базе данных:
spoiler
CREATE TABLE author (
	`author_id` INT NOT NULL UNIQUE PRIMARY KEY AUTO_INCREMENT,
	...
);

CREATE TABLE book (
	`book_id` INT NOT NULL UNIQUE PRIMARY KEY AUTO_INCREMENT,
	...
);

CREATE TABLE genre (
	`genre_id` INT NOT NULL UNIQUE PRIMARY KEY AUTO_INCREMENT,
	...
);

CREATE TABLE author_book (
	`author_id` INT NOT NULL REFERENCES author(author_id),
	`book_id` INT NOT NULL REFERENCES book(book_id),
		UNIQUE KEY `author_book_unique_id` (`author_id`,`book_id`)
);

CREATE TABLE author_genre (
	`author_id` INT NOT NULL REFERENCES author(author_id),
	`genre_id`  INT NOT NULL REFERENCES genre(genre_id),
		UNIQUE KEY `author_genre_id` (`author_id`,`genre_id`)
);


CREATE TABLE book_genre (
	`book_id` INT NOT NULL REFERENCES book(book_id),
	`genre_id`  INT NOT NULL REFERENCES genre(genre_id),
		UNIQUE KEY `book_genre_id` (`book_id`,`genre_id`)
);

К примеру сервис слой вызывает метод getAuthor(id) в слое DAO.
У возвращаемого автора должны быть проинициализированы поля books и genres. Там должны находится
книги которые писал автор и жанры в которых он работал. В свою очередь у каждой книги должна быть
информация в каком жанре она написана и какие у нее авторы. А жанр должен хранить список книг относящихся к нему
и авторов работающих в данном жанре.

Таким образом возвращая автора сервис слою мы должны загрузить кучу информации из базы данных, и это будет не один запрос, а очень много.
Вопрос верна ли данная архитектура(просматривая код примеров hibernate вижу что хранятся именно сущности, а не их ид).
Но как реализовать этот вариант в JDBC, на практике не понятно. Если архитектурно это правильно подскажите как это реализовать!

Или наоборот нужно в сущности хранить не ссылку на другую сущность, а информацию о id другой сущности.

public class Author {
...
private List booksID;
private List genresID;
}

В дальнейшем код будет переводится на hibernate но в данный момент необходим ответ только с использованием JDBC и Java, без использования hibernate и прочих фреймворков.

UPD для интересующихся этой же темой может быть полезно посмотреть :
https://ru.stackoverflow.com/questions/1127662/%D0...
  • Вопрос задан
  • 206 просмотров
Пригласить эксперта
Ответы на вопрос 1
azerphoenix
@azerphoenix Куратор тега Java
Java Software Engineer
Добрый день.
В Hibernate при использовании аннотации ManyToMany создаются 3 таблицы. 2 таблицы для самих сущностей, где хранится информация и 1 таблица с маппингами, где хранятся id сущностей. В данном случае с вашими таблицами все в порядке.

У возвращаемого автора должны быть проинициализированы поля books и genres. Там должны находится
книги которые писал автор и жанры в которых он работал. В свою очередь у каждой книги должна быть
информация в каком жанре она написана и какие у нее авторы. А жанр должен хранить список книг относящихся к нему
и авторов работающих в данном жанре.


При такой работе (при сериализации данных или при вызове метода toString) вы столкнетесь с рекурсией. Например, у автора есть список книг, у книг есть авторы и каждый раз будут вызваны методы, которые будут запрашивать то авторов, которые написали эту книгу, то книги, которые был написаны этим автором. Эти вопросы при работе с Jackson решаются при помощи аннотаций JsonManagedReference & JsonBackReference или JsonIgnore. Для lombok для исключения из toString можно использовать ToString.Ignore.

Таким образом возвращая автора сервис слою мы должны загрузить кучу информации из базы данных, и это будет не один запрос, а очень много.

Если мы говорим о hibernate (jpa), то там есть таккие параметры, как FetchType (EAGER & LAZY). Так вот, если LAZY, то информация из List будет загружена только при обращении к ней. В случае EAGER информация загружается при первом же обращении к сущности.
https://thorben-janssen.com/entity-mappings-introd...

Возможно, что эта ссылка будет полезна для вас:
https://stackoverflow.com/questions/21956042/mappi...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы