Convert sql to doctrine orm in aend framework - php

I have a query which looks like below:
SELECT *
FROM mydb.users
left join mydb.job on
users.id = job.userid;
Now I am using doctrine orm in querying database but I am newbie here.
What I have done so far is below but it doesn't work as expected.
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$qb->select(array('a', 'c'))
->from('Admin\Entity\User', 'a')
->leftJoin('a.id', 'c');
$query = $qb->getQuery();
$results = $query->getResult();
return $results;

you do not need the from clause and array from clause select
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder('u');
$qb->select('u', 'j')
->leftJoin('u.jobs', 'j')
$query = $qb->getQuery();
$results = $query->getResult();
return $results;
it is mandatory that your users entity contains a "one to many" jobs for the attribute.
trick to display the SQL output :
var_dump($qb->getQuery()->getSQL());

Related

Doctrine QueryBuilder from with subquery

I need to write some complex query builder expression. The sql looks like:
SELECT query,popularity,nb_words
FROM gemini_suggestion
WHERE query IN
(
SELECT * FROM
(
SELECT query
FROM gemini_suggestion
GROUP BY query
HAVING COUNT(query) > 1
) AS subquery
);
The code im stucked at is:
$queryBuilder = $em->createQueryBuilder();
$queryBuilder->select('a')
->from($this->entity['class'], 'a')
->where($queryBuilder->expr()->In('a.query', $subQuery->getDQL()));
$subQuery2 = $em->createQueryBuilder()
->select('b.query')
->from($this->entity['class'], 'b')
->groupBy('b.query')
->having('count(b.query)>1')
;
$subQuery = $em->createQueryBuilder();
$subQuery->select('a')
->from(...)
;
Any help would be nice!
You can try something like this. I'm assuming you have a namespace Entities where you have all your entities classes.
// Subquery to get the queries greater than 1
$subQueryBuilder = $this->entityManager->createQueryBuilder();
$subQueryBuilder->select('gemini_suggestion.query')
->from('Entities\gemini_suggestion', 'gemini_suggestion')
->groupBy('gemini_suggestion.query')
->having($subQueryBuilder->expr()->gt('COUNT(gemini_suggestion.query)', 1));
// Main query where you use the subquery to filter out the records you want
$queryBuilder = $this->entityManager->createQueryBuilder();
$queryBuilder->select('query, popularity, nb_words')
->from('Entities\gemini_suggestion', 'gemini_suggestion')
->where($queryBuilder->expr()->in('gemini_suggestion.query', $subQueryBuilder->getDQL()));
$result = $queryBuilder->getQuery()->getResult();
return $result;

How to limits results by main entity, not with childrens?

How to limits results by main entity, not with childrens?
If I do:
$queryBuilder = $em->createQueryBuilder();
$queryBuilder->select('n, c');
$queryBuilder->from('AppBundle:News', 'n');
$queryBuilder->leftJoin('n.comments', 'c');
$queryBuilder->setMaxResults(3);
$results = $queryBuilder->getQuery()->getResult();
And first News has for example 3 comments, then results return me only one record News. If I don't have comments or if I remove leftJoin, then this is working well.
You are using the wrong variable for your results.
You are using $queryBuilder to prepare your statement:
$queryBuilder = $em->createQueryBuilder();
But taking $qb to get your result;
$results = $qb->getQuery()->getResult();
Doctrine can behave unexpectedly with joins, multiple wheres and pagination.
The recommended way is to use the Paginator, and not directly call getResults.
The paginator handles the grouping of the results to the main entity.
Edit: to supply some sample code:
<?php
use Doctrine\ORM\Tools\Pagination\Paginator;
$dql = "SELECT p, c FROM BlogPost p JOIN p.comments c";
$query = $entityManager->createQuery($dql)
->setFirstResult(0)
->setMaxResults(100);
$paginator = new Paginator($query, $fetchJoinCollection = true);
$c = count($paginator);
foreach ($paginator as $post) {
echo $post->getHeadline() . "\n";
}
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/tutorials/pagination.html

symfony2 query builder with multiple databases (doctrine)

