Commit 00b84277 authored by zYne's avatar zYne

some docs for hydration

parent 195dff3e
......@@ -59,6 +59,79 @@ This is due to a fact that $user->GroupUser loads all group links for given user
++ Component overview
++ Fetching objects
Normally when you fetch data from database the following phases are executed:
1. Sending the query to database
2. Retrieve the returned data from the database
In terms of object fetching we call these two phases the 'fetching' phase. Doctrine also has another phase called hydration phase. The hydration phase takes place whenever you are fecthing structured arrays / objects. Unless explicitly specified everything in Doctrine gets hydrated.
Lets consider we have users and phonenumbers with their relation being one-to-many. Now consider the following plain sql query:
<code type="php">
$dbh->fetchAll('SELECT u.id, u.name, p.phonenumber FROM user u LEFT JOIN phonenumber p ON u.id = p.user_id');
</code>
If you are familiar with these kind of one-to-many joins it may be familiar to you how the basic result set is constructed. Whenever the user has more than one phonenumbers there will be duplicated data in the result set. The result set might look something like:
<code>
index | u.id | u.name | p.phonenumber |
0 | 1 | Jack Daniels | 123 123 |
1 | 1 | Jack Daniels | 456 456 |
2 | 2 | John Beer | 111 111 |
3 | 3 | John Smith | 222 222 |
4 | 3 | John Smith | 333 333 |
5 | 3 | John Smith | 444 444 |
</code>
Here Jack Daniels has 2 phonenumbers, John Beer has one whereas John Smith has 3 phonenumbers. You may notice how clumsy this result set is. Its hard to iterate over it as you would need some duplicate data checkings here and there.
Doctrine hydration removes all duplicated data. It also performs many other things such as:
# Custom indexing of result set elements
# Value casting and preparation
# Value assignment listening
# Makes multi-dimensional array out of the two-dimensional result set array, the number of dimensions is equal to the number of nested joins
Now consider the DQL equivalent of the SQL query we used:
<code type="php">
$array = $conn->query('SELECT u.id, u.name, p.phonenumber FROM User u LEFT JOIN u.Phonenumber p',
array(), Doctrine::HYDRATE_ARRAY);
</code>
The structure of this hydrated array would look like:
<code>
array(0 => array('id' => 1,
'name' => 'Jack Daniels',
'Phonenumber' =>
array(0 => array('phonenumber' => '123 123'),
1 => array('phonenumber' => '456 456'))),
1 => array('id' => 2,
'name' => 'John Beer',
'Phonenumber' =>
array(0 => array('phonenumber' => '111 111'))),
2 => array('id' => 3,
'name' => 'John Smith',
'Phonenumber' =>
array(0 => array('phonenumber' => '111 111')),
2 => array('phonenumber' => '222 222'),
3 => array('phonenumber' => '333 333'))));
</code>
This structure also applies to the hydration of objects(records) which is the default hydration mode of Doctrine. The only differences are that the individual elements are represented as Doctrine_Record objects and the arrays converted into Doctrine_Collection objects. Whether dealing with arrays or objects you can:
# Iterate over the results using //foreach//
# Access individual elements using array access brackets
# Get the number of elements using //count()// function
# Check if given element exists using //isset()//
# Unset given element using //unset()//
You should always use array hydration when you only need to data for access-only purposes, whereas you should use the record hydration when you need to change the fetched data.
The constant O(n) performance of the hydration algorithm is ensured by a smart identifier caching solution.
+++ Field lazy-loading
Whenever you fetch an object that has not all of its fields loaded from database then the state of this object is called proxy. Proxy objects can load the unloaded fields lazily.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment