본문으로 바로가기

Active Record 패턴 vs Data Mapper 패턴

category DB, ORM/🧊 typeORM 2020. 11. 10. 19:52

Active Record 패턴

 

In TypeORM you can use both the Active Record and the Data Mapper patterns.

 

Using the Active Record approach, you define all your query methods inside the model itself, and you save, remove, and load objects using model methods. 즉, Model.find({}), Model.remove(), Model.save() 꼴로 사용할 수 있는 거죠.

 

Active record 패턴에 대한 일반적 정의는 위키피디아를 참고합시다.

 

All active-record entities must extend the BaseEntity class, which provides methods to work with the entity. BaseEntity has most of the methods of the standard Repository. (예를 들면 save, remove, create와 같은 메서드들) Most of the time you don't need to use Repository or EntityManager with active record entities.

 

결론적으로는 모델로 부터 바로 메서드를 사용할 수 있어서 편합니다. 쓰다보면 mongoose와 같은 패턴으로 설계되었구나를 체감하실 수 있습니다.

 

active record 패턴을 이용한 entity 정의의 예시는 아래와 같습니다.

import {BaseEntity, Entity, PrimaryGeneratedColumn, Column} from "typeorm";

@Entity()
export class User extends BaseEntity {
       
    @PrimaryGeneratedColumn()
    id: number;
    
    @Column()
    firstName: string;
    
    @Column()
    lastName: string;
    
    @Column()
    isActive: boolean;
    
    static findByName(firstName: string, lastName: string) {
        return this.createQueryBuilder("user")
            .where("user.firstName = :firstName", { firstName })
            .andWhere("user.lastName = :lastName", { lastName })
            .getMany();
    }

}

 

 

data mapper 패턴

 

Using the Data Mapper approach, you define all your query methods in separate classes called "repositories", and you save, remove, and load objects using repositories. In data mapper your entities are very dumb - they just define their properties and may have some "dummy" methods.

 

Simply said, data mapper is an approach to access your database within repositories instead of models. You can read more about data mapper on Wikipedia.

 

쉽게 말해 모델에서 곧장 사용할 수 없고 repository를 이용한다는 것입니다. 

 

우선 선언은 똑같지만 보통 내부 메서드 정의가 없습니다. (못 쓴다는 게 아닙니다. 쓸 수 있습니다)

모델 내부에 메서드를 정의하는 건 대부분 active record 패턴이고, 여기서는 data mapper 패턴을 사용할 것입니다.

import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";

@Entity()
export class User {
       
    @PrimaryGeneratedColumn()
    id: number;
    
    @Column()
    firstName: string;
    
    @Column()
    lastName: string;
    
    @Column()
    isActive: boolean;

}

 

repository를 생성한 뒤 repository를 경유하여 find도 하고 remove도 하는 등 메서드를 사용할 수 있게 됩니다.

const userRepository = connection.getRepository(User);

// example how to save DM entity
const user = new User();
user.firstName = "Timber";
user.lastName = "Saw";
user.isActive = true;
await userRepository.save(user);

// example how to remove DM entity
await userRepository.remove(user);

// example how to load DM entities
const users = await userRepository.find({ skip: 2, take: 5 });
const newUsers = await userRepository.find({ isActive: true });
const timber = await userRepository.findOne({ firstName: "Timber", lastName: "Saw" });

 

커스텀 메서드를 만들고 싶을 때는 active record 방식이라면 그냥 모델 내부에 메서드를 정의하면 되고

datamapper 방식에서도 종종 그렇게 합니다.

 

그런데 data mapper 패턴에서는 Custom Repository을 이용할 수도 있습니다.

darrengwon.tistory.com/1064

import {EntityRepository, Repository} from "typeorm";
import {User} from "../entity/User";

@EntityRepository()
export class UserRepository extends Repository<User> {

    findByName(firstName: string, lastName: string) {
        return this.createQueryBuilder("user")
            .where("user.firstName = :firstName", { firstName })
            .andWhere("user.lastName = :lastName", { lastName })
            .getMany();
    }

}
const userRepository = connection.getCustomRepository(UserRepository);
const timber = await userRepository.findByName("Timber", "Saw");

 

 

그래서 뭘 사용해야 하는가?

 

The decision is up to you. Both strategies have their own cons and pros.

 

One thing we should always keep in mind in with software development is how we are going to maintain our applications. The Data Mapper approach helps with maintainability, which is more effective in bigger apps. The Active record approach helps keep things simple which works well in smaller apps. And simplicity is always a key to better maintainability.

 

 

 

참고한 글)

 

github.com/typeorm/typeorm/blob/master/docs/active-record-data-mapper.md

 

typeorm/typeorm

ORM for TypeScript and JavaScript (ES7, ES6, ES5). Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAP Hana, WebSQL databases. Works in NodeJS, Browser, Ionic, Cordova and Elect...

github.com

aonee.tistory.com/77

 


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체