- Introducción
- Ejecutando consultas SQL nativas
- Listeners de eventos de consultas
- Transacciones de bases de datos
Introducción
Laravel hace que la interacción con las bases de datos sea extremadamente fácil a través de una variedad de backends de bases de datos usando SQL nativo, el constructor de consultas query builder y el ORM Eloquent. Actualmente, Laravel soporta cuatro bases de datos:
- MySQL 5.6+ (Política de la versión)
- PostgreSQL 9.4+ (Política de la versión)
- SQLite 3.8.8+
- SQL Server 2017+ (Política de la versión)
Configuración
La configuración de base de datos para tu aplicación está localizada en config/database.php
. En este archivo puedes definir todas tus conexiones de bases de datos, y también especificar qué conexión debería ser usada por defecto. Ejemplos para la mayoría de los sistemas de bases de datos soportados son proporcionados en este archivo.
Por defecto, la configuración de entorno de muestra de Laravel está lista para usar con Laravel Homestead, la cual es una máquina virtual conveniente para el desarrollo con Laravel en tu máquina local. Eres libre de modificar esta configuración de acuerdo a tus necesidades de tu base de datos local.
Configuración de SQLite
Después de la creación de una nueva base de datos SQLite usando un comando tal como touch database/database.sqlite
, puedes configurar fácilmente tus variables de entorno para apuntar a esta base de datos creada recientemente al usar la ruta absoluta a la base de datos:
DB_CONNECTION=sqlite DB_DATABASE=/absolute/path/to/database.sqlite
Para habilitar las claves foráneas en conexiones de SQLite, debes establecer la variable de entorno DB_FOREIGN_KEYS
a true
:
DB_FOREIGN_KEYS=true
Configuración usando URLs
Típicamente, las conexiones a bases de datos son configuradas usando múltiples valores de configuración como host
, database
, username
, password
, etc. Cada uno de esos valores de configuración tiene su propia variable de entorno correspondiente. Esto quiere decir que al configurar tu información de conexión a la base de datos en un servidor de producción, necesitas administrar múltiples variables de entorno.
Algunos proveedores de bases de datos administrados como Heroku proporcionan una única «URL» de base de datos que contiene toda la información de conexión para la base de datos en una única cadena. Una URL de base de datos de ejemplo podría verse de la siguiente manera:
mysql://root:[email protected]/forge?charset=UTF-8
Estas URLs típicamente siguen una convención de esquema estándar:
driver://username:password@host:port/database?options
Por conveniencia, Laravel soporta dichas URLs como alternativa para configurar tu base de datos con múltiples opciones de configuración. Si la opción de configuración url
(o variable de entorno DATABASE_URL
correspondiente) está presente, esta será usada para extraer la conexión a la base de datos y la información de credenciales.
Conexiones de lectura y escritura
Algunas veces puedes desear contar con una conexión de base de datos para los comandos SELECT y otra para los comandos INSERT, UPDATE y DELETE. Laravel hace esto una tarea fácil, y las conexiones propias siempre serán usadas si estás usando consultas nativas, el constructor de consultas Query Builder o el ORM Eloquent.
Para ver cómo las conexiones de lectura / escritura deberían ser configuradas, vamos a mirar este ejemplo:
'mysql' => [ 'read' => [ 'host' => [ '192.168.1.1', '196.168.1.2', ], ], 'write' => [ 'host' => [ '196.168.1.3', ], ], 'sticky' => true, 'driver' => 'mysql', 'database' => 'database', 'username' => 'root', 'password' => '', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', ],
Observa que tres claves han sido agregadas al arreglo de configuración: read
, write
y sticky
. Las claves read
y write
tienen valores de arreglo que contienen una sola clave: la dirección ip del host
. El resto de las opciones de la base de datos para las conexiones read
y write
serán tomadas del arreglo principal mysql
.
Únicamente necesitas colocar elementos en los arreglos read
y write
si deseas sobrescribir los valores del arreglo principal. Así, en este caso, 192.168.1.1
será usado como la máquina para la conexión de «lectura», mientras que 192.168.1.3
será usada para la conexión de «escritura». Las credenciales de bases de datos, prefijo, conjunto de caracteres, y todas las demás opciones en el arreglo principal mysql
serán compartidas a través de ambas conexiones.
La opción sticky
La opción sticky
es un valor opcional que puede ser usado para permitir la lectura inmediata de registros que han sido escritos a la base de datos durante el ciclo de la solicitud actual. Si la opción sticky
está habilitada y una operación de «escritura» ha sido ejecutada contra la base de datos durante el ciclo de la solicitud actual, cualquiera de las operaciones de «lectura» hasta aquí usarán la conexión de «escritura». Esto asegura que cualquier dato escrito durante el ciclo de la solicitud pueda ser leído inmediatamente de la base de datos durante esa misma solicitud. Es posible para ti decidir si este es el comportamiento deseado para tu aplicación.
Usando conexiones de bases de datos múltiples
Cuando estamos usando conexiones múltiples, puedes acceder a cada conexión por medio del método connection
en el Facade DB
. El nombre name
pasado al método de conexión connection
debería corresponder a una de las conexiones listadas en tu archivo de configuración config/database.php
:
$users = DB::connection('foo')->select(...);
También puedes acceder a los datos nativos de la instancia PDO subyacente que usa el método getPdo
en una instancia de conexión:
$pdo = DB::connection()->getPdo();
Ejecutando consultas SQL nativas
Una vez que has configurado tu conexión de base de datos, puedes ejecutar consultas usando el Facade DB
. La clase facade DB
proporciona métodos para cada tipo de consulta: select
, update
, insert
, delete
y statement
.
Ejecutando una consulta select
Para ejecutar una consulta básica, puedes usar el método select
en el facade DB
:
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\DB; class UserController extends Controller { /** * Show a list of all of the application's users. * * @return Response */ public function index() { $users = DB::select('select * from users where active = ?', [1]); return view('user.index', ['users' => $users]); } }
El primer argumento pasado al método select
es la consulta SQL nativa, mientras que el segundo argumento es cualquier parámetro a enlazar que necesita estar conectado a la consulta. Típicamente, estos son los valores de las restricciones de cláusula where
. El enlazamiento de parámetro proporciona protección contra ataques de inyección SQL.
El método select
siempre devolverá un array
de resultados. Cada resultado dentro del arreglo será un objeto stdClass
de PHP, permitiendo que accedas a los valores de los resultados:
foreach ($users as $user) { echo $user->name; }
Usando enlaces nombrados
En lugar de usar ?
para representar tus enlaces (bindings) de parámetros, puedes ejecutar una consulta usando enlaces nombrados:
$results = DB::select('select * from users where id = :id', ['id' => 1]);
Ejecutando una instrucción insert
Para ejecutar una instrucción insert
, puedes usar el método insert
en la clase facade DB
. Igual que select
, este método toma la consulta SQL nativa como su argumento inicial y los enlaces como su argumento secundario:
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
Ejecutando una instrucción update
El método update
debería ser usado para actualizar los registros existentes en la base de datos. El número de filas afectadas por la instrucción serán devueltas:
$affected = DB::update('update users set votes = 100 where name = ?', ['John']);
Ejecutando una instrucción delete
El método delete
debería ser usado para eliminar registros de la base de datos. Al igual que update
, el número de filas afectadas será devuelto:
$deleted = DB::delete('delete from users');
Ejecutando una instrucción general
Algunas instrucciones de bases de datos no devuelven algún valor. Para estos tipos de operaciones, puedes usar el método statement
en la clase facade DB
:
DB::statement('drop table users');
Listeners de eventos de consultas
Si prefieres recibir cada consulta SQL ejecutada por tu aplicación, puedes usar el método listen
. Este método es útil para crear archivos logs de consultas o depurar. Puedes registrar tus listeners de consultas en un proveedor de servicio:
<?php namespace App\Providers; use Illuminate\Support\Facades\DB; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { DB::listen(function ($query) { // $query->sql // $query->bindings // $query->time }); } }
Transacciones de bases de datos
Puedes usar el método transaction
en la clase facade DB
para ejecutar un conjunto de operaciones dentro de una transacción de base de datos. Si un error de excepción es arrojado dentro del código Closure
de la transacción, la transacción automáticamente terminará con un rollback. Si el código Closure
se ejecuta correctamente, la transacción terminará automáticamente con un commit. No necesitas preocuparte por hacer rollback o commit manualmente mientras estés usando el método transaction
:
DB::transaction(function () { DB::table('users')->update(['votes' => 1]); DB::table('posts')->delete(); });
Manejando deadlocks (bloqueo mutuo)
El método transaction
acepta un segundo argumento opcional el cual define el número de veces que la ejecución de una transacción debería ser reintentada cuando un ocurra un deadlock. Una vez que estos intentos hayan sido completados sin éxito, un error de excepción será arrojado:
DB::transaction(function () { DB::table('users')->update(['votes' => 1]); DB::table('posts')->delete(); }, 5);
Usando transacciones manualmente
Si prefieres empezar una transacción manualmente y tener control total sobre rollbacks y commits, podrías usar el método beginTransaction
de la clase facade DB
:
DB::beginTransaction();
Puedes hacer rollback de la transacción por medio del método rollBack
:
DB::rollBack();
Finalmente, puedes confirmar una transacción por medio del método commit
:
DB::commit();
Los métodos de transacción del Facade DB
controlan las transacciones para ambos backends de bases de datos: el constructor de consultas query builder y el ORM Eloquent.
Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.
Lección anterior Programación de tareas - Documentación de Laravel 6 Lección siguiente Base de datos: constructor de consultas (query builder) - Documentación de Laravel 6