This article explains the core functionalities and some key features of an object-relational mapping (ORM) framework working through some simple examples. For these examples, we use Doctrine 2 as the example ORM.
Introduction
First of all, let us discuss the reason we need an ORM to develop our application. What are the benefits of an ORM? As developers, we often work and deal with objects. In the traditional database world, however, these data are maintained as table records (relational databases). A developer prefers working with these data in an object level rather than in the underlying record level. An ORM will work in the middle as a mapper between these two layers.
Association Mapping
When we work in the database level, how do we manage the relationships among objects? (From now on, we will use the word entity to refer to an object.) We will use the following example to take you through this explanation.
Example 1:
A customer can place as many orders as he wants, but an order cannot be shared among multiple customers. So the relationship is a one-to-many relationship, where the "many side" is the order.
Inner Workings
The ORM (in this case, Doctrine 2) will, maintain a table for each of your entities, map each field of your entity to a column of the respective table. Things become more interesting when it comes to holding the associations among different entities. Fundamentally, there can be two types of associations.
- Reference to a single entity is maintained using a foreign key.
- Reference to a collection of entities is maintained by keeping the foreign key to the holding entity, in each of the entities in the collection. (This is further explained below.)
Owning and Inverse Sides of an Association
To put in a nutshell, owning side is the side of the relationship, we prefer to deal with (We choose that side, so that we can look at the relationship form its perspective more easily.) Consider the customer-order example above. In the business world, our natural instinct suggests that, the Customer is the owning side of the association. In other words, the customer owns the order(s).
But in the database world, it is the other way around. Rather than keeping a pointer inside the Customer to each and every order he has placed, it is more convincing to keep a single pointer inside each and every order, to the customer who owns it. (Yes, that is what is done the database management systems. You will keep the foreign key in the Order table, not the other way around!)
So here, the owning side is the Order, and the inverse side is the Customer. In one-to-many associations, this is often the case. However in one-to-one and many--to-many types, it is up to you to decide on the owning side of the association (and yes, you have to figure out from which entity's perspective you are going to look at the association).
Example 2:
Consider the example of the article-tag relationship. There can be multiple articles under the same tag, and there can be multiple tags attached to a single article. So, do you want to get the articles under a particular tag, or do you want to get the tags attached to a particular article? It is totally up to you.
Note:
The bottom line is, when you are dealing with the owning entity of an association, the relationship is handled by the framework. However if you want to deal with inverse side, you will need some workaround to get things working.
The use of ORM frameworks have become popular in web and mobile solution development. Java's Hibernate is the biggest competitor around. Doctrine 2 for PHP, OrmLite for Android are some other popular object-relational frameworks.
My friend mentioned to me your blog, so I thought I’d read it for myself. Very interesting insights, will be back for more!
ReplyDeleteORM