Nestjs – Create relationship với Typeorm + mysql

Chào mừng các bạn trở lại với series tutorial Nestjs của mình. Nói chung là học cái nestjs này nó cũng đơn giản nhưng mà “people make it complicated” nên mình sẽ giúp em các bạn cảm thấy enjoy cái framework này 😂 😂 😂 – theo danh ca Chipu Index series Giới thiệu về

Chào mừng các bạn trở lại với series tutorial Nestjs của mình.

Nói chung là học cái nestjs này nó cũng đơn giản nhưng mà “people make it complicated” nên mình sẽ giúp em các bạn cảm thấy enjoy cái framework này 😂 😂 😂 – theo danh ca Chipu

Index series

  1. Giới thiệu về setup repository + typeorm.
  2. Xác thực người dùng trong Nestjs sử dụng Passport JWT.
  3. Tiếp tục series mình cùng các bạn sẽ tìm hiểu vể Relationship trong Nestjs + Typeorm. Bắt đầu nhé

1. Setting base

  • Ở bài viết về setup repository + typeorm mình đã setting rất chi tiết rồi. mọi người có thể tham khảo lại bài viết tại đây

  • Cụ thể: ở đây mình sẽ chỉ lấy ra thông tin user bằng id gửi lên function findById($id)

    Trong user.service.ts :

    import{ UsersRepository }from'./users.repository';...
     @Injectable()exportclassUsersService{constructor(@InjectRepository(UsersRepository)private usersRepository: UsersRepository,){}asyncfindById(
          id: number,
          relations: string[]=[],
          throwsException =false,): Promise<UserEntity>{returnawaitthis.usersRepository.getEntityById(
            id,
            relations,
            throwsException,);}}

    Trong user.repository.ts :

    import{ UsersService }from'./users.service';...
     @Injectable()exportclassUsersService{constructor(@InjectRepository(UsersRepository)private usersRepository: UsersRepository,){}asyncfindById(
          id: number,
          relations: string[]=[],
          throwsException =false,): Promise<UserEntity>{returnawaitthis.usersRepository.getEntityById(
            id,
            relations,
            throwsException,);}}

2. One-To-One

  1. Định nghĩa table
    users table :

    id name email password
    int increment varchar varchar varchar

    profiles table

    id user_id avatar address phone gender
    int increment int varchar varchar varchar varchar
  2. Define relationship in entity
    Định nghĩa user.entity.ts :

    import{ IUser }from'../interfaces/user.interface';...
      
       @Entity({ name:'users'})exportclassUserimplementsIUser{
         @PrimaryGeneratedColumn()
         id: string;
    
         @Column({ unique:true, length:255})
         email: string;
    
         @Column({ name:'password', length:255})
         password: string;
    
         @CreateDateColumn({ name:'created_at', type:'timestamp', nullable:true})
         createdAt: Date;
    
         @UpdateDateColumn({ name:'updated_at', type:'timestamp', nullable:true})
         updatedAt: Date;// define relationship with profiles table
         @OneToOne(()=> Profile,(profile)=> profile.user)
         profile: Profile;}

    Định nghĩa profile.entity.ts :

    import{ User }from'./entities/user.entity';...
       
       @EntityRepository(User)exportclassUsersRepository{...//function get user by id and relationshipasyncgetEntityById(
           id: number,
           relations: string[]=[],): Promise<UserEntity |null>{returnawaitthis.findOne({
             where:{ id },
             relations,}).then((entity)=>{if(!entity){return Promise.reject(newNotFoundException('Model not found'));}return Promise.resolve(entity ?this.transform(entity):null);});}transform(model: User): UserEntity {const transformOptions ={};returnplainToClass(
             UserEntity,classToPlain(model, transformOptions),
             transformOptions,);}
  3. Get data User with Profile

    Trong user.controller.ts :

    import{ UsersService }from'./users.service';...
    @Controller('users')exportclassUsersController{constructor(private readonly usersService: UsersService){}...
        
       @Get('conversation/:id')asyncuserConversation(@Param() params): Promise<UserEntity>{const user =awaitthis.usersService.findById(params.id,['profile',]);this.throwUserNotFound(user);return user;}...}

    còn đây sẽ là response

    {"id":"13","name":"duong","email":"[email protected]","password":"$2b$12$JDj6D0RIjpGdd4tAGO/BMOqUxmq.7tEGIvWHtJfbm6MfxIeXyBrGW","createdAt":"2021-10-10T06:56:06.000Z","updatedAt":"2021-10-10T06:56:06.000Z","profile":{"id":"2","user_id":"13","avatar":null,"phone":"+84999999999","createdAt":"2021-10-16T10:51:49.000Z","updatedAt":"2021-10-16T10:51:49.000Z"},}