I want join the abteilung table which is in another database with other access data.
Here is the right database for abteilung:
$manager = $this->getDoctrine()->getManager('olddb')->getRepository('ChrisOldUserBundle:BpDepartment');
And this is the old query i want to change:
$result = $this->getDoctrine()->getRepository('KfzBuchungBundle:Rent')
->createQueryBuilder('r')
->addSelect('abteilung')
->addSelect('auto')
->join('r.auto','auto')
->join('r.abteilung','abteilung')
->where('r.mieteStart >= :date_from')
->andWhere('r.mieteEnde <= :date_to')
->setParameter('date_from', $date_from)
->setParameter('date_to', $date_to)
->orderBy('r.mieteStart', 'ASC')
->distinct()
->getQuery()->getArrayResult();
I tried with:
$rsm = new ResultSetMapping();
$rsm->addEntityResult('Chris\KfzBuchungBundle\Entity\Rent', 'bp');
$rsm->addEntityResult('Chris\Bundle\OldUserBundle\Entity\BpDepartment', 'bp_dpt');
$rsm->addFieldResult('bp','id','id');
$query = $this->getDoctrine()->getManager()->createNativeQuery('SELECT * FROM bp_department bp_dpt', $rsm);
$result = $query->getResult();
But same shit, i have no idea.

Symfony Doctrine findBy and then map

Basically I want to execute this mysql query with doctrine:
select distinct user_id from work_hour where project_id = ?;
But I don't know how I can do this with pretty Doctrine code. Is it possible to make it look like the following pseudo code or do I have to use the query builder?:
$project = new Project();
...
$entities = $em->getRepository('AppBundle:WorkHour')
->findByProject($project)->selectUser()->distinct();
Where $entities is an array of User objects
WorkHour and Project have a ManyToOne relation
WorkHour and User have a ManyToOne relation
You'll need to use a QueryBuilder for that, but that would still be quite a "pretty Doctrine code" and would still look quite like your pseudo-code.
Something like this should work:
$queryBuilder = $em->createQueryBuilder();
$query = queryBuilder
->select('u')
->distinct()
->from('AppBundle:User', 'u')
->join('AppBundle:WorkHour', 'wh')
->where('u.workHour = wh')
->andWhere('wh.project = :project')
->getQuery();
$query->setParameter(':project', $project);
$entities = $query->getResult();
public function findByProject($project)
{
$qb = $this->getEntityManager()->createQueryBuilder('User');
$qb
->select('User')
->from('Path\Bundle\Entity\User', 'User')
->join('Path\Bundle\Entity\WorkHour', 'wh',
'WITH', 'User.workHour = wh')
->where('wh.project = :project'))
->distinct()
->setParameter('project', $project)
;
$query = $qb->getQuery();
return $query->getResult();
}
If you have a complicated query you should do it in QueryBuilder, it'll be more efficient.
http://doctrine-orm.readthedocs.org/en/latest/reference/query-builder.html
If you have complicated queries you shouldn't do it directly into the controller, it shouldn't know this logic, you have to do it in the repository and call it from there

How to perform a join query using Symfony and Doctrine Query Builder

I have two entities which are connected through a 1:1 relationship, e.g: MyEntity.idRelatedEntity
I want to create a Doctrine query where I can retrieve data from MyEntity depending on a value from a certain column in RelatedEntity. Something like this (it doesn't work of course):
$entity = $em
->getRepository('MyBundle:RelatedEntity')
->createQueryBuilder('e')
->leftJoin('MyBundle:RelatedEntity', 'r')
->where('r.foo = 1')
->getQuery()
->getResult();
Any help would be much appreciated :)
$entity = $em
->getRepository('MyBundle:MyEntity')
->createQueryBuilder('e')
->join('e.idRelatedEntity', 'r')
->where('r.foo = 1')
->getQuery()
->getResult();
Also left join makes no sense here (because of where clause that will make it work like inner join)
Note that you should write this query in your MyEntityRepository
public function getMyEntityWithRelatedEntity($parameter)
{
$query = $this->createQueryBuilder('e')
->addSelect('r') // to make Doctrine actually use the join
->leftJoin('e.relatedEntity', 'r')
->where('r.foo = :parameter')
->setParameter('parameter', $parameter)
->getQuery();
return $query->getResult();
}
And then use it in your controller/service :
$manager = $this->getDoctrine()->getManager();
$results = $manager->getRepository(MyEntity::class)->getMyEntityWithRelatedEntity(1);

Categories