简体   繁体   中英

DQL LEFT JOIN - sql example

well-functioning SQL is:

SELECT ro.id_role
       ,rr.id_role_resource
       ,re.id_resource
    FROM resource re
    LEFT JOIN role_resource rr
        ON rr.resource_id = re.id_resource
    LEFT JOIN role ro
        ON ro.id_role = rr.role_id

now I must write DQL- this is table shema:

role: id_role, name

role_resource: id_role_resource, role_id, resource_id, permission

resource: id_resource, controller,action ...

in the last table are no corresponding records in the table role_resource. That's why i need this left Join Query in DQL.

Normally if you would have an Resource entity with a $roles property and the correct annotations ( OneToMany , ManyToMany ) then your join table ( role_resource ) would not have or need and auto_increment id of its own.

This is because Doctrine handles association information and knows when a join table is needed based on them. Doctrine also knows what conditions to use when joining two entities based on the same association information.

So if an SQL query would join two tables via a third table by using 2 join clauses, a DQL query would only need to be told the association name and it would have all "join table" & "join conditions" information available.

So a simple query would look like:

SELECT
        /* i assume $idRole is the name of the property
         * mapped to the id_role column
         */
        ro.idRole,

        /* i assume $idResource is the name of the property
         * mapped to the id_resource column
         */
        re.idResource

FROM YourNamespace\Resource re
JOIN re.roles

With equivalent queryBuilder syntax:

$this->getEntityManager()->createQueryBuilder()
    ->select(array('ro.idRole', 're.idResource'))
    ->from('YourNamespace\Resource', 're')
    ->join('re.roles');

But JOIN defaults to an INNER JOIN so we would want to fix this by rewriting the query as:

SELECT  ro.idRole,
        re.idResource
FROM YourNamespace\Resource re
LEFT JOIN re.roles

With equivalent queryBuilder syntax:

$this->getEntityManager()->createQueryBuilder()
    ->select(array('ro.idRole', 're.idResource'))
    ->from('YourNamespace\Resource', 're')
    ->leftJoin('re.roles');

If however you want the role_resource table to have an auto_increment id of its own and be accessible in Doctrine queries, then Doctrine needs to know about that table -- it needs to be mapped to a separate entity and you need to explicitate the fact that you're joining Resources, RoleResources and Roles.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM