如何使用 Doctrine 和 Symfony 查询数据库数据
How to query database data with Doctrine and Symfony
我有这样一行
// $repository is my repository for location data
$locationObject = $repository->findOneBy(array('name' => $locationName));
它从 Locations
table 中选择它能找到的第一条记录。这很公平。
但是,我在 table 中还有一些额外的数据可以使查询更加精确。具体来说,一个 "item_name" 列。在位置 class 中指定为:
/**
* @ORM\ManyToOne(targetEntity="Item", inversedBy="locations", cascade={"persist", "remove"})
* @ORM\JoinColumn(name="item_id", referencedColumnName="item_id", onDelete="CASCADE")
*/
protected $item;
所以还有一个项目table有item_id、item_name等
我想做的是将原来的 findOneBy()
更改为也按项目名称过滤。所以我想要这样的东西:
$locationObject = $repository->findOneBy(array('name' => $locationName, 'item' => $itemName));
但是因为 $item
是 Locations class 中的一个对象,而不是字符串或 ID,这显然是行不通的。所以我真的很想以某种方式反对 item->getName()...
我不确定我该怎么做。有人有什么建议吗?
谢谢
您必须使用自定义 dql.You 可以使用查询生成器构建它。
//in your controller
protected function getEntities($itemName){
$em = $this->get('doctrine.orm.default_entity_manager');
$qb = $em->createQueryBuilder();
$qb->select('a')->from('YourBundleAlias:YourEntityName', 'a')->join('a.item','b')->where('b.item = :item')->setParameter('item', $itemName);
return $qb->getQuery()->execute();
}
我想您必须创建一个带有连接的自定义查询。最好为此实体创建自定义存储库 class,然后在其中创建自定义查询构建。
实体:
// src/AppBundle/Entity/Foo.php
/**
* @ORM\Table(name="foo")
* @ORM\Entity(repositoryClass="AppBundle\Repository\FooRepository")
*/
class Foo
{
...
}
您的存储库:
// src/AppBundle/Repository/FooRepository.php
use Doctrine\ORM\EntityRepository;
class FooRepository extends EntityRepository
{
public function findByYouWant($id)
{
// your query build
}
}
控制器:
// src/AppBundle/Controller/FooController.php
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class FooController extends Controller
{
public function showAction()
{
// ... your code
$locationObject = $repository->findByYouWant($id);
}
}
这很简单:
$locationObject = $repository->findOneBy(array(
'name' => $locationName,
'item' => $itemObject
));
使用 Doctrine2 以便在相关实体字段上执行 findBy,您必须提供一个实体实例:$itemObject
.
您应该向您的位置存储库添加一个方法 class,并创建一个类似于下面的查询:
class LocationRepository extends EntityRepository
{
public function findLocationByItemName($locationName, $itemName)
{
$qb = $this->createQueryBuilder('location');
$qb->select('location')
->innerJoin(
'MyBundle:Item',
'item',
Query\Expr\Join::WITH,
$qb->expr()->eq('location.item', 'item.item_id')
)
->where($qb->expr()->like('location.name', ':locationName'))
->andWhere($qb->expr()->like('item.name', ':itemName'))
->setParameter('locationName', $locationName)
->setParameter('itemName', $itemName);
$query = $qb->getQuery();
return $query->getResult();
}
}
我有这样一行
// $repository is my repository for location data
$locationObject = $repository->findOneBy(array('name' => $locationName));
它从 Locations
table 中选择它能找到的第一条记录。这很公平。
但是,我在 table 中还有一些额外的数据可以使查询更加精确。具体来说,一个 "item_name" 列。在位置 class 中指定为:
/**
* @ORM\ManyToOne(targetEntity="Item", inversedBy="locations", cascade={"persist", "remove"})
* @ORM\JoinColumn(name="item_id", referencedColumnName="item_id", onDelete="CASCADE")
*/
protected $item;
所以还有一个项目table有item_id、item_name等
我想做的是将原来的 findOneBy()
更改为也按项目名称过滤。所以我想要这样的东西:
$locationObject = $repository->findOneBy(array('name' => $locationName, 'item' => $itemName));
但是因为 $item
是 Locations class 中的一个对象,而不是字符串或 ID,这显然是行不通的。所以我真的很想以某种方式反对 item->getName()...
我不确定我该怎么做。有人有什么建议吗?
谢谢
您必须使用自定义 dql.You 可以使用查询生成器构建它。
//in your controller
protected function getEntities($itemName){
$em = $this->get('doctrine.orm.default_entity_manager');
$qb = $em->createQueryBuilder();
$qb->select('a')->from('YourBundleAlias:YourEntityName', 'a')->join('a.item','b')->where('b.item = :item')->setParameter('item', $itemName);
return $qb->getQuery()->execute();
}
我想您必须创建一个带有连接的自定义查询。最好为此实体创建自定义存储库 class,然后在其中创建自定义查询构建。
实体:
// src/AppBundle/Entity/Foo.php
/**
* @ORM\Table(name="foo")
* @ORM\Entity(repositoryClass="AppBundle\Repository\FooRepository")
*/
class Foo
{
...
}
您的存储库:
// src/AppBundle/Repository/FooRepository.php
use Doctrine\ORM\EntityRepository;
class FooRepository extends EntityRepository
{
public function findByYouWant($id)
{
// your query build
}
}
控制器:
// src/AppBundle/Controller/FooController.php
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class FooController extends Controller
{
public function showAction()
{
// ... your code
$locationObject = $repository->findByYouWant($id);
}
}
这很简单:
$locationObject = $repository->findOneBy(array(
'name' => $locationName,
'item' => $itemObject
));
使用 Doctrine2 以便在相关实体字段上执行 findBy,您必须提供一个实体实例:$itemObject
.
您应该向您的位置存储库添加一个方法 class,并创建一个类似于下面的查询:
class LocationRepository extends EntityRepository
{
public function findLocationByItemName($locationName, $itemName)
{
$qb = $this->createQueryBuilder('location');
$qb->select('location')
->innerJoin(
'MyBundle:Item',
'item',
Query\Expr\Join::WITH,
$qb->expr()->eq('location.item', 'item.item_id')
)
->where($qb->expr()->like('location.name', ':locationName'))
->andWhere($qb->expr()->like('item.name', ':itemName'))
->setParameter('locationName', $locationName)
->setParameter('itemName', $itemName);
$query = $qb->getQuery();
return $query->getResult();
}
}