1 : N 

1  → User,    N → Photo

Many 쪽에 해당하는 entity에 Foriegn key 가 생성 → Photo 에 user_id 생성됨

 

Photo.entity.ts

import {Column, Entity, ManyToOne, PrimaryGeneratedColumn} from "typeorm";
import {User} from "./User.entity";

@Entity()
export class Photo{
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    url: string;
    
    // 관계를 정의하기 위해 추가된 코드
    @ManyToOne(() => User, (user) => user.photos)
    user : User;
}

 

User.entity.ts

import {Column, Entity, OneToMany, PrimaryGeneratedColumn} from "typeorm";
import {Photo} from "./Photo.entity";

@Entity()
export class User {
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    name:string
    
    // 관계를 정의하기 위해 추가된 코드
    @OneToMany(() => Photo, (photo) => photo.user)
    photos : Photo[];
}

 

관계 형성 방식 1 

1) User 생성 

2) Photo 생성 ( Body에서 Photo 를 생성하기 위한 정보와 존재하는 User 정보를 받아서 처리 하는 방식)

//user.service.ts

....
async createUser(createUserRequest : CreateUserRequestDto): Promise<CreateUserResponseDto>{
        const newUser = await this.userRepository.save(createUserRequest);
        return new CreateUserResponseDto(
            newUser.id,
            newUser.name
        )
    }
....


// photo.service.ts
...
async create(createPhotoRequestDto: CreatePhotoRequestDto): Promise<CreatePhotoResponseDto> {
        const {url, user} = createPhotoRequestDto;
        const photo1 = new Photo()
        photo1.url = url;
        photo1.user = user;
        return await this.photoRepository.save(photo1);
    }
...

 

관계 형성 방식 2

1) Photo 생성 

2) User 생성 ( Body에서 User 를 생성하기 위한 정보와 존재하는 Photo 정보를 받아서 처리 하는 방식)

 

//user.service.ts

....
async createUser(createUserRequest : CreateUserRequestDto): Promise<CreateUserResponseDto>{
        const {name, photos} = createUserRequest
        const newUser = new User
        newUser.name = name;
        newUser.photos = photos // photos =[ photo1, photo2,..] 와 같은 형태
        
        return await this.userRepository.save(createUserRequest);
    }
....


// photo.service.ts
...
async create(createPhotoRequestDto: CreatePhotoRequestDto): Promise<CreatePhotoResponseDto> {
        const {url, user} = createPhotoRequestDto;
        const photo1 = new Photo()
        photo1.url = url;
        return await this.photoRepository.save(photo1);
    }
...

 

 

1 : N 관계 조회

find 방식

// user.service.ts
... codes
async findRelationPhoto(){
        return await this.userRepository.find({
            relations: {
                photos: true,
            }
        })
    }


//photo.service.ts
...codes
 async findRelationUser(){
        return await this.photoRepository.find({
            relations: {
                user : true,
            }
        });
    }

 

QueryBuilder 방식

//user.service.ts
... codes
return await this.dataSource
  .getRepository(User)
  .createQueryBuilder('user')
  .leftJoinAndSelect('user.photos', 'photo')
  .getMany();

// photo.service.ts
... codes
return await this.dataSource
  .getRepository(Photo)
  .createQueryBuilder('photo')
  .leftJoinAndSelect('photo.user', 'user')
  .getMany();

 

 

- Photo 쪽에서 검색한 결과

[
    {
        "id": 1,
        "url": "photo.url",
        "user": {
            "id": 1,
            "name": "test"
        }
    },
    {
        "id": 2,
        "url": "photo2.url",
        "user": {
            "id": 1,
            "name": "test"
        }
    }
]

 

- User 쪽에서 검색한 결과 ( Photo 가 리스트로 표현)

[
    {
        "id": 1,
        "name": "test",
        "photos": [
            {
                "id": 1,
                "url": "photo.url"
            },
            {
                "id": 2,
                "url": "photo2.url"
            }
        ]
    }
]

 

데이터 수정

user

// user.service.ts
....  codes
    async reviseUserData(userNameReviseRequestDto:ReviseUserNameRequestDto):Promise<RevisePhotoUrlResponseDto>{
        const {name, newName} = userNameReviseRequestDto
        
        const user = await this.userRepository.findOne({where:{name}});
        user.name = newName
        
        await this.userRepository.save(user);
        return await this.userRepository.findOne({where:{name:newName}});
    }

photo

// photo.service.ts
... codes
        const {currentUrl, newUrl} = revisePhotoUrlRequestDto
        
        const photo = await this.photoRepository.findOne({where:{url:currentUrl}});
        photo.url = newUrl;
        await this.photoRepository.save(photo);
        
        const changePhoto:Photo =  await this.photoRepository.findOne({where:{url:newUrl}});
...

 

 

데이터 삭제

remove 이용

- 엔티티를 이용하여 지우는 방식

- 삭제하려는 해당 데이터가 없으면 error 를 반환

- 삭제성공하면 삭제된 데이트를 반환

 

user  엔티티 삭제

  • 연결되어있는 Photo들을 무시한채 지우면 에러 발생 → 관계있는 photo 부터 삭제한 후 삭제 가능
Error: Cannot delete or update a parent row: a foreign key constraint fails

 

photo 엔티티 삭제

-   deletePhotoRelatedUserRequestDto = { id, name} 이용하여 특정 유저와 관계가 있는 photo 엔티티를 얻은 후 삭제

.... codes
    async deletePhotosByUser(deletePhotoRelatedUserRequestDto:DeletePhotoRelatedUserRequestDto){
        const photoData = await this.photoRepository.find({
            where:{
                user : deletePhotoRelatedUserRequestDto 
            },
                relations : {
                    user : true,
                }
            });
        return await this.photoRepository.remove(photoData);
    }

 

User 삭제

- 앞에서 지운 유저의 아이디를 이용하여 유저 엔티티를 얻은 후  엔티티를 이용하여 삭제

... codes
   async deleteUserEntity(deleteUserEntityRequestDto:DeleteUserEntityRequestDto){
        const {id} = deleteUserEntityRequestDto;
        const user = await this.userRepository.findOne({where:{id}});
        await this.userRepository.remove(user)
    }

 

Delete 이용 

- pk id 를 이용하여 삭제

- 삭제하려는 데이터가 없어도 에러를 반환 안하고 -1 을 반환

- 삭제 성공시 1 을 반환

- 삭제 성공여부 확인시  " result.affected ? true : false" 와 같은 식으로 확인 가능

... codes
   async deleteUserEntity(deleteUserEntityRequestDto:DeleteUserEntityRequestDto){
        const {id} = deleteUserEntityRequestDto;
        const result = await this.userRepository.delete({id});
        return result.affected ? true : false
    }

 

+ Recent posts