Home » Code » What’s the difference between Active Record and Data Mapper?

What’s the difference between Active Record and Data Mapper?

Posted by on June 18th, 2014

What's the difference between Active Record and Data Mapper
When it comes to working with data in an application, you are probably going to need an ORM in one form or another. An ORM is the layer between the database and your application. By using an ORM, a lot of the hard work of creating, updating, reading and deleting from the database is taken care for us.

I think for the most part, you don’t need to worry about what type of ORM you are using. The majority of modern frameworks usually ship with an ORM out of the box. Laravel for instance ships with Eloquent.

However as you delve deeper into how applications are designed and built and you start to work on applications that have specific characteristics, it’s worth exploring the different types of ORMs that you have available to you.

The two most popular implementations of ORM are Active Record and Data Mapper. In this article I’m going to be exploring the differences between the two patterns, what are the benefits and drawbacks of choosing one over the other and what you should consider when working with an ORM in your own projects.

What is an ORM and why do you need one?

Before I jump into the weeds of explaining the difference between Active Record and Data Mapper, first let me explain what an ORM is and why you need one.

An ORM (Object Relational Mapper) is the layer that sits between your database and your application. In Object Oriented Programming, you work with Objects as your main point of reference.

So for example you might have the following object:

$user = new User;
$user->name = 'philipbrown';

However databases such as MySQL can only store values as strings and integers:

+----+-------------+
| id | username    |
+----+-------------+
| 1  | philipbrown |
+----+-------------+

A User might have many posts within our application. To retrieve the user’s posts, we might do something like this:

$posts = $user->posts;

However, in the database, the posts would be stored in a table, like this:

+----+---------+-------+
| id | user_id | title |
+----+---------+-------+
| 1  | 2       | "..." |
+----+---------+-------+

When working with objects in our application, we work with a single object that stores all of the object’s properties and relationships.

However that data is stored as individual values across many tables in a database.

An ORM is the magic layer that transforms data in the form of objects into relational data that can be stored in a database and vice versa.

Now that I’ve explained what an ORM is and why you would want to use one, lets now look at the two most popular implementations of ORM, Active Record and Data Mapper.

What is the Active Record pattern?

The first ORM pattern I will look at is probably also the most popular, Active Record.

If you have ever used a framework such as Ruby on Rails or Laravel, you will probably be already familiar with the Active Record style of ORM.

A typical usage example of Active Record would be:

$user = new User;
$user->username = 'philipbrown';
$user->save();

In the example above I’m creating a new User object, setting the username and then saving the object to the database.

Active Record style ORMs map an object to a database row. In the example above, we would be mapping the User object to a row in the users table.

When you crack open the User model file, you will notice that you don’t have to specify the properties of the object and how they relate to the database. With Active Record style ORMs, the model is able to determine the properties of the model automatically by looking at the schema of the database.

One of the benefits of the Active Record style is that you can simple call the save() method on the object to update the database. Each model object inherits from a base Active Record object and so you have access to all the methods relating to persistence. This makes the Active Record style very easy to get started with because it is very intuitive.

What is the Data Mapper pattern?

The big difference between the Active Record style and the Data Mapper style is, the Data Mapper style completely separates your domain from the persistence layer. This means none of your model objects know anything about the database.

When using the Data Mapper style, your code will look something like this:

$user = new User;
$user->username = 'philipbrown';

So far, not that different to the Active Record style.

However, Data Mapper model objects are just plain PHP objects that have no knowledge of the database. This means we can’t call the save() method on the object to persist it to the database because it doesn’t exist.

Instead we need to use a completely different service known as an Entity Manager:

$user = new User;
$user->username = 'philipbrown';
EntityManager::persist($user);

The big benefit of the Data Mapper pattern is, your domain objects don’t need to know anything about how they are stored in the database. This means that your objects will be lighter because they don’t have to inherit the full ORM, but also there will be a stricter, more formal process for interacting with the database because you can’t just call the save() method anywhere in your code.

What are the differences between Active Record and Data Mapper?

Now that I’ve briefly covered the difference between Active Record and the Data Mapper patterns, now I will talk about the benefits and drawbacks of using each style.

I think both Active Record and Data Mapper have both positives and negatives and I definitely don’t think that one pattern is better than the other. As with just about everything else in programming, I think the right answer for choosing which pattern to use is “it depends”.

