Rework NativeSQL doc chapter and document SELECT clause generation (ref DDC-2055).
This commit is contained in:
parent
2ad6565632
commit
b2e29eaf97
@ -22,7 +22,7 @@ sys.path.append(os.path.abspath('_exts'))
|
|||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||||
extensions = ['configurationblock']
|
extensions = ['configurationblock', 'sphinx.ext.linkcode']
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
@ -192,3 +192,10 @@ latex_documents = [
|
|||||||
|
|
||||||
# If false, no module index is generated.
|
# If false, no module index is generated.
|
||||||
#latex_use_modindex = True
|
#latex_use_modindex = True
|
||||||
|
|
||||||
|
primary_domain = "dcorm"
|
||||||
|
|
||||||
|
def linkcode_resolve(domain, info):
|
||||||
|
if domain == 'dcorm':
|
||||||
|
return 'http://'
|
||||||
|
return None
|
||||||
|
@ -1,17 +1,21 @@
|
|||||||
Native SQL
|
Native SQL
|
||||||
==========
|
==========
|
||||||
|
|
||||||
A ``NativeQuery`` lets you execute native SELECT SQL statements, mapping the results
|
With ``NativeQuery`` you can execute native SELECT SQL statements
|
||||||
according to your specifications. Such a specification that
|
and map the results to Doctrine entities or any other result format
|
||||||
describes how a SQL result set is mapped to a Doctrine result is
|
supported by Doctrine.
|
||||||
represented by a ``ResultSetMapping``. It describes how each column
|
|
||||||
of the database result should be mapped by Doctrine in terms of the
|
|
||||||
object graph. This allows you to map arbitrary SQL code to objects,
|
|
||||||
such as highly vendor-optimized SQL or stored-procedures.
|
|
||||||
|
|
||||||
Because writing ``ResultSetMapping`` is not so simple, there is a convenience
|
In order to make this mapping possible, you need to describe
|
||||||
wrapper around it called a ``ResultSetMappingBuilder``. The last section
|
to Doctrine what columns in the result map to which entity property.
|
||||||
of this chapter describes its usage.
|
This description is represented by a ``ResultSetMapping`` object.
|
||||||
|
|
||||||
|
With this feature you can map arbitrary SQL code to objects, such as highly
|
||||||
|
vendor-optimized SQL or stored-procedures.
|
||||||
|
|
||||||
|
Writing ``ResultSetMapping`` from scratch is complex, but there is a convenience
|
||||||
|
wrapper around it called a ``ResultSetMappingBuilder``. It can generate
|
||||||
|
the mappings for you based on Entities and even generates the ``SELECT``
|
||||||
|
clause based on this information for you.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -25,14 +29,75 @@ The NativeQuery class
|
|||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
To create a ``NativeQuery`` you use the method
|
To create a ``NativeQuery`` you use the method
|
||||||
``EntityManager#createNativeQuery($sql, $resultSetMapping)``. As
|
``EntityManager#createNativeQuery($sql, $resultSetMapping)``. As you can see in
|
||||||
you can see in the signature of this method, it expects 2
|
the signature of this method, it expects 2 ingredients: The SQL you want to
|
||||||
ingredients: The SQL you want to execute and the
|
execute and the ``ResultSetMapping`` that describes how the results will be
|
||||||
``ResultSetMapping`` that describes how the results will be
|
|
||||||
mapped.
|
mapped.
|
||||||
|
|
||||||
Once you obtained an instance of a ``NativeQuery``, you can bind
|
Once you obtained an instance of a ``NativeQuery``, you can bind parameters to
|
||||||
parameters to it and finally execute it.
|
it with the same API that ``Query`` has and execute it.
|
||||||
|
|
||||||
|
.. code-block:: php
|
||||||
|
|
||||||
|
<?php
|
||||||
|
use Doctrine\ORM\Query\ResultSetMapping;
|
||||||
|
|
||||||
|
$rsm = new ResultSetMapping();
|
||||||
|
// build rsm here
|
||||||
|
|
||||||
|
$query = $entityManager->createNativeQuery('SELECT id, name, discr FROM users WHERE name = ?', $rsm);
|
||||||
|
$query->setParameter(1, 'romanb');
|
||||||
|
|
||||||
|
$users = $query->getResult();
|
||||||
|
|
||||||
|
ResultSetMappingBuilder
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
An easy start into ResultSet mapping is the ``ResultSetMappingBuilder`` object.
|
||||||
|
This has several benefits:
|
||||||
|
|
||||||
|
- The builder takes care of automatically updating your ``ResultSetMapping``
|
||||||
|
when the fields or associations change on the metadata of an entity.
|
||||||
|
- You can generate the required ``SELECT`` expression for a builder
|
||||||
|
by converting it to a string.
|
||||||
|
- The API is much simpler than the usual ``ResultSetMapping`` API.
|
||||||
|
|
||||||
|
One downside is that the builder API does not yet support entities
|
||||||
|
with inheritance hierachies.
|
||||||
|
|
||||||
|
.. code-block:: php
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
||||||
|
|
||||||
|
$sql = "SELECT u.id, u.name, a.id AS address_id, a.street, a.city " .
|
||||||
|
"FROM users u INNER JOIN address a ON u.address_id = a.id";
|
||||||
|
|
||||||
|
$rsm = new ResultSetMappingBuilder($entityManager);
|
||||||
|
$rsm->addRootEntityFromClassMetadata('MyProject\User', 'u');
|
||||||
|
$rsm->addJoinedEntityFromClassMetadata('MyProject\Address', 'a', 'u', 'address', array('id' => 'address_id'));
|
||||||
|
|
||||||
|
The builder extends the ``ResultSetMapping`` class and as such has all the functionality of it as well.
|
||||||
|
|
||||||
|
..versionadded:: 2.4
|
||||||
|
|
||||||
|
Starting with Doctrine ORM 2.4 you can generate the ``SELECT`` clause
|
||||||
|
from a ``ResultSetMappingBuilder``. You can either cast the builder
|
||||||
|
object to ``(string)`` and the DQL aliases are used as SQL table aliases
|
||||||
|
or use the ``generateSelectClause($tableAliases)`` method and pass
|
||||||
|
a mapping from DQL alias (key) to SQL alias (value)
|
||||||
|
|
||||||
|
.. code-block:: php
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$selectClause = $builder->generateSelectClause(array(
|
||||||
|
'u' => 't1',
|
||||||
|
'g' => 't2'
|
||||||
|
));
|
||||||
|
$sql = "SELECT " . $selectClause . " FROM users t1 JOIN groups t2 ON t1.group_id = t2.id";
|
||||||
|
|
||||||
|
|
||||||
The ResultSetMapping
|
The ResultSetMapping
|
||||||
--------------------
|
--------------------
|
||||||
@ -369,35 +434,6 @@ are actually a subtype of User. When using DQL, Doctrine
|
|||||||
automatically includes the necessary joins for this mapping
|
automatically includes the necessary joins for this mapping
|
||||||
strategy but with native SQL it is your responsibility.
|
strategy but with native SQL it is your responsibility.
|
||||||
|
|
||||||
ResultSetMappingBuilder
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
There are some downsides with Native SQL queries. The primary one is that you have to adjust all result set mapping
|
|
||||||
definitions if names of columns change. In DQL this is detected dynamically when the Query is regenerated with
|
|
||||||
the current metadata.
|
|
||||||
|
|
||||||
To avoid this hassle you can use the ``ResultSetMappingBuilder`` class. It allows to add all columns of an entity
|
|
||||||
to a result set mapping. To avoid clashes you can optionally rename specific columns when you are doing the same
|
|
||||||
in your sQL statement:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
|
||||||
|
|
||||||
$sql = "SELECT u.id, u.name, a.id AS address_id, a.street, a.city " .
|
|
||||||
"FROM users u INNER JOIN address a ON u.address_id = a.id";
|
|
||||||
|
|
||||||
$rsm = new ResultSetMappingBuilder($entityManager);
|
|
||||||
$rsm->addRootEntityFromClassMetadata('MyProject\User', 'u');
|
|
||||||
$rsm->addJoinedEntityFromClassMetadata('MyProject\Address', 'a', 'u', 'address', array('id' => 'address_id'));
|
|
||||||
|
|
||||||
For entities with more columns the builder is very convenient to use. It extends the ``ResultSetMapping`` class
|
|
||||||
and as such has all the functionality of it as well. Currently the ``ResultSetMappingBuilder`` does not support
|
|
||||||
entities with inheritance.
|
|
||||||
|
|
||||||
|
|
||||||
Named Native Query
|
Named Native Query
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user