Data Mapper Architecture
The Data Mapper pattern separates your domain objects from database persistence. Entities contain business logic and data, while a separate mapper layer — the EntityManager — handles storage and retrieval.
How It Works
The Data Mapper pattern separates your domain objects from the database. Entities hold data and business logic; the database holds records. The EntityManager sits between them, handling all persistence operations so neither side needs to know about the other. The pattern allows you to instantiate, test, and reuse entities without a database connection.
<?php
class ProductEntity {
private ?int $productId = null;
private string $name;
private float $price;
// Business logic lives here
public function applyDiscount(float $percent): void {
$this->price = $this->price * (1 - $percent / 100);
}
// Getters and setters
public function getProductId(): ?int { return $this->productId; }
public function getName(): string { return $this->name; }
public function setName(string $name): void { $this->name = $name; }
public function getPrice(): float { return $this->price; }
public function setPrice(float $price): void { $this->price = $price; }
}
Database operations go through the EntityManager:
<?php
$entityManager = new EntityManager($connection, $config);
// Creating
$product = new ProductEntity();
$product->setName('Wireless Mouse');
$product->setPrice(29.99);
$entityManager->persist($product);
$entityManager->flush();
// Updating
$product = $entityManager->find(ProductEntity::class, 123);
$product->applyDiscount(10);
$entityManager->persist($product);
$entityManager->flush();
The entity never knows it's being stored. It doesn't know what database it lives in, what table it maps to at runtime, or when it gets saved. The EntityManager owns that responsibility entirely.