aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Webontwikkeling

Eloquent vs Query Builder: wanneer welke

Wanneer je in Laravel de datalaag opzet, is de eerste grote keuze die je tegenkomt die tussen de Eloquent ORM en de query builder; het duo eloquent query builder rust eigenlijk op dezelfde basis maar werkt op verschillende abstractieniveaus. Eloquent koppelt tabellen aan modelobjecten en brengt relaties, events en mutators met zich mee. De query builder daarentegen blijft via een vloeiende interface veel dichter bij SQL. Er is geen eenduidig antwoord op de vraag welke de "juiste" is: het juiste antwoord hangt af van wat de taak voor je daadwerkelijk is.

Beide delen dezelfde kern

Een belangrijk punt: Eloquent is bovenop de query builder gebouwd. Wanneer je where() op een model aanroept, bereik je in feite achter de schermen een query builder-instantie. Eloquent is dus geen "traag alternatief" — het is een hoger niveau dat een objectlaag, relatiebeheer en model-events bovenop de query builder toevoegt. Het prestatieverschil komt niet van de engine zelf, maar van het werk dat die extra laag doet: elke rij omzetten in een PHP-object (hydratie) en relaties beheren kost iets.

Wanneer Eloquent uitblinkt

Eloquent springt er duidelijk uit in CRUD-scenario's waarin de businesslogica centraal staat en je een klein tot gemiddeld aantal records leest en schrijft. Leesbaarheid en onderhoudbaarheid zijn hier de echte winst:

  • Relaties: je bereikt gerelateerde data in één regel zoals $user->posts; met with() doe je eager loading en los je het N+1-queryprobleem op.
  • Model-events: events zoals creating en saved, observers en mutators/casts draaien automatisch.
  • Soft deletes, timestamps, scopes: de meeste herhaalde logica wordt op één plek verzameld via traits en scopes.
// Voorkom N+1 met eager loading
$posts = Post::with('author', 'comments')
    ->where('published', true)
    ->latest()
    ->get();

foreach ($posts as $post) {
    echo $post->author->name; // geen extra query
}

Wanneer de query builder beter is

De query builder komt in beeld wanneer je het modelgedrag niet nodig hebt en prestaties cruciaal zijn. Rapporten over duizenden rijen, bulk-updates, complexe join- en aggregatiequery's zijn precies zijn domein. Omdat hij niet elke rij in een modelobject omzet, is hij lichter qua geheugen en CPU.

// Een directe, lichte rapportagequery
$stats = DB::table('orders')
    ->select('user_id', DB::raw('SUM(total) as total'))
    ->where('created_at', '>=', now()->subMonth())
    ->groupBy('user_id')
    ->having('total', '>', 1000)
    ->get();

Hier wil je sowieso geen modelobject, relatie of event; je wilt alleen de getallen optellen en teruggeven. De query builder doet dit zonder hydratie-overhead en geeft stdClass-objecten terug.

Denk aan de prestatieafweging in cijfers

In de praktijk is het verschil zelden voelbaar bij het ophalen van één record; het draait allemaal om schaal. Er is geen meetbare kloof tussen 50 rijen ophalen met Eloquent of met de query builder. Maar als je over 50.000 rijen loopt voor een exporttaak, verbruikt het aanmaken van een model voor elke rij serieus geheugen. Een paar praktische regels:

  • Grote leesbewerkingen + verwerking: stream rijen met de query builder of de cursor()/lazy()-methoden van Eloquent in plaats van alles in het geheugen te laden.
  • Bulk-updates: Model::where(...)->update([...]) draait als één query maar vuurt geen model-events af; gebruik het in dat besef.
  • Als je maar een paar kolommen nodig hebt: beperk de kolommen met select() zelfs in Eloquent; onnodige data ophalen vertraagt de hydratie.
// Verwerk 50.000 rijen zonder ze in het geheugen op te stapelen
Order::where('exported', false)
    ->lazy()
    ->each(function ($order) {
        // één model tegelijk, weinig geheugen
    });

Beide samen gebruiken is de meest realistische weg

In plaats van een goed/fout-dilemma gebruiken de meeste projecten beide. CRUD en formulierverwerking met Eloquent schrijven terwijl je zware dashboardquery's aan de query builder overlaat, binnen dezelfde applicatie, is volkomen normaal. Je kunt zelfs waar nodig binnen Eloquent afdalen naar ruwe SQL met whereRaw() of selectRaw(), en de prestaties bijstellen terwijl je de modelvoordelen behoudt. Wanneer je naar ruwe query's afdaalt, verwaarloos de parameterbinding niet; gebruik zoals whereRaw('price > ?', [$min]) beschermt je tegen SQL-injectie.

Vragen om te stellen bij het beslissen

  • Zijn relaties, events of casts nodig voor deze taak? Zo ja, Eloquent.
  • Hoeveel rijen komen er terug, en ga ik ze allemaal in objecten omzetten? Zo veel, query builder of lazy().
  • Is dit een hot path (draait het bij elk verzoek)? Zo ja, meet en vereenvoudig indien nodig.
  • Is leesbaarheid of een milliseconde waardevoller? Voor de meeste schermen wint leesbaarheid.

Veelgestelde vragen

Is Eloquent echt trager dan de query builder?

Het is niet de engine op zich — het omzetten van elke rij in een PHP-object (hydratie) en het beheren van relaties zijn wat het vertraagt. Bij weinig records is het verschil onmerkbaar; over duizenden rijen is de query builder merkbaar lichter.

Kan ik ruwe SQL gebruiken binnen Eloquent?

Ja. Je kunt ruwe fragmenten toevoegen met whereRaw(), selectRaw() en DB::raw(). Geef waarden altijd door via parameterbinding in plaats van strings direct samen te voegen.

Welke moet mijn standaardkeuze zijn?

Begin met Eloquent; de code blijft schoner en gemakkelijker te onderhouden. Zodra je profileert en een knelpunt vindt, verplaats je die specifieke query naar de query builder of een streaming-methode.

Is de datalaag van je Laravel-app traag, of weet je gewoon niet waar te beginnen? Ik kan je helpen een schaalbare architectuur te bouwen die Eloquent en de query builder op de juiste plekken inzet. Neem contact op om over je project te praten.

Bu kategorideki tüm yazılar →

Devamı için