Active Record vs Data Mapper

Active Record

ORM frameworks using Active Record
  • Ruby on Rails
  • Laravel’s Eloquent
  • Django’s ORM
Explanation (Laravel Eloquent)

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.

<?php
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
}
Benefits

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.

Drawbacks
  • Active Record has lots database coupling (and testing). Because your database is so tightly coupled with your objects, you’ll have a hard time efficiently separating the two. Surely a good active record implementation is likely to make it pretty quick for you to switch from MySQL to Postgres, but it’ll not make it easy to use your objects without the database. The fact that most active record model-based systems are effectively impossible to separate (for testing or other reasons) is often held against them.

  • Performance bottlenecks of Active Record. A very similar complaint about the active record pattern is that you’ll have a hard time dealing with performance bottlenecks when they arise. For small web-apps with a few hundred users this generally isn’t an issue, but the lack of SQL efficiencies that more complex systems of separation between your system objects and your database allow are a big road block as Active Record-based applications grow.

Data Mapper

ORM frameworks using data mapper
  • Java Hibernate
  • Symfony Doctrine
  • SQLAlchemy in Python
Explanation (Symfony Doctrine)

Here’s a basic model, unlike Eloquent (active record) you must explicitly define:

class User {
    private $name;
 
    // Because the Symfony convention stresses making properties private or protected, it’s also important to make methods of access. Getters and setters are by far the most common method:
 
    public function getName(): ?string
    {
        return $this->name;
    }
}

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->name = "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.

Benefits
  • Data Mappers allow for greater flexibility between domain and database. As we mentioned above, one of the prototypical reasons that you’ll want to use a data mapper is that you as the application architect do not actually have final say on the database scheme. Where you’ve got a historical database, or a new database with an unfriendly gatekeeper, the data mapper pattern allows you to hide the ways in which you database isn’t an ideal way to think about your domain behind the whole data-mapping layer.

  • Data mappers can be much more performant. Similarly, because you do have a layer of abstraction and indirection between your domain objects and your database, there’s a good possibility that you can have the data mapper make more efficient use of the database than a naive active record implementation would allow.

Drawbacks
  • Often intimidating and hard to set-up. The advantage of active record is that you build your database schema and objects side-by-side, so when you’ve got one you’ve got the other. Because the data mapper pattern is deeper than that, you’re inherently going to have to think a little harder to configure your data mapping layer than you will a practically-invisible active record layer.

Reference

ORM Patterns: The Trade-Offs of Active Record and Data Mappers for Object-Relational Mapping - Thoughtful Code What’s the difference between Active Record and Data Mapper? | Culttt Active Record vs Data Mapper - HackMD mysql - Is Data Mapper a more modern trend than Active Record - Stack Overflow