Definition
Un ORM (Object-Relational Mapping) est une technique de programmation qui cree un "pont" entre les objets d'un langage de programmation et les tables d'une base de donnees relationnelle. L'ORM traduit automatiquement les operations sur les objets en requetes SQL.
Au lieu d'ecrire du SQL brut, vous manipulez des objets dans votre langage favori, et l'ORM genere le SQL correspondant.
Pourquoi utiliser un ORM ?
Avantages
- Productivite : moins de code repetitif, auto-completion
- Type safety : detection d'erreurs au compile time (TypeScript, Java)
- Portabilite : changer de SGBD sans reecrire les requetes
- Migrations : versionner le schema de la base de donnees
- Protection : prevention automatique des injections SQL
- Relations : gestion simplifiee des jointures et associations
Inconvenients
- Performance : requetes N+1 si mal utilise
- Abstraction fuyante : certaines requetes complexes necessitent du SQL brut
- Courbe d'apprentissage : chaque ORM a sa propre API
- Debug : plus difficile de comprendre le SQL genere
ORM populaires par langage
| Langage | ORM | Type |
|---|---|---|
| TypeScript/JS | Drizzle | Type-safe, SQL-like |
| TypeScript/JS | Prisma | Schema-first, type-safe |
| TypeScript/JS | TypeORM | Decorator-based |
| Python | SQLAlchemy | Full-featured, flexible |
| Python | Django ORM | Integre a Django |
| Java | Hibernate/JPA | Standard enterprise |
| PHP | Eloquent | Integre a Laravel |
| C# | Entity Framework | Integre a .NET |
| Go | GORM | Struct-based |
| Ruby | Active Record | Convention over config |
Exemple comparatif : Drizzle vs SQL brut
// Drizzle ORM (type-safe)
const users = await db.select()
.from(usersTable)
.where(eq(usersTable.active, true))
.leftJoin(ordersTable, eq(usersTable.id, ordersTable.userId))
.orderBy(desc(usersTable.createdAt))
.limit(20);
// SQL equivalent
const users = await sql\`
SELECT * FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.active = true
ORDER BY u.created_at DESC
LIMIT 20
\`;
Le probleme N+1
Le piege classique des ORM : charger une liste d'objets, puis charger les relations une par une.
// MAUVAIS : N+1 requetes (1 pour les users + N pour les commandes)
const users = await db.select().from(usersTable);
for (const user of users) {
user.orders = await db.select().from(ordersTable).where(eq(ordersTable.userId, user.id));
}
// BON : 1 seule requete avec jointure ou eager loading
const users = await db.select().from(usersTable)
.leftJoin(ordersTable, eq(usersTable.id, ordersTable.userId));
Tendance actuelle
La tendance en 2026 est aux ORM "type-safe" et "SQL-like" comme Drizzle qui offrent le meilleur des deux mondes : la securite des types et la clarte du SQL.