Active Record vs Data Mapper

Database patterns, such as Active Record or Data Mapper has been misunderstood by many beginner developers. Knowing the differences is extremely important, considering the fact majority of website interact with a database.

If you have been using ORMs such as Doctrine or Propel. You have definitely come to the terms Active Record or Data Mapper. It is important to know the meaning of each and when to integrate one of them.

Active Record

In Active Record your class directly maps to the database table.

Dealing CRUD operations using Active Record pattern is extremely fast. For example, in Laravel when your model extends Eloquent you are mapping it to the database table. Yes, Laravel provides the feature to choose another table name but yet you’re still mapping it directly to the database table.

In Laravel

class User extends Eloquent
{
}

In ORMs

class User extends Database
{
 public $firstname;
 public $lastname;
 public $age;
}

Since, we are extending a database class our class can easily perform create, update, delete or read operations. This makes developing very fast but sadly in big projects active record creates problems. Such as

  • when your table schema changes you need to modify your code. If column name changes in the database table from age to yearOfBirth you need to rename age to yearOfBirth everywhere in your code.
  • Mapping a class directly to a database table is not a very secure. Someone might create a User and pass wrong values.

Data Mapper Pattern

Unlike, Active Record which your CRUD operation can be done easily in Data Mapper you need to write the code for the CRUD operations. Data Mapper results in writing more code but in long term, it is easier to maintain and modify.

From the diagram, we can conclude that we have two classes. User and UserMapper. User is a entity class which has no idea of from database is mapped or retrieved. The UserMapper fetches the data from the database which can be of any type and binds it to the User class.

To implement Datamapper pattern, we would need to create a Users Entity class.

Entity is an independent class which does not extends or depends on any other class

class Users
{
 public $firstName;
 public $lastName;
 public $age;
}

Now that we have an entity class User we would need to create a mapper. To map this entity to a table. The good part of data mapper is that we get decide how we want to map.

class UsersMapper
{
   public static function findById($id)
   {
      // we retrieve the result from database via query
      $query = "SELECT * FROM users WHERE id = $id";
       // we create an instance of the User entity
       // and map it to its members
      $user = new Users();
      $user->firstname = $databaseResult['first_name'];
      $user->lastName = $databaseResult['last_name'];
      $user->age = $databaseResult['age'];
      return $user;
   }
}

As you can see we have written the code to map. If the column name for first_name changes all we have to do is to modify it in the UsersMapper class. We can as-well perform validation in the Mapper class to make it more secure.

You might even store the first name, lastName into one column and while binding you assign it to firstName and lastName members

class UsersMapper
{
  public static function findById($id);
  {
      // we retrieve the result from
      //database via query
     $query =SELECT * FROM users WHERE id = $id;
     // we create an instance of the User entity
     // and map it to its members
     $user = new Users();
     $name = $databaseResult['name'];
     // we assume we are concatenating first name and
     //last name with a dash ex: Michael-Peterson&
     $name = explode('-', $name);
     $user->firstName = $name[0];
     $user->lastName = $name[1];
     $user->age = $databaseResult['age'];
     return $user;
  }
}

This is an another advantage of data mapper pattern.