Как правильно структурировать Java-приложение для управления базами данных?

#java #sql #database #oop

#java #sql #База данных #ооп

Вопрос:

Во-первых, простите меня, если я не кажусь последовательным, поскольку я все еще новичок и не совсем уверен, как сформулировать некоторые из этих вещей.

Я создаю систему управления библиотеками на JavaFX, используя SQLite для базы данных. Я ознакомился с тем, как обрабатываются SQL-запросы в Java, и мое приложение работает. Однако сейчас я перестраиваю приложение, чтобы оно соответствовало принципам ООП. Мой вопрос заключается в том, какой подход я должен использовать с методами, которые включают запросы к базе данных.

В обычном приложении, я думаю, я бы написал эти методы в соответствующем классе — скажем, например, метод просмотра информации о книге будет содержаться в классе «Book». Но здесь это потребовало бы создания нового подключения к базе данных или передачи текущего, и моя интуиция подсказывает мне, что это неправильный способ сделать это. Должен ли я вместо этого иметь отдельный класс для хранения соединения, а также обрабатывать все операции с базой данных? Каков правильный способ сделать это?

Комментарии:

1. Я считаю, что весь SQL переходит в отдельный класс SQL. База данных заполняет модель приложения простыми объектами Java с использованием SQL. Модель приложения отображается в представлении и обновляется классами контроллера. Обновленная модель приложения обновляет базу данных с помощью SQL.

Ответ №1:

Проблема в том, что реляционные таблицы плохо сопоставляются с объектами. Как:

 SELECT author.name, book.title,
book.lang = author.native_tongue AS nativeWritten
FROM book LEFT JOIN author ON author.id = book.author;
  

перевести в объекты?

Это не так.

Если вы хотите отказаться от возможностей SQL везде или, по крайней мере, в большинстве мест, и в основном делать SELECT * FROM book WHERE unid = 1; и не идти дальше, вы можете сделать банальное упрощение, что существует класс типа Book, и он соответствует таблице book и может разумно инкапсулировать все, что вы, возможно, захотите сделатьдля БД, которые вообще связаны с книгами, хорошо, хорошо, вы могли бы заново изобрести колесо и переписать все JPA / Hibernate, или вы просто используете это.

В качестве альтернативы вам следует изучить JDBI или JOOQ, которые отказываются от идеи, что «таблица в db == class в java», и более ориентированы на SQL. В них есть всевозможные учебные пособия и руководства, которые точно покажут вам, как их использовать.

Если вы действительно настаиваете на том, чтобы заново изобрести это колесо: передача объекта connection не является безумием. Это то, что необходимо для выполнения заявленной задачи. Что-то вроде:

 public static Book getById(Connection db, int unid) throws SQLException { ... }
  

это один из способов. Немного более сложный способ, облегчающий тестирование, может быть чем-то вроде:

 public class DbBridge {
    public Book getById(int unid) throws SQLException { ... }
}
  

позволяет вам абстрагироваться от представления о том, как выполнять работу, но … тогда это означает, что вы передаете объект DbBridge всему.

Общий принцип «у меня есть эта несколько сложная концепция с сохранением состояния, которая мне нужна во многих местах, это почти как конфигурация» является распространенной проблемой. Это то, что пытаются решить фреймворки «внедрения зависимостей», такие как dagger. Вы можете либо изобрести это колесо, либо просто одно из них. Если вы хотите изобрести что-то новое, посмотрите, как работают эти проекты, чтобы у вас было представление о том, какие решения доступны.

ПРИМЕЧАНИЕ: Если вы выбрали SQLite, потому что он «lite», это не так. Не с точки зрения Java: для его использования вам нужен собственный исполняемый файл. Гораздо более простой и легкий подход заключается в использовании встроенного в Java файлового движка базы данных, такого как H2 или JavaDB. Используйте SQLite из Java, только если вам нужно, чтобы эта база данных была доступна из приложений, отличных от Java, или вы более или менее вынуждены использовать ее, например, потому что вы пишете приложения для Android. С точки зрения сложности, SQLite примерно так же сложен, как полноценный postgres или что-то еще, с точки зрения Java.

Комментарии:

1. Спасибо за ответ. Итак, если я правильно понял, вы говорите, что плохо сочетать SQL с объектно-ориентированными программами, и мне следует вообще избегать ORM и вместо этого заглядывать в JDBI или JOOQ?

2. Лучше всего рассматривать ORM как ORM и полностью забыть о SQL, если вы это сделаете. ORM — это инструмент, который принимает объекты и сохраняет их, а также предоставляет вам уровень запросов для извлечения их обратно, где бы они ни находились. Забудьте о SQL. Забудьте о настройке запросов. Тогда ORM (hibernate, JPA и т. Д.) Являются фантастическими. Как только вы видите это как способ «сделать SQL» из java, он начинает становиться чертовски дырявой абстракцией. (Вы МОЖЕТЕ настроить эти запросы и вручную написать для них некоторый SQL, но теперь вы только что значительно усложнили свою кривую обучения и отказались от независимости от БД. Упс).