Link Search Menu Expand Document

5.12. Usando la BD con QueryBuilder

En esta sección te voy a presentar a QueryBuilder, otra forma de acceder a la base de datos desde Laravel que te resultará muy útil en aquellos casos en los que, por la razón que sea, los métodos de Eloquent no sean suficientes.

5.12.1. ¿Qué es y cómo se utiliza QueryBuilder?

Eloquent permite usar la BD de forma simple y elegante en la mayor parte de las circunstancias.

Aún así, puede haber situaciones en las que queramos un acceso de más bajo nivel a la BD. Para eso existe QueryBuilder.

El grado de abstracción de QueryBuilder es mucho menor que el de Eloquent. Es decir, estaremos CASI escribiendo SQL, sin llegar a hacerlo.

Algunos ejemplos de uso te darán una pista de qué tipo cosas se pueden hacer con QueryBuilder:

$users = DB::table("users")->get();	
$users = DB::table("users")->where("name", "=", "Ana")->first();
$users = DB::table("users")->where("edad", ">=", 18)->orderBy("apellidos");
$maxId = DB::table("users")->max("id");
$existe = DB::table("users")->where("id", "=", $id)->exists();
$users = DB::table("users")->select("nombre, apellidos as apell")->get(); 

Ahora ves a qué me refiero cuando digo que QueryBuilder es casi SQL, sin llegar a serlo. No tendrás que depurar el SQL, ni pelearte con comillas que se abren y cierran, ni nada de eso. QueryBuilder generará el SQL por ti a partir de expresiones como las que acabas de ver.

En la documentación oficial encontrarás una referencia completa de todas las funciones de QueryBuilder, pero con estas que ves en el ejemplo puedes construir prácticamente cualquier consulta sencilla.

5.12.2. Colecciones

El resultado de consultas como las que veíamos de ejemplo en el apartado anterior es bastante intuitivo:

  • O bien un dato simple (como el $maxId de la cuarta consulta, que es un entero).
  • O bien un objeto de tipo Collection.

Las colecciones de Laravel tienen un montón de métodos útiles para procesarlas y puedes echarle un vistazo a la documentación oficial para ello, pero la mayor parte de las veces basta con hacer un foreach sobre la variable para ir accediendo a cada uno de los elementos, que se comportarán como objetos del tipo adecuado.

Por ejemplo, para acceder a todos los registros de la tabla de usuarios:

   $users = DB::table("users")->get();
   foreach ($users as $user) {
      echo $user->name;
      echo $user->email;
      ...etc...
   }

5.12.3. Ventajas de QueryBuilder sobre SQL

Como ves, QueryBuilder te permite construir sentencias SQL sin necesidad de escribir SQL.

La ventaja de esto es triple:

  1. No tendremos que depurar nuestros errores sintácticos en SQL, con el ahorro de tiempo que eso conlleva.
  2. El SQL generado será 100% compatible con el gestor de base de datos que estemos utilizando. Si escribimos SQL en crudo, tendremos que adaptarlo al dialecto de nuestro gestor de base de datos. Y, si cambiamos de gestor, habrá que revisar todas las sentencias SQL para adaptarlas de nuevo. Todo esto lo evita QueryBuilder, puesto que hace esa adaptación por nosotros.
  3. Es imposible que suframos un ataque por inyección de código, puesto que QueryBuilder no lo permitirá.

5.12.4. Relaciones entre tablas con QueryBuilder

Las relaciones entre tablas se manejan con joins, como en SQL, solo que escritos al estilo QueryBuilder.

Para hacer un INNER JOIN, puedes usar como referencia este ejemplo:

$users = DB::table('users')
            ->join('contacts', 'users.id', '=', 'contacts.user_id')
            ->join('orders', 'users.id', '=', 'orders.user_id')
            ->select('users.*', 'contacts.phone', 'orders.price')
            ->get(); 

Por supuesto, también puedes hacer LEFT JOIN y RIGHT JOIN:

$resultado = DB::table('A')->leftJoin('B'...); 
$resultado = DB::table('A')->rightJoin('B'...); 

5.12.5. SQL crudo

Por último, QueryBuilder también te permite escribir SQL crudo, es decir, SQL tal cual, si es que alguna vez lo necesitas.

Eso sí, deberías valorar muy bien para qué narices quieres escribir SQL crudo. ¿Estás seguro/a de que eso que intentas hacer no se puede lograr más fácilmente con Eloquent o con QueryBuilder?

Además, tendrás que extremar las precauciones ante un posible ataque por inyección de código.

Si aún así no te he convencido, puedes ejecutar tu SQL crudo así:

$resultado = DB::raw('escribe-aquí-tu-sentencia-SQL');