Doctrine
01 / 02

Doctrine Fundamentals: Entities, EntityManager & DQL

Doctrine: Entities, EntityManager & DQL

Doctrine ORM is an Object-Relational Mapping library for PHP, most commonly associated with Symfony. It lets developers work with database records as PHP objects (entities) rather than writing raw SQL directly -- similar in role to TypeORM/Prisma for Node.js or Entity Framework for .NET.

Defining an Entity

#[ORM\Entity]
#[ORM\Table(name: 'users')]
class User
{
    #[ORM\Id]
    #[ORM\GeneratedValue]  // auto-incrementing, no manual assignment needed
    #[ORM\Column]
    private int $id;

    #[ORM\Column(type: 'string', length: 255)]
    private string $email;

    #[ORM\Column(type: 'datetime')]
    private \DateTime $createdAt;
}

EntityManager: persist() & flush()

$user = new User();
$user->setEmail('alice@example.com');

// persist() marks the entity for saving -- no SQL executed yet
$entityManager->persist($user);

// flush() batches ALL pending changes into actual SQL statements,
// executed against the database in one go (the Unit of Work pattern)
$entityManager->flush();

// Doctrine auto-detects a property change and generates the UPDATE
$user->setEmail('newemail@example.com');
$entityManager->flush();  // no explicit "update" call needed

DQL: Object-Oriented Queries

// Queries entity classes/properties, not raw table/column names --
// Doctrine compiles this to the actual SQL for the configured database
$query = $entityManager->createQuery(
    'SELECT u FROM App\Entity\User u WHERE u.email = :email'
)->setParameter('email', 'alice@example.com');

$user = $query->getOneOrNullResult();

Repositories

// Centralizes entity-specific query logic, rather than scattering
// similar DQL across many parts of the application
class UserRepository extends ServiceEntityRepository
{
    public function findActiveUsersInRegion(string $region): array
    {
        return $this->createQueryBuilder('u')
            ->andWhere('u.region = :region')
            ->andWhere('u.isActive = true')
            ->setParameter('region', $region)
            ->getQuery()
            ->getResult();
    }
}

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free