-
Notifications
You must be signed in to change notification settings - Fork 5
TypeORM Entity 접근하기
https://typeorm.io/#/working-with-entity-manager
TypeORM에는 Entity들을 관리할 수 있는 방법이 몇가지 있다. 먼저 EntityManager에 대해 알아본다. EntityManager를 사용하면 어느 entity든 insert, update, deelte, load 등을 할 수 있다. EntityManager는 모든 entity repository를 한 함수에 모아둔 것과 같다.
getManager 함수 또는 Connection으로 부터 entity manager에 접근할 수 있다.
import {getManager} from "typeorm";
import {User} from "./entity/User";
const entityManager = getManager(); // getConnection().manager를 통해서도 접근 가능
const user = await entityManager.findOne(User, 1); // id가 1인 유저를 가지고 와서 이름을 바꾸고 저장
user.name = "Umed";
await entityManager.save(user);
https://typeorm.io/#/working-with-repository
Repository는 구체적인 하나의 entity에 대한 EntityManger이다
getRepository(Entity)를 통해 또는 Connection의 getRepository 메소드, EntityManger의 getRepository 메소드를 통해 접근할 수 있다.
import {getRepository} from "typeorm";
import {User} from "./entity/User";
const userRepository = getRepository(User); // you can also get it via getConnection().getRepository() or getManager().getRepository()
const user = await userRepository.findOne(1);
user.name = "Umed";
await userRepository.save(user);
https://typeorm.io/#/custom-repository
내가 만든 Method를 포함하는 Custom Repository를 만들 수 있다. Custom Repository는 보통 하나의 엔티티에 대해 만들어지고, 특정 query Method를 포함한다. 예를 들어 주어진 성과 이름으로 사용자를 검색하는 findByName (firstName : string, lastName : string)이라는 메서드가 필요하다고 가정 했을 때 이 메서드의 가장 좋은 위치는 Repository에 이다. userRepository라는 Custom Repository를 만들고 findByName이라는 메소드를 만들어두면 userRepository.findByName (...)과 같이 호출 할 수 있다.
repository/favorite-repository.ts
import { EntityRepository, Repository } from 'typeorm';
import { Favorite } from '../entity/Favorite';
import { CreateParams } from '../service/favorite-service'; // type
@EntityRepository(Favorite) // 기본 적인 Repository 클래스를 상속 받는 커스텀 Repository를 만든다.
export default class FavoriteRepository extends Repository<Favorite> {
getByUserId(userId: number) {
return this.find({ user: { id: userId } });
}
createAndSave({ title, latex, userId }: CreateParams) {
const favorite = this.create({ latex, title, user: { id: userId } }); // favorite 생성
// 이때는 id가 없음
return this.manager.save(favorite); // 이 때 생성된 id가 포함된 정보가 온다.
}
}
service/favorite-service.ts
import { getCustomRepository } from 'typeorm';
import FavoriteRepository from '../repository/favorite-repository';
export interface CreateParams {
title: string;
latex: string;
userId: number;
}
class FavoriteService {
static instance: FavoriteService;
private favoriteRepository: FavoriteRepository;
constructor() {
this.favoriteRepository = getCustomRepository(FavoriteRepository);
}
static getInstance(): FavoriteService { // class에 static instance를 내보내준다.
if (!FavoriteService.instance) {
FavoriteService.instance = new FavoriteService();
}
return FavoriteService.instance;
}
async getFavoritesByUserId(userId: number) {
//다음과 같이 커스텀 repository를 활용할 수 있다.
const favorites = await this.favoriteRepository.getByUserId(userId);
return favorites;
}
async createFavorites({ latex, title, userId }: CreateParams) {
return await this.favoriteRepository.createAndSave({ title, latex, userId });
}
async deleteFavorites(id: number) {
await this.favoriteRepository.delete(id);
}
}
export default FavoriteService;
또는 AbstractRepository를 extends하는 Custom Repository를 만들 수도 있다.
import {EntityRepository, AbstractRepository} from "typeorm";
import {User} from "../entity/User";
@EntityRepository(User)
export class UserRepository extends AbstractRepository<User> {
createAndSave(firstName: string, lastName: string) {
const user = new User();
user.firstName = firstName;
user.lastName = lastName;
return this.manager.save(user);
}
findByName(firstName: string, lastName: string) {
return this.repository.findOne({ firstName, lastName });
}
}
그러면 이렇게 쓸 수 있다.
import {getCustomRepository} from "typeorm";
import {UserRepository} from "./repository/UserRepository";
const userRepository = getCustomRepository(UserRepository); // or connection.getCustomRepository or manager.getCustomRepository()
await userRepository.createAndSave("Timber", "Saw");
const timber = await userRepository.findByName("Timber", "Saw");
그냥 Repository와 AbstractRepository를 상속받는것의 차이점은 Repository는 모든 메소드들을 포함하고 있지만, AbstractRepository는 public methods를 가지고 있지 않다는 것이다.
manager, repository와 같은 protect method만 있으며 자신의 공용 메서드만 사용가능하다. AbstractRepository로 extends하는 것은 Repository가 가지고 잇는 모든 메소드를 public으로 사용하고 싶지 않을 때 유용하다.