@@ -976,7 +976,7 @@ The Query class
976976---------------
977977
978978An instance of the ``Doctrine\ORM\Query `` class represents a DQL
979- query. You create a Query instance be calling
979+ query. You create a Query instance by calling
980980``EntityManager#createQuery($dql) ``, passing the DQL query string.
981981Alternatively you can create an empty ``Query `` instance and invoke
982982``Query#setDQL($dql) `` afterwards. Here are some examples:
@@ -993,58 +993,146 @@ Alternatively you can create an empty ``Query`` instance and invoke
993993 $q = $em->createQuery();
994994 $q->setDQL('select u from MyProject\Model\User u');
995995
996- Query Result Formats
997- ~~~~~~~~~~~~~~~~~~~~
996+ Query Result Formats (Hydration Modes)
997+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
998+
999+ The way in which the SQL result set of a DQL SELECT query is transformed
1000+ to PHP is determined by the so-called "hydration mode".
1001+
1002+ ``getResult() ``
1003+ ^^^^^^^^^^^^^^^
1004+
1005+ Retrieves a collection of objects. The result is either a plain collection of objects (pure) or an array
1006+ where the objects are nested in the result rows (mixed):
1007+
1008+ .. code-block :: php
1009+
1010+ <?php
1011+ use Doctrine\ORM\AbstractQuery;
1012+
1013+ $query = $em->createQuery('SELECT u FROM User u');
1014+ $users = $query->getResult();
1015+ // same as:
1016+ $users = $query->getResult(AbstractQuery::HYDRATE_OBJECT);
1017+
1018+ - Objects fetched in a FROM clause are returned as a Set, that means every
1019+ object is only ever included in the resulting array once. This is the case
1020+ even when using JOIN or GROUP BY in ways that return the same row for an
1021+ object multiple times. If the hydrator sees the same object multiple times,
1022+ then it makes sure it is only returned once.
1023+
1024+ - If an object is already in memory from a previous query of any kind, then
1025+ then the previous object is used, even if the database may contain more
1026+ recent data. This even happens if the previous object is still an unloaded proxy.
1027+
1028+ ``getArrayResult() ``
1029+ ^^^^^^^^^^^^^^^^^^^^
1030+
1031+ Retrieves an array graph (a nested array) for read-only purposes.
1032+
1033+ .. note ::
1034+
1035+ An array graph can differ from the corresponding object
1036+ graph in certain scenarios due to the difference of the identity
1037+ semantics between arrays and objects.
1038+
1039+ .. code-block :: php
1040+
1041+ <?php
1042+ $users = $query->getArrayResult();
1043+ // same as:
1044+ $users = $query->getResult(AbstractQuery::HYDRATE_ARRAY);
1045+
1046+ ``getScalarResult() ``
1047+ ^^^^^^^^^^^^^^^^^^^^^
1048+
1049+ Retrieves a flat/rectangular result set of scalar values that can contain duplicate data. The
1050+ pure/mixed distinction does not apply.
1051+
1052+ .. code-block :: php
1053+
1054+ <?php
1055+ $users = $query->getScalarResult();
1056+ // same as:
1057+ $users = $query->getResult(AbstractQuery::HYDRATE_SCALAR);
1058+
1059+ Fields from classes are prefixed by the DQL alias in the result.
1060+ A query of the kind `SELECT u.name ... ` returns a key `u_name ` in the result rows.
1061+
1062+ ``getSingleScalarResult() ``
1063+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
1064+
1065+ Retrieves a single scalar value from the result returned by the database. If the result contains
1066+ more than a single scalar value, a ``NonUniqueResultException `` is thrown. The pure/mixed distinction does not apply.
1067+
1068+ .. code-block :: php
1069+
1070+ <?php
1071+ $query = $em->createQuery('SELECT COUNT(u.id) FROM User u');
1072+ $numUsers = $query->getSingleScalarResult();
1073+ // same as:
1074+ $numUsers = $query->getResult(AbstractQuery::HYDRATE_SINGLE_SCALAR);
1075+
1076+ ``getSingleColumnResult() ``
1077+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
1078+
1079+ Retrieves an array from a one-dimensional array of scalar values:
1080+
1081+ .. code-block :: php
1082+
1083+ <?php
1084+ $query = $em->createQuery('SELECT a.id FROM User u');
1085+ $ids = $query->getSingleColumnResult();
1086+ // same as:
1087+ $ids = $query->getResult(AbstractQuery::HYDRATE_SCALAR_COLUMN);
1088+
1089+ ``getSingleResult() ``
1090+ ^^^^^^^^^^^^^^^^^^^^^
1091+
1092+ Retrieves a single object. If the result contains more than one object, a ``NonUniqueResultException ``
1093+ is thrown. If the result contains no objects, a ``NoResultException `` is thrown. The pure/mixed distinction does not apply.
1094+
1095+ ``getOneOrNullResult() ``
1096+ ^^^^^^^^^^^^^^^^^^^^^^^^
1097+
1098+ Retrieves a single object. If the result contains more than one object, a ``NonUniqueResultException ``
1099+ is thrown. If no object is found, ``null `` will be returned.
1100+
1101+ Custom Hydration Modes
1102+ ^^^^^^^^^^^^^^^^^^^^^^
1103+
1104+ You can easily add your own custom hydration modes by first
1105+ creating a class which extends ``AbstractHydrator ``:
1106+
1107+ .. code-block :: php
1108+
1109+ <?php
1110+ namespace MyProject\Hydrators;
1111+
1112+ use Doctrine\ORM\Internal\Hydration\AbstractHydrator;
1113+
1114+ class CustomHydrator extends AbstractHydrator
1115+ {
1116+ protected function _hydrateAll()
1117+ {
1118+ return $this->_stmt->fetchAllAssociative();
1119+ }
1120+ }
9981121
999- The format in which the result of a DQL SELECT query is returned
1000- can be influenced by a so-called ``hydration mode ``. A hydration
1001- mode specifies a particular way in which a SQL result set is
1002- transformed. Each hydration mode has its own dedicated method on
1003- the Query class. Here they are:
1004-
1005-
1006- - ``Query#getResult() ``: Retrieves a collection of objects. The
1007- result is either a plain collection of objects (pure) or an array
1008- where the objects are nested in the result rows (mixed).
1009- - ``Query#getSingleResult() ``: Retrieves a single object. If the
1010- result contains more than one object, an ``NonUniqueResultException ``
1011- is thrown. If the result contains no objects, an ``NoResultException ``
1012- is thrown. The pure/mixed distinction does not apply.
1013- - ``Query#getOneOrNullResult() ``: Retrieve a single object. If the
1014- result contains more than one object, a ``NonUniqueResultException ``
1015- is thrown. If no object is found null will be returned.
1016- - ``Query#getArrayResult() ``: Retrieves an array graph (a nested
1017- array) that is largely interchangeable with the object graph
1018- generated by ``Query#getResult() `` for read-only purposes.
1019-
1020- .. note ::
1021-
1022- An array graph can differ from the corresponding object
1023- graph in certain scenarios due to the difference of the identity
1024- semantics between arrays and objects.
1025-
1026-
1027-
1028- - ``Query#getScalarResult() ``: Retrieves a flat/rectangular result
1029- set of scalar values that can contain duplicate data. The
1030- pure/mixed distinction does not apply.
1031- - ``Query#getSingleScalarResult() ``: Retrieves a single scalar
1032- value from the result returned by the dbms. If the result contains
1033- more than a single scalar value, an exception is thrown. The
1034- pure/mixed distinction does not apply.
1035-
1036- Instead of using these methods, you can alternatively use the
1037- general-purpose method
1038- ``Query#execute(array $params = [], $hydrationMode = Query::HYDRATE_OBJECT) ``.
1039- Using this method you can directly supply the hydration mode as the
1040- second parameter via one of the Query constants. In fact, the
1041- methods mentioned earlier are just convenient shortcuts for the
1042- execute method. For example, the method ``Query#getResult() ``
1043- internally invokes execute, passing in ``Query::HYDRATE_OBJECT `` as
1044- the hydration mode.
1045-
1046- The use of the methods mentioned earlier is generally preferred as
1047- it leads to more concise code.
1122+ Next you just need to add the class to the ORM configuration:
1123+
1124+ .. code-block :: php
1125+
1126+ <?php
1127+ $em->getConfiguration()->addCustomHydrationMode('CustomHydrator', 'MyProject\Hydrators\CustomHydrator');
1128+
1129+ Now the hydrator is ready to be used in your queries:
1130+
1131+ .. code-block :: php
1132+
1133+ <?php
1134+ $query = $em->createQuery('SELECT u FROM CmsUser u');
1135+ $results = $query->getResult('CustomHydrator');
10481136
10491137 Pure and Mixed Results
10501138~~~~~~~~~~~~~~~~~~~~~~
@@ -1148,165 +1236,6 @@ will return the rows iterating the different top-level entities.
11481236 [2] => Object (User)
11491237 [3] => Object (Group)
11501238
1151-
1152- Hydration Modes
1153- ~~~~~~~~~~~~~~~
1154-
1155- Each of the Hydration Modes makes assumptions about how the result
1156- is returned to user land. You should know about all the details to
1157- make best use of the different result formats:
1158-
1159- The constants for the different hydration modes are:
1160-
1161-
1162- - ``Query::HYDRATE_OBJECT ``
1163- - ``Query::HYDRATE_ARRAY ``
1164- - ``Query::HYDRATE_SCALAR ``
1165- - ``Query::HYDRATE_SINGLE_SCALAR ``
1166- - ``Query::HYDRATE_SCALAR_COLUMN ``
1167-
1168- Object Hydration
1169- ^^^^^^^^^^^^^^^^
1170-
1171- Object hydration hydrates the result set into the object graph:
1172-
1173- .. code-block :: php
1174-
1175- <?php
1176- $query = $em->createQuery('SELECT u FROM CmsUser u');
1177- $users = $query->getResult(Query::HYDRATE_OBJECT);
1178-
1179- Sometimes the behavior in the object hydrator can be confusing, which is
1180- why we are listing as many of the assumptions here for reference:
1181-
1182- - Objects fetched in a FROM clause are returned as a Set, that means every
1183- object is only ever included in the resulting array once. This is the case
1184- even when using JOIN or GROUP BY in ways that return the same row for an
1185- object multiple times. If the hydrator sees the same object multiple times,
1186- then it makes sure it is only returned once.
1187-
1188- - If an object is already in memory from a previous query of any kind, then
1189- then the previous object is used, even if the database may contain more
1190- recent data. Data from the database is discarded. This even happens if the
1191- previous object is still an unloaded proxy.
1192-
1193- This list might be incomplete.
1194-
1195- Array Hydration
1196- ^^^^^^^^^^^^^^^
1197-
1198- You can run the same query with array hydration and the result set
1199- is hydrated into an array that represents the object graph:
1200-
1201- .. code-block :: php
1202-
1203- <?php
1204- $query = $em->createQuery('SELECT u FROM CmsUser u');
1205- $users = $query->getResult(Query::HYDRATE_ARRAY);
1206-
1207- You can use the ``getArrayResult() `` shortcut as well:
1208-
1209- .. code-block :: php
1210-
1211- <?php
1212- $users = $query->getArrayResult();
1213-
1214- Scalar Hydration
1215- ^^^^^^^^^^^^^^^^
1216-
1217- If you want to return a flat rectangular result set instead of an
1218- object graph you can use scalar hydration:
1219-
1220- .. code-block :: php
1221-
1222- <?php
1223- $query = $em->createQuery('SELECT u FROM CmsUser u');
1224- $users = $query->getResult(Query::HYDRATE_SCALAR);
1225- echo $users[0]['u_id'];
1226-
1227- The following assumptions are made about selected fields using
1228- Scalar Hydration:
1229-
1230-
1231- 1. Fields from classes are prefixed by the DQL alias in the result.
1232- A query of the kind 'SELECT u.name ..' returns a key 'u_name' in
1233- the result rows.
1234-
1235- Single Scalar Hydration
1236- ^^^^^^^^^^^^^^^^^^^^^^^
1237-
1238- If you have a query which returns just a single scalar value you can use
1239- single scalar hydration:
1240-
1241- .. code-block :: php
1242-
1243- <?php
1244- $query = $em->createQuery('SELECT COUNT(a.id) FROM CmsUser u LEFT JOIN u.articles a WHERE u.username = ?1 GROUP BY u.id');
1245- $query->setParameter(1, 'jwage');
1246- $numArticles = $query->getResult(Query::HYDRATE_SINGLE_SCALAR);
1247-
1248- You can use the ``getSingleScalarResult() `` shortcut as well:
1249-
1250- .. code-block :: php
1251-
1252- <?php
1253- $numArticles = $query->getSingleScalarResult();
1254-
1255- Scalar Column Hydration
1256- ^^^^^^^^^^^^^^^^^^^^^^^
1257-
1258- If you have a query which returns a one-dimensional array of scalar values
1259- you can use scalar column hydration:
1260-
1261- .. code-block :: php
1262-
1263- <?php
1264- $query = $em->createQuery('SELECT a.id FROM CmsUser u');
1265- $ids = $query->getResult(Query::HYDRATE_SCALAR_COLUMN);
1266-
1267- You can use the ``getSingleColumnResult() `` shortcut as well:
1268-
1269- .. code-block :: php
1270-
1271- <?php
1272- $ids = $query->getSingleColumnResult();
1273-
1274- Custom Hydration Modes
1275- ^^^^^^^^^^^^^^^^^^^^^^
1276-
1277- You can easily add your own custom hydration modes by first
1278- creating a class which extends ``AbstractHydrator ``:
1279-
1280- .. code-block :: php
1281-
1282- <?php
1283- namespace MyProject\Hydrators;
1284-
1285- use Doctrine\ORM\Internal\Hydration\AbstractHydrator;
1286-
1287- class CustomHydrator extends AbstractHydrator
1288- {
1289- protected function _hydrateAll()
1290- {
1291- return $this->_stmt->fetchAllAssociative();
1292- }
1293- }
1294-
1295- Next you just need to add the class to the ORM configuration:
1296-
1297- .. code-block :: php
1298-
1299- <?php
1300- $em->getConfiguration()->addCustomHydrationMode('CustomHydrator', 'MyProject\Hydrators\CustomHydrator');
1301-
1302- Now the hydrator is ready to be used in your queries:
1303-
1304- .. code-block :: php
1305-
1306- <?php
1307- $query = $em->createQuery('SELECT u FROM CmsUser u');
1308- $results = $query->getResult('CustomHydrator');
1309-
13101239 Iterating Large Result Sets
13111240~~~~~~~~~~~~~~~~~~~~~~~~~~~
13121241
0 commit comments