让前端飞Web前端之路

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

2019-07-17  本文已影响4人  cbw100

上一章中用更新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
上一篇下一篇

猜你喜欢

热点阅读