В TypeORM нет репозиториев
Да, их там действительно нет. Вернее так, там есть что-то с названием «репозиторий», но это не репозиторий. Сейчас объясню почему.
Есть такой паттерн Data Mapper, у которого одного предназначение – гонять данные между доменной моделью и базой, тобишь создавать объекты с данными и сохранять их обратно в бд. Чем, собственно, TypeORM и занимается.
В представлении многих разработчиков это и есть репозиторий. Но у репозитория другая задача – имитировать коллекцию.
Мы же все знаем, что объекты передаются по ссылке. И, следовательно, получив ссылку на объект, можно этот объект мутировать как душе угодно. Но в случае с дата мапером эта идеальная картина мира рушится. Во-первых дата мапер при каждом вызове будет возвращать новый объект, а во-вторых он не будет знать ни о каких манипуляциях с объектом, и по итогу придется вызывать dataMapper.save
, чтобы записать состояние объекта в бд.
Кажется сверху дата мапера нужен еще один слой.
Тут в дело вступает репозиторий, который, напомню, имитирует коллекцию объектов. С правильным репозиторием достаточно написать следующий код, чтобы изменить состояние в бд:
Следующее так же будет верно:
Но как изменения попадут в базу? Дата мапер все равно не узнает, что объект мутировал. Кажется все таки нам нужен метод repository.save
…
У этой проблемы есть решение и имя ему Unit of Work – это еще один патерн, которые реализуется поверх предыдущих двух и следит за границами работы с объектами.
Код с Unit of Work, Repository и Data Mapper выглядел бы так:
По итогу работы этого кода, UoW подсчитал бы все изменения которые произошли в репозиториях и вызвал бы нужные методы у дата маппера, а в базе бы оказалось 2 записи: первая со старым пользователем, у которого обновилось имя, и вторая с новым Гришей.