Обработка агрегатов в службе или DAO - PullRequest
3 голосов
/ 01 декабря 2011

Очень популярная дискуссия о разработке правильных DAO всегда заканчивается чем-то вроде «DAO должны выполнять только простые операции CRUD».

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

Предположим, у меня есть следующий интерфейс DAO:

public interface UserDao {
    public User getByName(String name);
}

А вот объекты, которые он возвращает:

public class Transaction {
    public int amount;
    public Date transactionDate;
}

public class User {
    public String name;
    public Transaction[] transactions;
}

Прежде всего, я считаю, что DAO возвращает стандартный объект Value, если все, что он делает, это операции CRUD.

Так что теперь я смоделировал DAO, чтобы вернуть что-то на основе отношений хранилища данных. Это правильно? Что если у меня есть более сложный граф объектов?

Обновление: Я предполагаю, что в этой части я спрашиваю, должно ли быть смоделировано возвращаемое значение DAO, будь то VO, DTO или как вы хотите его назвать, после представление данных? Или я должен, скажем, ввести новый DAO для получения транзакций пользователя и для каждого пользователя, вызванного UserDAO, вызвать вызов TransactionDAO для их получения?

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

Но что, если количество транзакций пользователя исчисляется десятками тысяч? Это негативно скажется на производительности приложений. Было бы неправильно вводить новый метод в DAO, который выполняет агрегацию?

Конечно, это может быть предположение, что DAO поддерживается базой данных, где я могу написать простой запрос SELECT SUM (). И если реализация DAO изменится, скажем, на простой файл или что-то в этом роде, мне все равно придется выполнить агрегацию в памяти.

Так какая же здесь лучшая практика?

1 Ответ

0 голосов
/ 01 декабря 2011

Я использую DAO в качестве слоя перевода: читайте объекты БД, создавайте бизнес-объекты на стороне Java и наоборот. Иногда для сохранения или создания бизнес-объекта может использоваться пара вызовов. Для приведенного примера я бы сделал два вызова: один для информации о пользователе, один для списка транзакций пользователя. Стоимость звонка за дополнительную базу данных. Я не боюсь сделать дополнительный звонок, если я использую пул соединений, и я не повторяю вычисления. Отдельные вызовы проще в использовании (распаковка массива составных типов из вызова jdbc непроста и, как правило, требует проприетарного объекта соединения) и предоставляет повторно используемые компоненты. Допустим, вы хотели, чтобы пользовательский объект был для экрана входа в систему: вы можете использовать тот же пользовательский dao и вам не нужно извлекать данные транзакции.

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

Безопасно ли считать, что дао отображается в реляционный БД? Если это то, с чего вы начинаете, я бы поспорил, что резервное хранилище данных останется реляционным БД. Иногда бывает много суеты и беспокойства, чтобы это было общим, и, если можно, отлично. Но мне кажется, что просто изменить тип реляционных БД в задней части гораздо дальше, чем могло бы пойти большинство приложений (не говоря уже о переходе на нереляционный магазин, такой как плоский файл).

...