创建查询生成器时如何避免重复代码?

问题描述 投票:0回答:2

早上好,我有订单服务。这里我有两个方法 find( findAll )和 findByKey(通过键查找所有),因为它是一个查询生成器,我需要加入其他表。

方法查找:

find(): Promise<Order[]> {
    return this.orderRepository
      .createQueryBuilder('order')
      .leftJoinAndSelect('order.restaurant', 'restaurant')
      .leftJoinAndSelect('order.user', 'media')
      .leftJoinAndSelect('order.orderCustomer', 'orderCustomer')
      .innerJoinAndSelect('order.orderCart', 'orderCart')
      .leftJoinAndSelect('orderCart.product', 'product')
      .leftJoinAndSelect('product.media', 'product_media')
      .leftJoinAndSelect('order.orderPayment', 'orderPayment')
      .getMany();
  }

方法findByKey:

findByKey(data: FindByKeyInput): Promise<Order[]> {
    const { field, value } = data;
    return this.orderRepository
      .createQueryBuilder('order')
      .where(`order.${field} = :${field}`, { [field]: value })
      .leftJoinAndSelect('order.restaurant', 'restaurant')
      .leftJoinAndSelect('order.user', 'media')
      .leftJoinAndSelect('order.orderCustomer', 'orderCustomer')
      .innerJoinAndSelect('order.orderCart', 'orderCart')
      .leftJoinAndSelect('orderCart.product', 'product')
      .leftJoinAndSelect('product.media', 'product_media')
      .leftJoinAndSelect('order.orderPayment', 'orderPayment')
      .getMany();
  }

如何避免这种重复,我可以将这部分代码放入变量中并重用吗?谢谢!

typescript typeorm
2个回答
0
投票

您可以使用可选参数创建一个函数,例如:

find(data: FindByKeyInput = { field=null, value=null }): Promise<Order[]> {
const { field, value } = data;
let query = this.orderRepository
  .createQueryBuilder('order') ;

 if(field != null && value != null)
 query.where(`order.${field} = :${field}`, { [field]: value });

 query.leftJoinAndSelect('order.restaurant', 'restaurant')
  .leftJoinAndSelect('order.user', 'media')
  .leftJoinAndSelect('order.orderCustomer', 'orderCustomer')
  .innerJoinAndSelect('order.orderCart', 'orderCart')
  .leftJoinAndSelect('orderCart.product', 'product')
  .leftJoinAndSelect('product.media', 'product_media')
  .leftJoinAndSelect('order.orderPayment', 'orderPayment')
  .getMany();
 return query
   }

更新
要执行您想要的操作,您可以创建一个返回查询生成器的函数:

getOrderRepoWithRelations(){
 return  this.orderRepository
   .createQueryBuilder('order')
  .leftJoinAndSelect('order.restaurant', 'restaurant')
  .leftJoinAndSelect('order.user', 'media')
  .leftJoinAndSelect('order.orderCustomer', 'orderCustomer')
  .innerJoinAndSelect('order.orderCart', 'orderCart')
  .leftJoinAndSelect('orderCart.product', 'product')
  .leftJoinAndSelect('product.media', 'product_media')
  .leftJoinAndSelect('order.orderPayment', 'orderPayment')
}

然后你可以在你的函数中使用它,例如:

find(): Promise<Order[]> {
return this.getOrderRepoWithRelations()
  .getMany();
 }


 findByKey(data: FindByKeyInput): Promise<Order[]> {
    const { field, value } = data;
    let query = this.getOrderRepoWithRelations();
    return query
      .where(`order.${field} = :${field}`, { [field]: value })
      .getMany();
  }

0
投票

您还可以使用 .clone() 方法。

//1. create a common query builder
const queryBuilder = this.orderRepository
  .createQueryBuilder('order')
  .leftJoinAndSelect('order.restaurant', 'restaurant')
  .leftJoinAndSelect('order.user', 'media')
  .leftJoinAndSelect('order.orderCustomer', 'orderCustomer')
  .innerJoinAndSelect('order.orderCart', 'orderCart')
  .leftJoinAndSelect('orderCart.product', 'product')
  .leftJoinAndSelect('product.media', 'product_media')
  .leftJoinAndSelect('order.orderPayment', 'orderPayment');

// 2. clone and add more queries to it
const firstQueryResult = await queryBuilder.clone().getMany()

const secondQueryResult = await queryBuilder.clone()
  .where(`order.${field} = :${field}`, { [field]: value })
  .getMany()

但是,我主要使用 clone() 方法多次重复使用相同的 queryBuilder,例如当我想根据某些过滤器获取项目列表并获取计数时。 例如

const queryPrice = 10
const page= 1
const limit = 20
const queryBuilder = productRepo.createQueryBuilder('prod')
  .select('prod.id', 'id')
  .addSelect('prod.name', 'productName')
  .addSelect('prod.price', 'productPrice')
  .where('prod.price > :queryPrice', {queryPrice})
const count = await queryBuilder.clone().getCount()
const products = await queryBuilder.clone()
  .orderBy('prod.price', 'DESC')
  .skip((page - 1) * size)
  .take(limit)
  .getMany();
© www.soinside.com 2019 - 2024. All rights reserved.