Doctrine DQL or SQL
Developers that use Doctrine are often puzzled on what should they use for SELECT queries - DQL or SQL?
Short answer: both.
Long answer:
Official Doctrine documentation here says:
A common mistake for beginners is to mistake DQL for being just some form of SQL and therefore trying to use table names and column names or join arbitrary tables together in a query. You need to think about DQL as a query language for your object model, not for your relational schema.
That page clearly tells us: don't use DQL to built complicated and heavy queries.
But what about database independent code? Query building? You might ask...
For former question Doctrine has whole DBAL layer located in Doctrine\DBAL namespace, for latter it has Doctrine\DBAL\Query\QueryBuilder which builds pure SQL code in similar way as Doctrine\ORM\QueryBuilder builds DQL and A LOT! of developers don't even aware of its existence!
Believe me, I saw a few projects (including one that worth millions and has dozens of developers working on it!) where people do not even know that SQL builder exists and that according to the official documentation it is preferably to avoid build complex queries, but still, they write huge and slow running queries!
So my philosophy here is:
Short answer: both.
Long answer:
Official Doctrine documentation here says:
A common mistake for beginners is to mistake DQL for being just some form of SQL and therefore trying to use table names and column names or join arbitrary tables together in a query. You need to think about DQL as a query language for your object model, not for your relational schema.
That page clearly tells us: don't use DQL to built complicated and heavy queries.
But what about database independent code? Query building? You might ask...
For former question Doctrine has whole DBAL layer located in Doctrine\DBAL namespace, for latter it has Doctrine\DBAL\Query\QueryBuilder which builds pure SQL code in similar way as Doctrine\ORM\QueryBuilder builds DQL and A LOT! of developers don't even aware of its existence!
$qb = $this->connection->createQueryBuilder(); $qb->from('shipment', 's') ->where('s.shop_id = :shop_id') ->andWhere('s.shipment_status_time BETWEEN :from AND :to') ->setParameter('shop_id', $this->shop->getId()) ->setParameter('from', $this->from, Type::DATE) ->setParameter('to', $this->to, Type::DATE) ; if ($this->carrier) { $qb->andWhere('s.carrier_id = :carrier_id') ->setParameter('carrier_id', $this->carrier->getId()); } if ($this->country) { $qb->andWhere('s.customer_address_country_id = :county_id') ->setParameter('county_id', $this->country->getId()); }
Believe me, I saw a few projects (including one that worth millions and has dozens of developers working on it!) where people do not even know that SQL builder exists and that according to the official documentation it is preferably to avoid build complex queries, but still, they write huge and slow running queries!
So my philosophy here is:
- if you are not going to migrate to noSQL database it is quite possible to write DBAL query builder code that can be portable between SQL database platform
- almost any project at some point of its existence will require to write complex queries that require complex joins, grouping etc. So unless you are intended to migrate to completely different database engine - use SQL builder!
- it is very unlikely that even sticking only to DQL you will not experience any complications after database engine change
- DQL is very handy to write simple queries and get resulting object tree
- ask yourself - is query complex and requires arbitrary joins? If yes - use SQL query builder and if you need entities as a result of a query you can hydrate SQL query to entities using ResultSetMapping
- do you need entities or just pure data? If pure data only - use SQL query builder
DQL in practice not so good
ReplyDeletewe often kick put DQL and write that we need in SQL
any AS clause in DQL select broke DQL at all