Using ResultSetMapping in Doctrine - php

I have a query like this:
$query = "select run_record_detail.id from
(select max(id) as run_record_id from run_record where delete_flag=0 group by test_run_id) rr
inner join
run_record_detail
on rr.run_record_id = rr.run_record_id
where delete_flag=0 and test_case_id IN (:ids)";
$rsm = new \Doctrine\ORM\Query\ResultSetMapping();
$rsm->addEntityResult('\Test\Entity\RunRecordDetail', 'run_record_detail');
$rsm->addFieldResult('run_record_detail', 'id', 'id');
$query = $this->getEntityManager()->createNativeQuery($query, $rsm);
$query->setParameter('ids', $testCaseIdArray);
$result = $query->getResult();
I am trying to use ResultsetMapping to bind run_record_detail to RunRecordDetail object. I want RunRecordDetail object in the output. But I am getting only its id(as I have selected ). Please help me getting this object.
I am following Doctrine doc http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html

Related

Add additional fields into doctrine result (DTO)

Im trying to get the best rated movies by average from my database and hydrate them nicely into a DTO with doctrine so i can work well later with it and integrate them e.g. into my api with api platform.
I already managed to get it work with a raw SQL query but i cannot manage to get it work with hydration into a DTO with doctrine.
namespace App\Repository;
use App\Entity\Movie;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
class MovieRepository extends ServiceEntityRepository
{
public function findBestRated()
{
$sql = "
SELECT m.*, AVG(Cast(r.rating as Decimal)) AS avg_rating, COUNT(r.id) AS count_rating
FROM `movie` m
JOIN rating r ON r.movie_id = m.id
GROUP BY m.id
ORDER BY avg_rating DESC
LIMIT 10
";
$connection = $this->getEntityManager()->getConnection();
$statement = $connection->prepare($sql);
$result = $statement->executeQuery();
return $result->fetchAllAssociative();
}
}
I would like to use a DTO like below:
namespace App\Dto;
use App\Entity\Movie;
class RatedMovie
{
public Movie $movie;
public float $averageRating;
public int $ratingCount;
public function __construct(Movie $movie, float $averageRating, int $ratingCount)
{
$this->movie = $movie;
$this->averageRating = $averageRating;
$this->ratingCount = $ratingCount;
}
}
I found some information on https://geek-week.imtqy.com/articles/en496166/index.html, but still i cannot get the hydration running. I already tried with ResultSetMapping and ResultSetMappingBuilder and a native doctrine query. With ResultSetMappingBuilder i can kind of simulate my raw sql query but the result is still an associative array and not mapped into the RatedMovie DTO.
public function findBestRated()
{
$rsm = new ResultSetMappingBuilder($this->getEntityManager());
$rsm->addScalarResult('id', 'movieId');
$rsm->addScalarResult('name', 'movieName');
$rsm->addScalarResult('avg_rating', 'averageRating', Types::FLOAT);
$rsm->addScalarResult('count_rating', 'countRating', Types::INTEGER);
$sql = "
SELECT m.*, AVG(r.rating) AS avg_rating, COUNT(r.id) AS count_rating
FROM `movie` m
JOIN rating r ON r.name_id = m.id
GROUP BY m.id
ORDER BY avg_rating DESC
LIMIT 10
";
$query = $this->getEntityManager()->createNativeQuery($sql, $rsm);
return $query->getResult();
}
I cannot get it running with newObjectMappings or the kind of strange syntax SELECT NEW DepartmentSalary(d.dept_no, avg_salary) FROM ... from the linked article. Any ideas?

How to write sql query in yii2

