Search code examples
doctrine-ormdoctrinezend-framework3

Doctrine returning strange field names from query


I am using "doctrine/doctrine-orm-module": "^2.1" (it is a module for zend framework 3). I want to create a query which will return rows with field names (trivial, right?). But instead of exact names of fields I am getting this query result:

SELECT 
    u0_.id AS id_0, u0_.username AS username_1, u0_.email AS email_2, 
    u0_.first_name AS first_name_3, u0_.last_name AS last_name_4, 
    u0_.password AS password_5, u0_.status AS status_6, u0_.created AS created_7, 
    u0_.modified AS modified_8 
FROM 
    user_item u0_ 
ORDER BY 
    u0_.id DESC

This query is generated by this code:

    $entityManager = $this->getEntityManager();

    $queryBuilder = $entityManager->createQueryBuilder();

    $queryBuilder->select('u')
        ->from(UserItem::class, 'u')
        ->orderBy('u.id', 'DESC')
    ;

    $query = $queryBuilder->getQuery();

    echo $query->getSql();
    print_r($query->getParameters());
    die('|||');

What is the "0_" appending to the table name? What is appendings "_x" to the fields name?

How can I get normal fields and tables names without appended "_x"?


Solution

  • Just names, I'm assuming both the first_name and last_name as shown in that generated SQL, right?

    I changed the order below, makes it easier to read / understand.

    What you want to do is (pseudo code): Select from UserItem all the first & last names

    So, write the code that way :)

    $queryBuilder
        ->from(UserItem::class, 'u')
        ->select(['u.first_name', 'u.last_name'])
        ->orderBy('u.id', 'DESC'); // Might want to sort by either u.first_name or u.last_name
    

    What's in the QueryBuilder?

    • ->from(UserItem::class, 'u') - First parameter is the FQCN (Fully Qualified Class Name) of the Entity you wish to use with the QueryBuilder. Not required is the second parameter, which is an alias to use for this instance of the QueryBuilder to recognize the FQCN defined class by. (Off of the top of my head it defaults to snake_case'd names of the class, in this case "user_item")

    • ->select(['u.first_name', 'u.last_name']) - Function takes a "mixed" param. Click through to its definition and you'll see the following in the function:

      $selects = is_array($select) ? $select : func_get_args();

    Which indicates that it will always pass the "$selects" on the next bit as an array. (Another hint is that $selects is plural)

    • ->orderBy('u.id', 'DESC') - Creates a rule to order results by. If you click through to this function, you'll see that this one ends like so:

      return $this->add('orderBy', $orderBy);

    Meaning: you can add more than 1 order by.


    When it comes to the generated DQL:

    • u0_ is the table alias as defined in the DQL, from your question: FROM user_item u0_, this will later be transformed to MySQL (usually) which will be the same. It sets u0_ as an alias for user_item.

    • The _* appended to property names is just plain the order of the columns as they've been created in the database (have a look, they'll be in that order).

    • Lastly, the fact you were receiving entire entities and not just the names (first_name & last_name) is due to ->select('u'). Because no property (or properties as shown above) is defined, Doctrine assumes you wish to receive the whole enchalada. Doing ->select('u.first_name') would then get you just the first names, and using an array as above would get you more than 1 property.


    Hope that helped you out :)