How to retrieve a Doctrine record with all relational records? - doctrine

I was wondering if there is a way to get a record with all relational data, something like a 'Deep-Fetch'
So if a model Child were related to another model Parent,
can we fetch Child & then access Child->Parent->name thru a single query?
Doctrine today fires a query whenever a relationship is accessed. Is this too costly? does it need to be optimizeD?
thanks

Doctrine automatically hydrates related objects when you select fields from that relations:
Doctrine_Query::create()
->select('a.*, c.*)
->from('Article a')
->innerJoin('Category c');
In this example both Article and Category objects are being hydrated (no additional queries are made).

Related

Laravel - How to relate two collections like Eloquent method "belongsToMany" and "with"

How can you combine two collections, one being the collection of parent items together combined with your collection of child items?
I would like something like using the method with and belongsToMany,but in this scenario I cannot use both methods correctly because one table is in another schema and the pivot table is in another schema.
Area::with('permissoes')
->where('sistema', '<>', 'S')
->get()
Most Eloquent eagerloads are done with separate queries that just use an IN statement on keys from the previous one. Pivot tables are the exception. It sounds like you need to explicitly tell the Model relation what database your pivot table is in. See my answer here: belongsToMany relationship in Laravel across multiple databases

How Eloquent ORM creates its data structure on eager loading

I have been looking into eloquent's source code to see how it manages building its data structure when eager loaded with one or more relationships specified but I have not been successful.
For instance:
User has many photos, and a photo belongs to a User
How does eloquent perform its SQL query?
Does it make multiple SQL? A query to get the user and then another one to get his/her photo, or does it perform a single query.
I am also interested to see the structure of the SQL, because I have tried lots of options and there is absolutely no way I could tell what tables each field belonged to because the returned result is just plain array of objects.
Laravel will create at least two queries when you'll try to use eager loading.
For example, this code:
$users = User::with('photos')->get();
Will produce two queries similar to these:
select * from `users` where `users`.`deleted_at` is null
select * from `photos` where `photos`.`user_id` in ('1', '2', ... '99')
I'd recommend you to use Laravel Debugbar, if you want to better understand how raw SQL queries look like.
Sometimes using toSql() in php artisan tinker tool is also helpful:
\App\User::where('id', 2)->toSql()

Laravel Eloquent model data from 2 tables

I've just started using Laravel and I'm coming from a different system using an existing database. In this system there are 2 users table, one stock with the CMS and one custom one.
I want to create an Eloquent model which retrieves data from both tables into one model. I know I can use the following to create a relationship.
$this->hasOne('App\SecondUser', 'id', 'id);
But this results in 2 sql queries, and I want to join results from 2 tables before returning the model, in one join statement. How do I do this?
That might be a bit more complicated that you would expect.
First of all you have to use \DB facade to join the two collections(arrays) and then recreate the Eloquent collection from these arrays using Collection's make method.
More info about the Collection class here
An easier way might be to join them using standard laravel relationships and user something like Model::user->with('relation')->get.
But this will still create 2 queries (still relatively fast).

JPA OneToMany and Getting children with a single query

I notice that in hibernate, it queries the child collections of entities an entity at a time. So, for example, I have a Person entity with a OneToMany relationship with PhoneNumber as well as a OneToMany relationship with EmailAddress. If I do a simple query on the Person entity that returns 1,000 people then hibernate will make 1,000 queries to EmailAddress and 1,000 queries to PhoneNumber. Let's forget about eager or lazy fetching for a minute and assume I will be accessing the phone and email collections of every person.
This seems like a naive implementation. Is there a simple way to change this so there is only 1 query into PhoneNumber and only 1 query into EmailAddress? These should be put into a map keyed by their Person foreign key so they are easily retrieved by the Person getter methods.
Any thoughts besides doing a brute force query into the session cache for emails and phone numbers BEFORE executing the Person query?
TIA, let me know if you need additional data.
Apart for doing the queries by yourself, you could simply enable batch fetching, as described in the documentation:
You can also enable batch fetching of collections. For example, if each Person has a lazy collection of Cats, and 10 persons are currently loaded in the Session, iterating through all persons will generate 10 SELECTs, one for every call to getCats(). If you enable batch fetching for the cats collection in the mapping of Person, Hibernate can pre-fetch collections:

code igniter datamapper join get()

I am using this join in my code igniter model
$this->db->select('e.name, p.projects');
$this->db->from('example as e');
$this->db->join('procure as p', e.id = p.id');
$this->db->where('e.cityid', '1');
$this->db->where('e.status', '0');
I do not have separate table for join. Here is my data mapper, this is not giving any output.
I have two tables and I want to write a join query on them.I have this in my controller.
$example = new Example();
$example ->where_join_field('procure', FALSE);
Update
can you show me the snippet for joining three tables using data mapper.
Generally you don't do joins by hand with DMZ models (the sql generated will use joins nonetheless). The thing you are looking for is Relations.
You have to set up your model's relations, using the $has_one and $has_many attributes, keeping the naming conventions, creating the necessary tables for many-to-many and so on. You can read about these in the docs here and here.
Once you got your models set up, you can use the where_related and include_related methods where you have used joins before:
where_related is for when you want to filter the models you are querying on some related model's field values. So if you have a related project set up on your Example class, you can write ->where_related('project', 'procure', false); and it will filter the returned Example instances based on their related project's procedure field. So basically it's the same conditionals that you would put into the where SQL clause.
include_related is for when you want to include fields from related models or even whole instance. So if you write ->include_related('project', 'projects') when you query Example instances you will end up with a project_projects attribute on the returned instances. There are many options to control how these attributes should be created. Basically these are the fields you would have put into the select SQL clause.
There are magic methods created for every named relation and many other options, i refer you to the Get (Advanced) page of the documentation for start and free to explore the other pages describing relations.

Resources