Często przytaczany jest taki argument, że ORM daje warstwę abstrakcji nad używaną bazą danych i pozwala ją zmienić. To prawda, ale nie cała. W realnych aplikacjach, szczególnie tych złożonych, praktycznie nigdy nie zachodzi proces wymiany silnika bazodanowego. Jest to zwyczajnie teoretyczny, akademicki profit z korzystania z ORM, a w praktyce tego się nie robi. W złożonych systemach trzeba w którymś momencie zacząć wykorzystywać "ficzery" charakterystyczne dla używanego silnika bazodanowego. Również naprawdę duże, złożone zapytania do bazy trzeba w końcu pisać ręcznie, przynajmniej częściowo, wykorzystując elementy języka SQL specyficzne dla danej bazy, bo żaden query builder tego tak dobrze za programistę nie zrobi.
Dlatego uważam, że ta możliwość zmiany bazy, to trochę złudzenie, dzięki któremu czujemy się lepiej

A tu kilka innych przemyśleń w tym temacie.
1) Query builder to nie jest ORM. ORM to mapowanie danych przechowywanych w relacyjnej bazie danych, na obiekty wykorzystywane w programowaniu obiektowym. Sposób napisania zapytań do bazy, pobrania wyników i utworzenia z nich obiektów, to jest jedna rzecz, a zwracane obiekty, reprezentujące jakieś dane przechowywane w tejże bazie, to druga. W tej warstwie abstrakcji selecty mogą być tworzone w czystym SQLu, mogą za pomocą builderów, czy jeszcze inaczej - nie jest to ważne, ważne, żeby ta warstwa ORM zwróciła odpowiedni obiekt reprezentujący jakąś logiczną paczkę danych. Według mnie, trzeba te dwie rzeczy odróżniać, choć chyba wszystkie biblioteki ORM dostarczają od razu różnego rodzaju query buildery więc może się wydawać, że query builder to ORM, bo w takich bibliotekach query buildery są zintegrowane z ORMem i czasem nawet nie dają możliwości pobrania czystego SQLa, który został zbudowany (sic!).
2) Wykorzystanie query builderów jest bardzo wygodne, przyśpiesza pracę i znacznie upraszcza kod - tak, ale tylko w przypadku prostych selectów. W przypadku skomplikowanych zapytań, budowanych na podstawie sprawdzania wielu warunków, użycie query builderów równa się napisaniu kodu, który jest później bardzo trudny do zrozumienia i prześledzenia co się dzieje, a programista czytający taki kod w końcu
w ogóle nie ma możliwości wydedukować, jak wygląda finalne zapytanie i co robi.
3) Encje jako modele - to jest nieporozumienie. Obiekty zwracane przez ORMy - nazwijmy je tu encjami dla rozróżnienia -
nie są tym, co nazywa się modelem dziedzinowym. Te ORMowe encje to potworki, które mają dziesiątki metod i oferują dziesiątki funkcjonalności nie mające nic wspólnego z logiką biznesową reprezentowaną przez model. W takich aplikacjach, nie ma tak naprawdę rozróżnienia między abstrakcyjnym, logicznym modelem reprezentującym logikę biznesową, a tabelą w bazie danych. Te aplikacje stają się z automatu data-centryczne tylko z tego powodu, że programiści używają (wygenerowanych zwykle automatycznie) klas encji ORMowych, mapowanych 1:1 na odpowiednie tabele w bazie, jako modeli dziedzinowych. Na takich ORM-owych modelach-encjach, programista może w dowolnym momencie wykonywać dowolne operacje bazodanowe, co jest może i wygodne, ale bardzo szkodliwe dla całości kodu i projektu. Najgorzej jest, gdy te "encje" to activ-recordy, ale w pozostałych wzorcach jest podobnie.
ORM-owe modele to nie są modele w MVC ani tym bardziej w DDD.
4) Z tego samego powodu programiści używający takich encji reprezentujących tabele, zamiast myśleć obiektowo, myślą tak naprawdę w kategoriach tabel z kolumnami danych i zapisu do nich. Jest to absurdalne, że reprezentacja tabeli relacyjnej bazy danych przenika do wyższych warstw, gdzie jest (powinna być) logika biznesowa. Dodatkowo, takie "modele" są trwale związane z używanym frameworkiem (czy ORM-em) ze wszystkimi tego konsekwencjami - przykładowo nie można zmienić klasy bazowej, podlegają jakimś regułom wymuszonym przez konwencję ORMa itd. Pomijam już fakt, że w publicznym interfejsie takich obiektów na 5 metod realizujących rzeczywistą logikę biznesową napisanych przez programistę, jest 50 metod z ORMa...
5) Trzeba pamiętać, że czasem wykorzystywanie ORMa daje ogromny narzut czasowy i pamięciowy dla aplikacji. To potrafi być sporym problemem. Są też inne - patrz
tuKonkludując, warstwa modelu w aplikacji (oprócz tych najprostszych) powinna być zupełnie oddzielona od warstwy składowania danych. Lepiej użyć ORM w warstwie zapisu danych, nie w warstwie logiki aplikacji, gdzie powinny istnieć czyste modele dziedzinowe. Niestety, wszystkie dokumentacje od popularnych frameworków uczą (niejawnie) bardzo złego podejścia, że
ORM Model równa się
Domain Model. To jest ZŁO