Symfony2/Doctrine:SQL 到存储库中查询生成器的 DQL 以制作搜索表单
Symfony2/Doctrine: SQL to DQL for a querybuilder in a repository to make a search form
在我使用 Symfony 的项目中,我需要制作一个具有多标准的搜索表单。
我有实体 Parc 的 select,实体 Typesactivite 的 select 和 Ensembles 的输入文本。
我有这个SQL请求:
SELECT distinct e.nom FROM `ensembles` e, `parcsimmobilier` p, `batiments` b, `batiments_typesactivite` bta, `typesactivite` ta WHERE e.parcsimmobilier_id=p.id AND b.ensembles_id=e.id AND bta.batiments_id=b.id AND bta.typesactivite_id = ta.id AND p.nom="Ville de Dijon" AND ta.type="Sport"
这个 SQL 请求给了我属于第戎公园的所有合奏,那里的 baiments 有 activity 的运动。
我试图在我的 EnsemblesRepository.php 中用 DQL 语法转换这个 SQL 请求,但它没有给我很好的结果,我想我做到了错误:
public function recherche($input) //$input est la valeur entrée dans l'input type text recherche
{
$qb = $this ->createQueryBuilder('e')
->select('e.nom')
->addSelect('e.parcsimmobilier')
->from('MySpaceDatabaseBundle:Parcsimmobilier', 'p')
->from('MySpaceDatabaseBundle:Typesactivite', 'ta')
->from('MySpaceDatabaseBundle:Batiments', 'b')
->where('e.parcsimmobilier = p.id')
->andWhere('b.ensembles=b.id')
->andWhere('ta.batiments=b.id')
->andWhere('e.nom LIKE :input')
->setParameters(array(
'input' => "%".$input."%"));
return $qb->getQuery()->getResult();
}
当我提交表单时,出现以下错误:
[2/2] QueryException: [Semantical Error] line 0, col 16 near
'parcsimmobilier': Error: Invalid PathExpression. Must be a
StateFieldPathExpression.
[1/2] QueryException: SELECT e.nom, e.parcsimmobilier FROM
MySpace\DatabaseBundle\Entity\Ensembles e,
MySpaceDatabaseBundle:Parcsimmobilier p,
MySpaceDatabaseBundle:Typesactivite ta,
MySpaceDatabaseBundle:Batiments b WHERE e.parcsimmobilier = p.id AND
b.ensembles=b.id AND ta.batiments=b.id AND e.nom LIKE :input
如何在我的存储库中发出 DQL 请求?
这是我提交的搜索表单,用于搜索我的实体集成:
class RechercheType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
//Parcsimmobilier
->add('parcs:', 'entity', array(
'class' => 'MySpaceDatabaseBundle:Parcsimmobilier',
'property' => 'nom',
'empty_value' => 'Choisir le parc immobilier',
'required' => true))
//Typesactivite
->add('typesactivite:', 'entity', array(
'class' => 'MySpaceDatabaseBundle:Typesactivite',
'property' => 'type',
'empty_value' => 'Choisir le type d\'activite',
'required' => false))
//Ensembles
->add('ensemble', 'text', array(
'attr' => array('placeholder' => 'rechercher'),
'required' => false))
;
更新
这是我的控制器代码,如果有帮助的话:
public function rechercheEnsemblesAction() {
$formRecherche = $this->createForm(new RechercheType());
//si la méthode est bien en POST
if ($this->get('request')->getMethod() == 'POST' )
{
$formRecherche->bind($this->get('request'));
$em=$this->getDoctrine()->getManager();
$ensemble = $em ->getRepository('MySpaceDatabaseBundle:Ensembles')
->recherche($formRecherche['ensemble']
->getdata());
}
return $this->render('MySpaceGestionPatrimoinesBundle:Ensembles:rechercheEnsembles.html.twig', array('ensemble' => $ensemble, 'formRecherche' => $formRecherche->createView() ));
}
让我们尝试逐步执行查询。
在select标签中,我可以选择parcs的名称(required),without 在我的输入文本中为 ensemble 的名称输入一个值。
我的 SQl 请求在 phpMyAdmin:
SELECT distinct e.nom FROM `ensembles` e, `parcsimmobilier` p where e.parcsimmobilier_id=p.id
这个请求给了我属于 parc 的 所有合奏 ,id 为 1。
在 DQl 中,我在我的存储库中尝试这个 EnsemblesRepository.php:
public function recherche() //$input est la valeur entrée dans l'input type text recherche
{
$qb = $this ->createQueryBuilder('e')
->select('e.nom')
->from('MySpaceDatabaseBundle:Parcsimmobilier', 'p')
->where('e.parcsimmobilier = p.id')
->andWhere('e.nom LIKE :input')
->setParameters(array(
'input' => "%".$input."%"));
return $qb->getQuery()->getResult();
}
但 return 我并没有得到好的结果。即使我在构建表单中创建的 select 标签中选择了一个 parc,结果也是我数据库中的所有 Ensemble。
有人可以一步一步地帮助我吗?
如果您需要更多信息,这是我的实体之间的关系。只有两个 classes/entities 有我需要的关系。
Ensemnles.php:
/**
* @var \Parcsimmobilier
*
* @ORM\ManyToOne(targetEntity="Parcsimmobilier")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="parcsimmobilier_id", referencedColumnName="id")
* })
*/
private $parcsimmobilier;
Batiments.php:
/**
* @ORM\ManyToOne(targetEntity="MySpace\DatabaseBundle\Entity\Ensembles")
* @ORM\JoinColumn(nullable=false)
*/
private $ensembles;
/**
* @ORM\ManyToMany(targetEntity="MySpace\DatabaseBundle\Entity\Typesactivite")
* @ORM\JoinColumn(nullable=true)
*/
private $typesactivite;
我真的找不到解决方案,如果您需要,请随时询问更多信息。
感谢您的理解。
您尝试 select 一个带有别名的对象。如果你想 select 标量字段使用 select('entity_alias.field')
但如果你想 select 一个实体你只需指定 table 别名。在您的情况下,您需要 select 'p' 而不是 'e.parcsimmobilier'。
此外,您应该始终加入而不是使用多个 from 语句。这也将允许您根据您的对象模型将那些 where 语句作为 doctrine join 删除,这样您就不需要手动编写那些 Id = id 。
就像我告诉你的那样 here, check the Jquery datatables here,对于你的项目,如果它是为了在 Symfony 中管理你的实体。
然后,您可以将自己的请求与 Jquery、Ajax 和 Symfony 一起使用,以便在 html <table>
.
这是一个 .js
的示例,您可以使用它在数据中进行搜索table:
$(document).ready(function() {
$('#dataTables').DataTable( {
"dom": '<"toolbar">frtip',
responsive: true,
initComplete: function () {
var api = this.api();
api.columns().indexes().flatten().each( function ( i ) {
var column = api.column( i );
var select = $('<select><option value=""></option></select>')
.appendTo( $(column.footer()).empty() )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
});
column.data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' )
});
});
}
});
$("div.toolbar").html('<b>Example</b>');
});
当然还有 html
(不要忘记使用数据表的 table 的结构,所有步骤都在文档中 => 数据表能够增强 HTML table,table 必须有效,格式正确 HTML,带有 header (thead) 和 body (t body)。也可以使用可选的页脚 (tfoot)。):
<table id="dataTables" class="your class or bootstrap class if you are using bootstrap for example">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
...number you want...
</tr>
</thead>
<tbody>
<tr>
<td>{{ entity.field }}</td>
<td>{{ entity.field2 }}</td>
...etc..
</tr>
</tbody>
</table>
在我使用 Symfony 的项目中,我需要制作一个具有多标准的搜索表单。 我有实体 Parc 的 select,实体 Typesactivite 的 select 和 Ensembles 的输入文本。
我有这个SQL请求:
SELECT distinct e.nom FROM `ensembles` e, `parcsimmobilier` p, `batiments` b, `batiments_typesactivite` bta, `typesactivite` ta WHERE e.parcsimmobilier_id=p.id AND b.ensembles_id=e.id AND bta.batiments_id=b.id AND bta.typesactivite_id = ta.id AND p.nom="Ville de Dijon" AND ta.type="Sport"
这个 SQL 请求给了我属于第戎公园的所有合奏,那里的 baiments 有 activity 的运动。
我试图在我的 EnsemblesRepository.php 中用 DQL 语法转换这个 SQL 请求,但它没有给我很好的结果,我想我做到了错误:
public function recherche($input) //$input est la valeur entrée dans l'input type text recherche
{
$qb = $this ->createQueryBuilder('e')
->select('e.nom')
->addSelect('e.parcsimmobilier')
->from('MySpaceDatabaseBundle:Parcsimmobilier', 'p')
->from('MySpaceDatabaseBundle:Typesactivite', 'ta')
->from('MySpaceDatabaseBundle:Batiments', 'b')
->where('e.parcsimmobilier = p.id')
->andWhere('b.ensembles=b.id')
->andWhere('ta.batiments=b.id')
->andWhere('e.nom LIKE :input')
->setParameters(array(
'input' => "%".$input."%"));
return $qb->getQuery()->getResult();
}
当我提交表单时,出现以下错误:
[2/2] QueryException: [Semantical Error] line 0, col 16 near 'parcsimmobilier': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
[1/2] QueryException: SELECT e.nom, e.parcsimmobilier FROM MySpace\DatabaseBundle\Entity\Ensembles e, MySpaceDatabaseBundle:Parcsimmobilier p, MySpaceDatabaseBundle:Typesactivite ta, MySpaceDatabaseBundle:Batiments b WHERE e.parcsimmobilier = p.id AND b.ensembles=b.id AND ta.batiments=b.id AND e.nom LIKE :input
如何在我的存储库中发出 DQL 请求?
这是我提交的搜索表单,用于搜索我的实体集成:
class RechercheType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
//Parcsimmobilier
->add('parcs:', 'entity', array(
'class' => 'MySpaceDatabaseBundle:Parcsimmobilier',
'property' => 'nom',
'empty_value' => 'Choisir le parc immobilier',
'required' => true))
//Typesactivite
->add('typesactivite:', 'entity', array(
'class' => 'MySpaceDatabaseBundle:Typesactivite',
'property' => 'type',
'empty_value' => 'Choisir le type d\'activite',
'required' => false))
//Ensembles
->add('ensemble', 'text', array(
'attr' => array('placeholder' => 'rechercher'),
'required' => false))
;
更新
这是我的控制器代码,如果有帮助的话:
public function rechercheEnsemblesAction() {
$formRecherche = $this->createForm(new RechercheType());
//si la méthode est bien en POST
if ($this->get('request')->getMethod() == 'POST' )
{
$formRecherche->bind($this->get('request'));
$em=$this->getDoctrine()->getManager();
$ensemble = $em ->getRepository('MySpaceDatabaseBundle:Ensembles')
->recherche($formRecherche['ensemble']
->getdata());
}
return $this->render('MySpaceGestionPatrimoinesBundle:Ensembles:rechercheEnsembles.html.twig', array('ensemble' => $ensemble, 'formRecherche' => $formRecherche->createView() ));
}
让我们尝试逐步执行查询。
在select标签中,我可以选择parcs的名称(required),without 在我的输入文本中为 ensemble 的名称输入一个值。 我的 SQl 请求在 phpMyAdmin:
SELECT distinct e.nom FROM `ensembles` e, `parcsimmobilier` p where e.parcsimmobilier_id=p.id
这个请求给了我属于 parc 的 所有合奏 ,id 为 1。
在 DQl 中,我在我的存储库中尝试这个 EnsemblesRepository.php:
public function recherche() //$input est la valeur entrée dans l'input type text recherche
{
$qb = $this ->createQueryBuilder('e')
->select('e.nom')
->from('MySpaceDatabaseBundle:Parcsimmobilier', 'p')
->where('e.parcsimmobilier = p.id')
->andWhere('e.nom LIKE :input')
->setParameters(array(
'input' => "%".$input."%"));
return $qb->getQuery()->getResult();
}
但 return 我并没有得到好的结果。即使我在构建表单中创建的 select 标签中选择了一个 parc,结果也是我数据库中的所有 Ensemble。
有人可以一步一步地帮助我吗?
如果您需要更多信息,这是我的实体之间的关系。只有两个 classes/entities 有我需要的关系。
Ensemnles.php:
/**
* @var \Parcsimmobilier
*
* @ORM\ManyToOne(targetEntity="Parcsimmobilier")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="parcsimmobilier_id", referencedColumnName="id")
* })
*/
private $parcsimmobilier;
Batiments.php:
/**
* @ORM\ManyToOne(targetEntity="MySpace\DatabaseBundle\Entity\Ensembles")
* @ORM\JoinColumn(nullable=false)
*/
private $ensembles;
/**
* @ORM\ManyToMany(targetEntity="MySpace\DatabaseBundle\Entity\Typesactivite")
* @ORM\JoinColumn(nullable=true)
*/
private $typesactivite;
我真的找不到解决方案,如果您需要,请随时询问更多信息。
感谢您的理解。
您尝试 select 一个带有别名的对象。如果你想 select 标量字段使用 select('entity_alias.field')
但如果你想 select 一个实体你只需指定 table 别名。在您的情况下,您需要 select 'p' 而不是 'e.parcsimmobilier'。
此外,您应该始终加入而不是使用多个 from 语句。这也将允许您根据您的对象模型将那些 where 语句作为 doctrine join 删除,这样您就不需要手动编写那些 Id = id 。
就像我告诉你的那样 here, check the Jquery datatables here,对于你的项目,如果它是为了在 Symfony 中管理你的实体。
然后,您可以将自己的请求与 Jquery、Ajax 和 Symfony 一起使用,以便在 html <table>
.
这是一个 .js
的示例,您可以使用它在数据中进行搜索table:
$(document).ready(function() {
$('#dataTables').DataTable( {
"dom": '<"toolbar">frtip',
responsive: true,
initComplete: function () {
var api = this.api();
api.columns().indexes().flatten().each( function ( i ) {
var column = api.column( i );
var select = $('<select><option value=""></option></select>')
.appendTo( $(column.footer()).empty() )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
});
column.data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' )
});
});
}
});
$("div.toolbar").html('<b>Example</b>');
});
当然还有 html
(不要忘记使用数据表的 table 的结构,所有步骤都在文档中 => 数据表能够增强 HTML table,table 必须有效,格式正确 HTML,带有 header (thead) 和 body (t body)。也可以使用可选的页脚 (tfoot)。):
<table id="dataTables" class="your class or bootstrap class if you are using bootstrap for example">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
...number you want...
</tr>
</thead>
<tbody>
<tr>
<td>{{ entity.field }}</td>
<td>{{ entity.field2 }}</td>
...etc..
</tr>
</tbody>
</table>