问题描述
也许我不明白这个想法,但我开始创建我的第一个使用 api 平台的测试应用程序。
/**
* @Route(
* path="/api/pharmacies/search",* name="pharmacy_search",* defaults={
* "_api_resource_class"=Pharmacy::class,* "_api_collection_operation_name"="search"
* }
* )
* @param Request $request
*
* @return Paginator
*/
public function search(Request $request)
{
$query = SearchQuery::createFromrequest($request);
return $this->pharmacyRepository->search($query);
}
和存储库中的方法:
public function search(SearchQuery $searchQuery: Paginator
{
$firstResult = ($searchQuery->getPage() - 1) * self::ITEMS_PER_PAGE;
$qb = $this->createqueryBuilder('p')
/...
->setFirstResult($firstResult)
->setMaxResults(self::ITEMS_PER_PAGE);
$doctrinePaginator = new DoctrinePaginator($qb,false);
return new Paginator($doctrinePaginator);
}
它工作正常,但此操作不需要实体的所有字段以及与其他表的关系。目前此操作会创建 22 个查询。我想在 DBAL/QueryBuilder 中创建查询并使用 DTO 返回分页对象。
public function search(SearchQuery $searchQuery)
{
.../
$qb = $this->createqueryBuilder('p')
->select('p.id')
->addSelect('p.name')/....
$rows = $qb->getQuery()->getArrayResult();
foreach ($rows as $row){
$data[] = new SearchPharmacy($row['id'],$row['name']);
}
return $data;
}
上面的代码可以工作,但如果响应不是 Pagination 对象并且响应中没有 hydra:totalItems
、hydra:next
等。
理论上我可以使用 DataTransformer 将实体转换为 DTO,但这种方式不能简化数据库查询。
我能做到吗?
解决方法
我不知道如何使用 dbal 查询并将结果映射到 DTO,但我知道如何添加自定义选择,像标量一样返回它:
public function search(SearchQuery $searchQuery): Paginator
{
$firstResult = ($searchQuery->getPage() - 1) * self::ITEMS_PER_PAGE;
$qb = $this->createQueryBuilder('p')
->select('p.id')
->addSelect('p.name')
->where('p.name LIKE :search')
->setParameter('search',"%" . $searchQuery->getSearch() . "%");
$query = $qb->getQuery()->setFirstResult($firstResult)
->setMaxResults(self::ITEMS_PER_PAGE);
$doctrinePaginator = new DoctrinePaginator($query,false);
$doctrinePaginator->setUseOutputWalkers(false);
return new Paginator($doctrinePaginator);
}
最后我有 2 个轻量级查询,从实体和分页中选择字段。
来源: