美文网首页让前端飞Web前端之路
Nest.js学习之路(22)-TypeORM(9) Relat

Nest.js学习之路(22)-TypeORM(9) Relat

作者: cbw100 | 来源:发表于2019-07-17 10:12 被阅读4次

    上一章中用更新User的两个关联数据为例,介绍RelationQueryBuilder,今天把UserService里面全部用QueryBuilder改写,另外值得提的是这样做以后其实可以改注入entitymanager或是connection就可以了,两者的优劣就可能就是个人偏好或是大家可以讨论(应该是跟Performance有关吧!?)

    注入Entitymanager

    用QueryBuilder全部改写,意谓不会再用到TypeORM的Repository API,我们可以只注入EntityManager,习惯写SQL多一点的人适合。

    修改user.service constructor部分

    constructor(
            // @InjectRepository(User) // 注入 typeorm repository
            // private readonly userRepo: Repository<User>,
    
            // 注入EntityManager可以指定Connection
            // 会用default connection,多个connection要参考nestjs官网
            @InjectEntityManager()
            private readonly em: EntityManager,
            private platformService: PlatformService,
            private roleService: RoleService,
        ){}
    

    user.module不用修改

    这下关于userRepo的地方下面会有红色小蚯蚓,把useRep按F2 Refactor成em

    还有一个要修改的地方是

    // 会有红色小蚯蚓
    this.em.createQueryBuilder('u') 
    // EntityManager必须要传入Entity Type
    this.em.createQueryBuilder(User, 'u')
    

    使用EntityManager的好处是可以使用Transaction,未来有机会再介绍,简单说可以实践多个SQL Operation在一个Transaction

    Refactor getUserById

    async getUserById(userId): Promise<User>{
            // 载入roles导览属性
            // 设定eager=true后要把plat拿掉,重复载入SQL语法错误
            // return await this.userRepo.findOne(id, {relations: ['plat', 'roles']});
            // return await this.userRepo.findOneOrFail(id); // 以id搜寻,沒找到会丟出例外
            return await this.em
                        .createQueryBuilder(User, 'u')
                        .leftJoinAndSelect('u.roles', 'r')
                        .leftJoinAndSelect('u.plat', 'p')
                        .whereInIds(userId)
                        .select([
                                'u.id',
                                'u.name',
                                'u.age',
                                'p.id',
                                'p.platformname',
                                'r.id',
                                'r.roleName',
                         ])
                        .getOne(); // 单笔使用getOne
        }
    

    Refactor addUser

    async addUser(data: UserDTO): Promise<User>{
            const user = new User();
    
            user.name = data.name;
            user.age = data.age;
    
            // // user.platId  = data.platId; 不能只指定id,必须传入platform对象save的时候才会储存关联资料
            // user.dep = await this.depService.getDepById(data.depId);
            // // 先要取得role,再指给user物件下的roles,save时才会存储关联
            // user.roles = await this.roleService.getRolesByIds(data.roleIds);
            // return await this.userRepo.save(user);
            let userId;
            await this.em.createQueryBuilder()
                                .insert() // 不接受任何参数
                                .into(User) //
                                .values(user) // 先更新关联以外的属性
                                .execute() // 必须execute才会产生SQL送到DB
                                .then(async (result) => {
                                    Logger.log(result); // 到console看回传的格式
                                    userId = result.identifiers[0].id; // 取得新增后回传的id
                                    // 以下更新关联属性
                                    await this.em.createQueryBuilder()
                                    .relation(User, 'roles')
                                    .of(userId)
                                    .add(data.roleIds)
                                    .then(async () => {
                                        await this.em.createQueryBuilder()
                                                             .relation(User, 'plat')
                                                             .of(userId)
                                                             .set(data.platId);
                                    });
                                });
    
            return this.getUserById(userId);
        }
    
    2018111505.png

    Refactor deleteUser

    async deleteUser(id){
        const userDeleted = this.getUserById(id); // 先把原本的User存起來
        return this.em.createQueryBuilder()
                   .delete()
                   .from(User)
                   .whereInIds(id) // 指定id for delete
                   .execute()
                   .then(result => userDeleted); // 回传raw沒有资料
        }
    

    cache

    取得user list的时候可以使用cache(Repository API也有),以QueryBuilder改写getUsers

    async getUsers(pageInfo: UserQueryDTO): Promise<User[]>{
            return await this.em
                            .createQueryBuilder(User, 'u')
                            .leftJoinAndSelect('u.roles', 'r')
                            .leftJoinAndSelect('u.plat', 'p')
                            .select([
                                'u.id',
                                'u.name',
                                'u.age',
                                'p.id',
                                'p.platformname',
                                'r.id',
                                'r.roleName',
                             ])
                             .orderBy('p.platformname', 'ASC')
                             .addOrderBy('u.name')
                             .skip((pageInfo.page - 1) * pageInfo.pageSize)
                             .take(pageInfo.pageSize) // 取pageSize
                             .cache(60000) // 1 min內
                             .getMany();
        }
    

    使用postman测试


    2018111504.png

    TypeORM还有最后一个值得分享是Listener跟有关embedded entity,再来就回到nestjs

    推荐一下我的公众号: 【 geekjc 】,微信号: 【 c8706288 】一起学习交流编程知识,分享经验,各种有趣的事。

    tuiguang.png

    相关文章

      网友评论

        本文标题:Nest.js学习之路(22)-TypeORM(9) Relat

        本文链接:https://www.haomeiwen.com/subject/gvlyfqtx.html