With that in mind, I think there are two main areas where you should judge which pattern is right for you.

The type of application you are building

The first thing to think about is, what type of application you are building.

I think generally speaking, there are two types of web application, CRUD based applications and Domain based applications.

A CRUD based application is where your code maps cleanly to a database. Typically you will be creating, reading, updating and deleting entities. You might also have relationships between your models, but for the most part, there isn’t really strict rules around how those relationships should be enforced.

When you are building an application that has this kind of “database mindset”, Active Record is the perfect solution. Active Record will allow you to quickly and easily get up and running with a working application.

If however, your application is not built with this “database mindset”, but rather, you are building an application to satisfy the rules and procedures of a business, the Data Mapper pattern might be a better choice. The Data Mapper pattern will enforce certain restrictions of dealing with data and persistence, and it will allow you to encapsulate those business rules within your entities.

The application and the environment you are building it in

Secondly, I think the nature of the application and the environment you are building it in should also be a factor when basing your decision on which pattern to use.

If you are building an Minimum viable product application to test the waters of a new market, I think it makes more sense to use the Active Record pattern. At the outset you don’t know what business rules are going to be important and you never will if you obsess over the architecture of your application.

On the other hand, if you have been brought into an existing business to build a new application from a legacy system, I think it usually makes more sense to use the Data Mapper pattern. An existing business will already have rules and procedures around how their business works. By using the Active Record pattern you will end up trying to force those business rules to play nicely with the “database mindset” of Active Record. The Data Mapper pattern will allow you to encapsulate the domain rules of the business so working with the application is clear and intuitive.

Conclusion

I strongly believe that both the Active Record and the Data Mapper patterns have a place within our developer tool belts. I think it is wrong to categorically say that one pattern is better than the other. Hopefully I’ve shown in this article that each pattern has a time and a place.

Choosing the wrong pattern for an application will always be a mistake, but you can’t blame the tools at your disposal. By being aware of the different methods and ideologies of patterns such as Active Record or Data Mapper, we can make better, more informed decisions on the tools we choose for the current project.

This article has been mostly theory without any real practical examples. If you want to see an excellent, practical tutorial on the differences between Active Record and Data Mapper, I would highly recommend reading How We Code: ORMs and Anemic Domain Models by Chris Fidao.

Philip Brown