3. One-To-Many

  1. Định nghĩa table
    users table :

    id name email password
    int increment varchar varchar varchar

    messages table

    id user_id conversation_id message
    int increment int int varchar
  2. Define relationship in entity

    Định nghĩa user.entity.ts :

    import{ IUser }from'../interfaces/user.interface';...
      
       @Entity({ name:'users'})exportclassUserimplementsIUser{...
         
         @OneToMany(()=> Message,(message)=> message.user)
         messages?: Message[];}

    Định nghĩa messages.entity.ts

    import{ IUser }from'../interfaces/user.interface';...
      
       @Entity({ name:'messages'})exportclassMessageimplementsIMessage{...
         
         @ManyToOne(()=> User,(user)=> user.messages)
         @JoinColumn({ name:'user_id'})
         user?: User;}
  3. Get data User with Profile

    Trong user.controller.ts :

    import{ UsersService }from'./users.service';...
    @Controller('users')exportclassUsersController{constructor(private readonly usersService: UsersService){}...
        
       @Get('conversation/:id')asyncuserConversation(@Param() params): Promise<UserEntity>{const user =awaitthis.usersService.findById(params.id,['messages',]);this.throwUserNotFound(user);return user;}...}

    còn đây sẽ là response

    {"id":"13","name":"duong","email":"[email protected]","messages":[{"id":"1","conversation_id":"1","user_id":"12","message":"hello xuan duong 2",},{"id":"2","conversation_id":"1","user_id":"12","message":"hello xuan duong 2",},]}

4. Many-To-Many

  1. Định nghĩa table
    users table :

    id name email password
    int increment varchar varchar varchar

    conversations table :

    id title description ….
    int increment varchar varchar varchar

    user_conversation table

    id user_id conversation_id
    int int int
  2. Define relationship in entity

    Định nghĩa user.entity.ts :

    @Entity({ name:'users'})exportclassUserimplementsIUser{...
      @ManyToMany(()=> Conversation,(conversations)=> conversations.users)
      @JoinTable({
        name:'user_conversation',
        joinColumn:{ name:'user_id', referencedColumnName:'id'},
        inverseJoinColumn:{ name:'conversation_id'},})
      conversations: Conversation[];}

    conversation.entity.ts :

     @Entity({ name:'conversations'})exportclassConversationimplementsIConversation{...
       
       @ManyToMany(()=> User,(users)=> users.conversations)
       @JoinTable({
         name:'user_conversation',
         joinColumn:{ name:'conversation_id', referencedColumnName:'id'},
         inverseJoinColumn:{ name:'user_id'},})
       users: User[];}
    1. Get data User with Profile

    Trong user.controller.ts :

    import{ UsersService }from'./users.service';...
      
       @Controller('users')exportclassUsersController{constructor(private readonly usersService: UsersService){}...
    
          @Get('conversation/:id')asyncuserConversation(@Param() params): Promise<UserEntity>{const user =awaitthis.usersService.findById(params.id,['conversations','conversations.messages',// lấy ra luôn các message trong converstion => nhớ định nghĩa relationship nhé]);this.throwUserNotFound(user);return user;}...}

5. Kết luận

  1. Qua bài viết này mình đã giới thiệu cho các bạn relationship trong typeorm. nếu có khó khắn hoặc thắc mặc đừng ngại ngần comment ở dưới, Nếu bài viết hay và hữu ích thì cho mình xin 1 upvote.

  2. Từ cấu trúc bảng mình đã xây dựn ở trên , ở bài tiếp theo mình sẽ giới thiệu với các bạn về chat realtime sử dụng :

    Server: Nestjs + socket.io

    Client: React + Redux saga

    Thank you!

Nguồn: viblo.asia

Bài viết liên quan

9 Mẹo lập trình Web “ẩn mình” giúp tiết kiệm hàng giờ đồng hồ

Hầu hết các lập trình viên (kể cả những người giỏi) đều tốn thời gian x

Can GPT-4o Generate Images? All You Need to Know about GPT-4o-image

OpenAI‘s GPT-4o, introduced on March 25, 2025, has revolutionized the way we create visual con

Khi nào nên dùng main, section, article, header, footer, và aside trong HTML5

HTML5 đã giới thiệu các thẻ ngữ nghĩa giúp cấu trúc nội dung web một cách có

So sánh Webhook và API: Khi nào nên sử dụng?

Trong lĩnh vực công nghệ thông tin và phát triển phần mềm, Webhook và API là hai th