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

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