I have a raw sql query which i run using yii2 Yii::$app->db->createCommand() but then i wonder i how i can use yii's method of writing queries to actualize the same thing.
$m = "SELECT p.basic_plan_amt AS basic,p.premium_plan_amt AS premium,p.daju_plan_amt AS daju,c.name
AS country FROM price p LEFT JOIN country c ON p.country_id = c.id WHERE p.country_id = " .$country_id;
though the above query works well and provide expected result, but then how can i write the same query using the below format
$model = \backend\models\Price::find()->select([p.basic_plan_amt AS basic,p.premium_plan_amt AS
premium,p.daju_plan_amt AS daju,c.name
AS country])->where(['country_id' => $country_id])->all();
Below are the examples of query in yii hope it will help you More reference
Relation Model
$model = User::find()
->with('comments')
->all();
foreach ($model as $user) {
// get data from relation model
$comments = $user->comments;
......
foreach($comments as $comment){
........
}
}
joinWith()
Sample 1:
$model = User::find()
->joinWith('comments')
->all();
Sample 2:
$model = User::find()
->joinWith('comments')
->orderBy('tbl_comments_id.id, tbl_user.id')
->all();
innerJoinWith()
$model = User::find()
->innerJoinWith('comments', false)
->all();
// equivalent to the above
$model = User::find()
->joinWith('comments', false, 'INNER JOIN')
->all();
Join()
JOIN_TYPE = INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN etc
Syntax
$query = new Query;
$query ->select(['SELECT COLUMNS'])
->from('TABLE_NAME_1')
->join( 'JOIN_TYPE',
'TABLE_NAME_2',
'TABLE_NAME_2.COLUMN =TABLE_NAME_1.COLUMN'
);
$command = $query->createCommand();
$data = $command->queryAll();
Sample 1:
$query = new Query;
$query ->select([
'tbl_user.username AS name',
'tbl_category.categoryname as Category',
'tbl_document.documentname']
)
->from('tbl_user')
->join('LEFT OUTER JOIN', 'tbl_category',
'tbl_category.createdby =tbl_user.userid')
->join('LEFT OUTER JOIN', 'tbl_document',
'tbl_category.cid =tbl_document.did')
->LIMIT(5) ;
$command = $query->createCommand();
$data = $command->queryAll();
Output Query
SELECT `tbl_user`.`username` AS `name`, `tbl_category`.`categoryname` AS `Category`
FROM `tbl_user`
LEFT OUTER JOIN `tbl_category` ON tbl_category.createdby =tbl_user.userid
LEFT OUTER JOIN `tbl_document` ON tbl_category.cid =tbl_document.did
LIMIT 5
leftJoin()
Sample 1:
$query = new Query;
$query ->select(['tbl_user.username AS name', 'tbl_category.type as Category'])
->from('tbl_user')
->leftJoin('tbl_category', 'tbl_category.createdby = tbl_user.userid')
->limit(2);
$command = $query->createCommand();
$data = $command->queryAll();
Output Query
SELECT `tbl_user`.`username` AS `name`, `tbl_category`.`type` AS `Category`
FROM `tbl_user`
LEFT JOIN `tbl_category` ON tbl_category.createdby = tbl_user.useridd
LIMIT 2
use createcommand() method:
use yii\db\Query();
$connection = \Yii::$app->db;
$query = new Query;
$insql = $connection->createCommand("SELECT* FROM inventory );
$result=$insql->queryAll();
the above method list all data from the inventory table.

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 createNativeQuery, add count()

I have a query in a repository like :
$rsm = new ResultSetMapping;
$rsm->addEntityResult('\My\ProjectBundle\Entity\News', 't');
$rsm->addFieldResult('t', 'id', 'id');
$rsm->addMetaResult('t', 'account_id', 'account_id');
$qb = $this->_em->createNativeQuery(
'SELECT t.*
FROM news as t
LEFT JOIN
LEFT JOIN
WHERE
CONDITIONS CONDITIONS
',
$rsm
);
return $qb->getResult();
I simplified the above query which is used to retrieve the news that meet specific conditions.
I need to add a count() function to this query.
I have an other ManyToOne entity-relationship between Comment and News.
How to modify the query to get the comments number a given news has ?
I'm trying to add a left join to comment and add Count() in the select but I always get errors. How could I resolve this problem ?
Raw SQL with Doctrine is easier like this :
$em = $this->getDoctrine()->getManager()->getConnection();
$query = "
SELECT t.*
FROM news as t
LEFT JOIN
LEFT JOIN
WHERE
CONDITIONS CONDITIONS
";
$stmt = $em->prepare($query);
$stmt->execute();
$result = $stmt->fetchAll();

Propel filtering based on joined tables columns?

How do I filter based on a joined table's columns in Propel?
Like:
$results = FooQuery::create()->joinBar()->filterByBarSurname('surname');
You have to use use method as described in the doc:
$results = FooQuery::create()
->useBarQuery()
->filterBySurname('surname')
->endUse()
->find();
// example Query generated for a MySQL database
$query = 'SELECT foo.* from foo
INNER JOIN bar ON foo.BAR_ID = bar.ID
WHERE bar.SURNAME = :p1'; // :p1 => 'surname'
If you have to use join(), I don't think you can use filterByXXX method but the old where:
$results = FooQuery::create()
->join('Foo.Bar')
->where('Bar.surname = ?', 'surname')
->find();

Categories