Это хороший подход для пользовательского объектно-реляционного отображения в Java? - PullRequest
0 голосов
/ 12 декабря 2010

Я разрабатываю пример Java-приложения, использующего встроенную схему Oracle «HR». Я хотел бы рассматривать строки таблицы как объекты Java. Одна из таблиц в схеме управления персоналом, СОТРУДНИКИ, ссылается на себя. У него есть столбец MANAGER_ID, который содержит (если не NULL) внешний ключ для другой строки в таблице EMPLOYEES.

В объектно-ориентированных терминах проблема заключается в том, как получить доступ к данному менеджеру объекта Employee (который является другим объектом Employee). Стремительная загрузка не кажется хорошим решением, поскольку у данного менеджера объекта Employee также может быть менеджер и так далее. Количество объектов, которые охотно загружаются в этой ситуации, не ограничено.

Пока я решил загружать поле MANAGER_ID при создании объекта Employee. Затем, когда запрашивается объект Employee для менеджера сотрудника (с помощью метода getManager()), последний будет загружен лениво. В коде:

public class Employee
{
    private int id;
    private int managerId;
    private Employee manager;

    public int getId()
    {
        return id;
    }

    public Employee getManager()
    {
        if(manager == null && managerId > 0)
        {
            // Lazy loading!
        }

        return manager;
    }

    public void setManager(Employee manager)
    {
        this.manager = manager;
        this.managerId = manager.getId();
    }
}

Так это хороший подход? Единственная проблема, которую я имею с этим, состоит в том, как осуществить ленивую загрузку. Казалось бы, объект Employee нуждается в ссылке на его экземпляр - предположительно, это было бы то же самое, что и экземпляр его объекта Employee.

Кроме того, я знаю, что мог бы просто использовать одну из многих платформ ORM, вместо того, чтобы развернуть свою собственную, но я делаю это самостоятельно, чтобы лучше понять базовый процесс (ы).

РЕДАКТИРОВАТЬ: Просто чтобы прояснить, моя архитектура для этого усилия (как он есть) вообще не включает Java EE. Это архитектура Java SE, где клиент взаимодействует с сервером через простой RMI.

Кроме того, приведенному выше классу Employee явно требуется ссылка на DAO для выполнения отложенной загрузки. Тем не менее, я не считаю это тесно связанным, потому что:

  1. объект Employee может содержать ссылку на абстрактный интерфейс, который реализует DAO; и / или
  2. объект Employee может содержать ссылку на объект сервера, который, в свою очередь, содержит (частную) ссылку на DAO.

Обратите внимание, что в случае # 2 объект сервера, на который ссылается объект Employee, предположительно тот же, на который ссылается клиент.

1 Ответ

1 голос
/ 17 декабря 2010

Если вам известны другие ORM, почему бы не посмотреть, как они это делают? В частности, вам могут быть интересны ленивые загрузочные прокси Hibernate:

Hibernate создаст (во время выполнения, используя генерацию байт-кода) подкласс Employee, который инкапсулирует ссылку на еще не загруженный объект employee. Вызов любого метода (кроме getId()) в этом классе загружает указанный объект сотрудника, а затем делегирует ему.

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

void switchJobs(Employee e1, Employee e2) {
    Employee m1 = e1.getManager();  // doesn't load the manager!
    e1.setManager(e2.getManager()); // doesn't load the manager!
    e2.setManager(m1);
}

Кроме того, Hibernate не будет загружать один и тот же менеджер несколько раз в транзакции, а будет повторно использовать уже загруженный постоянный объект или ленивый загрузочный прокси. Это одновременно повышает производительность и согласованность вашей объектной модели, т. Е. Если несколько сотрудников совместно используют менеджера, а один сотрудник изменяет его, другой сотрудник увидит это изменение, и менеджеров можно сравнить с помощью ==.

...