Hey, I'm Philip Brown, a designer and developer from Durham, England. I create websites and web based applications from the ground up. In 2011 I founded a company called Yellow Flag. If you want to find out more about me, you can follow me on Twitter or Google Plus.

  • I’m just wondering if you know of any open source projects that are using Laravel and the data mapper pattern? I’d like to see it in the context of an actual project.

  • Pingback: Getting started with Doctrine 2 and Laravel | Culttt()

  • alireza Rahmani khalili

    Awesome Article

  • Pingback: Encapsulating your application's business rules | Culttt()

  • liuggio

    data mapper promotes single responsibility principle, and a bunch of other principles of DDD. active record is something from the past :)

    • Yes that is correct about The Data Mapper pattern. However, Active Record is still a very important part of application development. It’s about choosing the right tool for the job, and The Data Mapper pattern is only the right tool in certain circumstances.

      • liuggio

        > The Data Mapper pattern is only the right tool in certain circumstances

        Ehm I think is the opposite if you want a quick and run project and you don’t care about design: Active Record is the tool.

        • Yes exactly, so The Data Mapper pattern would not be the right tool in that circumstance.

          • liuggio

            No data mapper is a right tool but if you don’t care about patterns with a quick and dirty solution you can use AR.

          • shawn haggard

            Are u dumb?

  • Donald Zhan

    Nice article. Gave me a lots help.

  • lijinma

    A very good article, thanks a lot.

  • Paul

    Thanks for writing this article, really makes clear the difference between the two.

  • Milton Dehara

    Interesting article, it solved many of my questions!

  • Romaldy Minaya

    Thanks @philip_brown:disqus :)

  • Doctrine is far better then Eloquent, it comes with so many helpers like findBy & many while eloquent have only few.

    • Hmm, I don’t think the helper methods are really the benefit to using Doctrine.

      • Yeah ok, tell me what if i want to find a user by email i have to write query or query builder in elequent , where i have to pass table name and column name and all stuff in my DAO Class which i dont want, no abstraction at all, so what is the use of ORM? it should have helper methods like hibernate have so that it can minimize the use of queries and can provide us a better abstraction.

        • You would only have to write $user = User::where('email', $email)->first();

    • Mateus Azevedo

      In Eloquent you can use User::whereName($name)…
      It uses magic methods and works the same as findBy.

  • Benedikt

    I have an ongoing PHP project since ’99 and as I will be forced to adopt my code of which parts are in plain old functional php style with mysql_* functions used directly in the functions, I try to avoid mistakes on decisions when refactoring the code, which will anyway take me weeks and I just want to do it once.

    Therefore I read about OOP, patterns, especially the repository pattern, ORMs (active record and data mapper style) and database wrapping classes for PDO and mysqli about a month now and I feel I have to make decisions soon.

    I have read that there is still no common sense that ORMs are definitely the way to go in any case. I have sql queries that have 50 lines but very fast on large data sets and I just can’t imagine that an ORM can build them as efficiently as I did. Also it horrifies me that I have to set them in an ORM specific syntax and maybe in half a year I find out that another ORM would have been the better choice.

    So I tend to stick with a PDO wrapping class, actually the one you suggested in an article years ago: http://culttt.com/2012/10/01/roll-your-own-pdo-php-class/

    My questions:
    1) Do you think that this can be reasonable in anyway or is this just crazy (old fashioned sql freaky) me?

    2) I have difficulties to find a good example for a repository pattern used for database interaction without the use of an ORM. Also your examples all incorporate an ORM. Do you know of any?
    3) If you say, it is absolutely no good idea to stay without an ORM, what are peoples plans to avoid much work once they want to switch to another ORM?

    • 1. Yeah I don’t think it’s a terrible decision to use PDO directly. And yeah, it’s often easier to write the specific query you want as SQL, rather than trying to pack it into an ORM.

      2. You would just create repositories that are baked by PDO rather than an ORM. It would be basically the same, you would just have to deal with converting into your Domain Objects.

      3. When switching ORM, you would basically just creating a new implementation of your repositories. So you would just drop what you have, create a new implementation, and make sure all of your tests still pass.

  • Matin Rezaei

    great article !
    I just started learning eloquent and that was nice info!
    thanks

  • Gaston

    Great article! Thanks

  • Pritamkumar Bohra

    @philip_brown:disqus excellent article. It cleared lot of my doubts. Looking forward to read more of such wonderful articles.

  • Pratso

    Hi @philip_brown:disqus could you please give some examples of Domain based applications??

    • Every application is a Domain based application. For example, if you were creating a website for a small business, the domain of the application would be the rules and procedures that the business must follow.

  • hfatahi

    I’ve been learning about ORMs and this article was very helpful. I have a question thought. What are other ORM implementations, other than Active Record and Data Mapper?
    Thanks

    • Thank you :) Hmm, I think for the most part you’re probably only ever going to be using Active Record or Data Mapper.

  • Giorgio

    Would it be counterproductive to use both patterns at the same time? For instance, having a save() method on the domain object that delegates to a data mapper the actual persistence work (e.g. DataMapper::persist(this)).
    In this way you hide from the client the complexity in most of the cases, but you also have major flexibility when you need it.
    Does this make any sense?

    • Ah yeah that makes sense. You would still be coupled to the method of persisting the data to the database. The save() method would need to know about the Entity Manager, and so your domain object would no longer be a plain old PHP class.

  • Alexandre

    If you read the Fowler´s book on enterprise patterns, you going to be surprised on how wrong your definitions of Active Record and Data Mapper are. In fact, it is the metadata mapping that discusses about reading the schema from databases, specifying by hand, and so forth.
    Saying “you will notice that you don’t have to specify the properties of the object and how they relate to the database” has nothing to do with Active Record, but how you work with metadata.
    The fundamental difference is Active record has a “save” method in the domain. This means, your domain class extends ActiveRecord base class.
    In the datamapper, the save (and other persistence related operations) is NOT at the domain class, but in the mapper class ( sometimes it is a generic mapper repository, such as the session of Hibernate). The domain class is not coupled to the persistence/mapper layer.

  • Pingback: Alternative Laravel Migration Menggunakan Doctrine - Rohman Notes()

  • Pingback: Alternative Laravel Migration Menggunakan Laravel-Doctrine - Rohman Notes()