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
}
'프로그래밍 > Nest.js' 카테고리의 다른 글
[ NestJS] [ TypeORM ] transactions - DataSource 이용 (0) | 2024.04.29 |
---|---|
[ NestJS ] [TypeORM ] N : M 관계 형성 (0) | 2024.04.27 |
[ NestJS] [errror] No metadata for "User" was found. (0) | 2024.04.23 |
[ NestJS ] Modules (0) | 2024.04.18 |
[ NestJS ] Providers (0) | 2024.04.18 |