Очень простой вопрос о моделировании данных - PullRequest
1 голос
/ 23 июля 2011

Предположим, мне нужно разработать простую модель данных на Java для Order, которая содержит Order Items. Похоже, что Order должен содержать ссылку на коллекцию Order Items Что теперь, если Order и Order Items хранятся в базе данных? Должен ли Order по-прежнему содержать ссылку на коллекцию, или вместо него должна быть указана простая функция retrieveItemsByOrderId?

Ответы [ 2 ]

2 голосов
/ 23 июля 2011

А что если заказ и элементы заказа хранятся в базе данных?Должен ли Order по-прежнему содержать ссылку на коллекцию или вместо него должна быть предоставлена ​​простая функция retrieveItemsByOrderId?

Это будет зависеть от того, как ваша объектная модель используется слоем постоянства для сопоставления классов с базой данных.столы.Если вы используете Hibernate / JPA / EclipseLink / Toplink или аналогичную инфраструктуру ORM, у вас в классе Order будет просто метод getter, который будет возвращать коллекцию OrderItem экземпляров.Частичное представление кода будет выглядеть следующим образом:

class Order
{

    private long id;
    private Set<OrderItem> orderItems;
    ...
    public Set<OrderItem> getOrderItems()
    {
        return orderItems;
    }

    public void setOrderItems(Set<OrderItem> orderItems)
    {
        this.orderItems = orderItems;
    }
}

class OrderItem
{
    private Order order;
    ...
    public Order getOrder()
    {
        return order;
    }

    public void setOrder(Order order)
    {
        this.order = order;
    }
}

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

  • каждый экземпляр класса Order содержит Id, который может быть естественным ключом (или может быть сгенерированным).
  • , вызываяМетод getOrderItems приведет к Set элементов заказа, связанных с заказом, который будет возвращен.Обратите внимание, что большинство ORM лениво извлекают коллекции, поэтому вам нужно понять еще несколько понятий, таких как работа с управляемыми и отсоединенными сущностями, чтобы фактически заставить это работать;вам может потребоваться написать службу приложений, которая выполнит работу по объединению отдельных сущностей, а затем извлечет коллекцию.

В одном из комментариев говорится, что нет необходимости ссылаться на Order из OrderItem класс.Это приведет к однонаправленным отношениям вместо двунаправленных.Вы можете использовать однонаправленные отношения в большинстве сред ORM, но учтите следующее:

  • Было бы нетривиально поддерживать ссылочную целостность (используя внешние ключи) для однонаправленных отношений;это будет зависеть от вашей структуры ORM.Некоторые платформы ORM могут позволить вам не иметь ссылки на Order из OrderItem без каких-либо дополнительных усилий с вашей стороны, в то время как другие могут потребовать от вас использования таблицы Join.Если вы сохраняете граф объектов в базе данных, необходимо знать, какой OrderItem соответствует Order;удалив ссылку из OrderItem, вы будете вынуждены отобразить эту информацию в другом месте, в другом объекте, что обычно приводит к другой таблице;это таблица соединения, о которой упоминалось ранее.
  • Однонаправленные связи достаточны для большинства применений.Если Order отвечает за доступ к экземплярам OrderItem, то вам не нужны двунаправленные отношения.Но если вам нужно получить доступ к Order для OrderItem, то вам понадобятся двунаправленные отношения.Я бы предложил прочитать шаблон взаимной регистрации , чтобы вы всегда могли поддерживать ссылочную целостность независимо от операций мутации, выполняемых в классах Order или OrderItem в таком случае.Без этого паттерна вы почти всегда будете видеть неопределенные, необъяснимые и неправильные графы объектов, приводящие к несовместимому состоянию базы данных.

Если вы не используете ORM или не собираетесь,тогда это будет зависеть от доступа к экземплярам OrderItem;Короче говоря, это зависит от того, как вы пишете свой постоянный слой.Если вы используете шаблон DAO, то решением проблемы будет добавление нового метода retrieveItemsByOrderId в интерфейс DAO.

1 голос
/ 23 июля 2011

Я думаю, вам следует сохранить ссылку на коллекцию OrderItem в классе модели Order. Затем вы можете реализовать метод getOrderItems (), который извлекает элементы из базы данных на основе идентификатора заказа.

Этот запрос должен выполняться только в том случае, если вам нужен доступ к позициям заказа (поиск LAZY LOADING), а не каждый раз, когда вы загружаете сущность Order из БД.

Использование ссылки на коллекцию OrderItem в вашем классе модели Order будет использовать ваше приложение на тот случай, если вам потребуется дважды получить доступ к элементам заказа в одном и том же потоке запрос-ответ.

Скелет метода getOrderItems () будет выглядеть так:

public List<OrderItem> getOrderItems(){
    if(this.orderItems==null)
        // perform the query
        // set the this.orderItems values
    }
    return this.orderItems
}
...