@@ -976,7 +976,7 @@ The Query class
976
976
---------------
977
977
978
978
An 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
980
980
``EntityManager#createQuery($dql) ``, passing the DQL query string.
981
981
Alternatively you can create an empty ``Query `` instance and invoke
982
982
``Query#setDQL($dql) `` afterwards. Here are some examples:
@@ -993,58 +993,146 @@ Alternatively you can create an empty ``Query`` instance and invoke
993
993
$q = $em->createQuery();
994
994
$q->setDQL('select u from MyProject\Model\User u');
995
995
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
+ }
998
1121
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');
1048
1136
1049
1137
Pure and Mixed Results
1050
1138
~~~~~~~~~~~~~~~~~~~~~~
@@ -1148,165 +1236,6 @@ will return the rows iterating the different top-level entities.
1148
1236
[2] => Object (User)
1149
1237
[3] => Object (Group)
1150
1238
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
-
1310
1239
Iterating Large Result Sets
1311
1240
~~~~~~~~~~~~~~~~~~~~~~~~~~~
1312
1241
0 commit comments