Active Record (named by Fowler): an object wraps one database row. It carries both domain logic and its own saving code, as in user.save(). It is simple, but the domain is tied to the table structure.
Data Mapper: a separate layer moves data between in-memory objects and the database. The domain objects know nothing about how they are stored. It needs more code, but the domain model and the database schema can change separately.
Repository: sits between the domain and the data-mapping layer. It offers an interface that looks like a collection, such as orders.findById(id) and orders.save(order). In DDD there is one repository per aggregate root (the main object of a group that is saved as one unit). Its interface uses domain terms. It usually sits on top of a data mapper.
A DAO (Data Access Object) is an older abstraction that is closer to the tables. It gives CRUD operations per table or data source. In practice, the line between a DAO and a repository is blurry.
TypeORM supports both styles:
- Entities that extend
BaseEntityuse Active Record. - Injected repositories follow Data Mapper.
- Active Record is a row object with domain logic and a save() method.
- Data Mapper is a separate layer, so domain objects know nothing about storage.
- A repository is a collection-like domain interface, one per aggregate.
- A DAO gives table-oriented CRUD, and its difference from a repository is blurry.
- TypeORM supports both Active Record and Data Mapper.