Дизайн рабочего стола Java - MVC с Hibernate - PullRequest
1 голос
/ 29 февраля 2012

У меня есть несколько вопросов о дизайне моего Java-приложения. Программное обеспечение представляет собой настольное приложение, которое использует базу данных MySQL для хранения объектов различного типа (клиенты, сотрудники, документы). Каждый сотрудник имеет коллекцию клиентов, а каждый клиент содержит ряд документов. Вся структура загружается через Hibernate.

В настоящее время я использую эти четыре слоя для создания своего приложения

  • модель - объекты, содержащие данные, например, клиенты, сотрудники, ...
  • просмотров - просмотр для каждого действия (добавление клиента, создание документа, ...)
  • контроллер - каждое представление имеет свой собственный контроллер, который управляет одним или несколькими бизнес-объектами
  • бизнес-объекты - инкапсулировать логику действий в моделях (добавление customer = customerBO, добавление document = documentBO, ...)

Таким образом, когда пользователь теперь хочет добавить новый документ для клиента, контроллер представления клиента открывает новое - давайте назовем это - «окно документа», которое имеет свой собственный контроллер. Поскольку каждый документ должен принадлежать клиенту, я передаю его в качестве параметра. Но если я использую этот способ, я должен убедиться, что текущий сеанс гибернации открыт, а объект customer присоединен к сеансу для использования отложенной загрузки.

Итак, мой вопрос сейчас: есть ли более элегантный способ сделать это? Может быть, через сессионный класс, в котором хранится активный клиент или около того? Или в моей структуре вообще есть ошибка, которую я не видел?

Ответы [ 2 ]

0 голосов
/ 28 сентября 2013

Прежде всего, нередко делать что-то вроде этого:

DocumentService {
   public Document addDocument(int customerId) {
         Customer customer = session.getById(Customer.class, customerId);
         Document document = new Document();
         customer.getDocuments().add(document);
         session.update(customer);
         return document;
   }
}

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

Обычно я использую что-то вроде объекта CustomerInfo, который просто хранит некоторую связанную информацию, такую ​​как идентификатор, имя, может быть адрес и т. д. Обычно все, что часто не меняется, не критично, если пользователь видит устаревшие данные.(если это критично, часто используют событие / сообщения уведомления для обновления связанных информационных объектов).

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

Здесь есть только одно правило.Так как информация о клиенте может содержать устаревшие данные (какой-то другой пользователь изменил ее, вам нужно проверить достоверность. Вы можете ввести @Version к ней или сравнить соответствующие свойства, если они уже изменились. (Вы используете оптимистическое ведение журнала, так называемоепользовательская транзакция и две или более короткие транзакции базы данных).

Таким образом, в конце использования reattach нет ничего плохого.

Если у вас есть локальная встроенная база данных, и приложение, использующее hibernate, является единственным пользователем (однопользовательская настройка), вы можете рассмотреть возможность использования подхода единого сеанса, когда вы синхронизируете или объединяете каждый доступ к сеансу, чтобы избежать одновременных транзакций / доступа к базе данных.

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

Сводка

  • Использование присоединения не является неправильным,
  • Передача экземпляров сущностей в вашем приложении не является неправильной.
  • Помните: Hibernate обычно выдает выбор для обновления объекта и проверки того, что он представляет текущее состояние БД, которое видит текущий сеанс / транзакция (используйте @Version для снижения стоимости).
  • Вы можете использовать объекты CustomerInfo / DocumentInfo, чтобы избежать передачи экземпляров сущностей, чтобы уменьшить объем памяти и избежать перезагрузки.
  • Если производительность является проблемой, вы можете использовать идентификатор непосредственно для создания документа и послекоторые создают DocumentInfo, используя идентификатор, который вы получили из оператора вставки (SQL).Таким образом, вам не нужно перезагружать пользователя или создавать объект документа.Это только для того, чтобы уменьшить объем памяти и повысить производительность, но швы не должны вас беспокоить.

Мой совет, придерживайтесь повторного подключения, если у вас нет проблем с потреблением памяти.

0 голосов
/ 28 сентября 2013

Это может быть хорошим использованием для объекта передачи данных или объекта значения.Короче говоря, используйте в своем коде пользовательского интерфейса доступное только для чтения и не спящее представление для Заказчика, а не созданное в Hibernate.Этот объект Customer будет минимальной проекцией полноценного объекта Customer с вашего бэкэнда, который нужен вашему пользовательскому интерфейсу.В действительности вам, вероятно, не нужно намного больше, чем имя и идентификатор (конечно, зависит от вашего пользовательского интерфейса).

В прошлом я вводил «сервисный» интерфейс, который работает только в терминахиз этих объектов-значений, или DTO (эти термины не являются действительно взаимозаменяемыми, но я пытаюсь быть гибким, и концепция имеет значение: -)).

При сохранениичто-то сделано от имени клиента, позвоните в сервисный компонент service#attachDocument(customer.getCustomerId()) или как угодно.Этот компонент будет взаимодействовать с Hibernate для извлечения клиента и вызова customer.addDocument (documentId) (или того, что подходит для вашей модели).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...