Insertar, Actualizar y Eliminar datos utilizando JDatabase
From Joomla! Documentation
Ten en cuenta que muchos ejemplos en línea usan $db->query()
en lugar de $db->execute()
. Este era el antiguo método en Joomla! 1.5 y 2.5 y lanzará un aviso de obsoleto en Joomla! 3.0 +.
Este tutorial se divide en dos partes independientes:
- Insertar, actualizar y eliminar datos de la base de datos.
- Seleccionar datos de una o más tablas y recuperarlos en una variedad de formas diferentes.
Esta sección de la documentación que se ve insertar, actualizar y eliminar datos de una tabla de base de datos. Para ver la otra parte click aquí
Introducción
Joomla! ofrece una sofisticada capa de abstracción de la base de datos para simplificar su uso por parte de los desarrolladores de terceras partes. Las nuevas versiones de la Plataforma API de Joomla! proporciona funcionalidades adicionales que extiende la capa de base de datos; que incluye características tales como conectores para una mayor variedad de servidores de base de datos y la consulta encadenada. para mejorar la legibilidad del código de conexión y simplificar el código SQL.
Joomla puede utilizar diferentes tipos de sistemas de base de datos SQL y ejecutar una variedad de entornos con diferentes prefijos de las tablas. Además de estas funciones, la clase crea automáticamente la conexión a base de datos. Además de crear una instancia del objeto, necesitas sólo dos líneas de código para obtener un resultado de la base de datos, en una variedad de formatos. El uso de la capa de base de datos de Joomla! asegura una máxima compatibilidad y flexibilidad para tu extensión.
La Consulta
La consulta a la base de datos de Joomla! ha cambiado desde que el nuevo Framework de Joomla! introdujo la consulta "encadenada", ahora es el método recomendado para la construcción de consultas de base de datos (aunque la cadena de consultas aún son compatibles).
Consulta encadenada se refiere a un método de conexión de un número de métodos, uno tras otro, con cada método devolviendo un objeto que puede soportar el método siguiente, se mejora la legibilidad y la simplificación de código.
Para obtener una nueva instancia de la clase JDatabaseQuery utilizamos el método getQuery de JDatabaseDriver :
$db = JFactory::getDbo();
$query = $db->getQuery(true);
JDatabaseDriver::getQuery toma un argumento opcional, $new, que puede ser true o false (el valor predeterminado es false).
La consulta a nuestra base de datos puede llamar a un número de métodos JDatabaseQuery; estos métodos encapsulan el lenguaje de consulta de la fuente de datos (en la mayoría de los casos SQL), ocultando la sintaxis específica de la consulta al desarrollador y aumentando la portabilidad de los código fuente del desarrollador.
Algunos de los métodos utilizados con más frecuencia incluyen: select, from, join, where y order. También hay métodos tales como insert, update y delete para la modificación de registros en la base de datos. Por el encadenamiento de estos y otros métodos de llamada, puedes crear casi cualquier consulta sobre tu base de datos sin comprometer la portabilidad del código.
Insertar un Registro
Utilizando SQL
La clase JDatabaseQuery proporciona una serie de métodos para la construcción consultas para insertar datos , siendo los más comunes
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Insert columns.
$columns = array('user_id', 'profile_key', 'profile_value', 'ordering');
// Insert values.
$values = array(1001, $db->quote('custom.message'), $db->quote('Inserting a record using insert()'), 1);
// Prepare the insert query.
$query
->insert($db->quoteName('#__user_profiles'))
->columns($db->quoteName($columns))
->values(implode(',', $values));
// Set the query using our newly populated query object and execute it.
$db->setQuery($query);
$db->execute();
(Aquí la función quoteName() añade las comillas apropiadas a los nombres de la tabla y de la columna para evitar conflictos con cualquier palabra reservada de la base de datos, ahora o en el futuro). Para obtener el ID del registro recién insertado, puedes utilizar el método 'insertid' por ejemplo.
// Get the row that was just inserted
$new_row_id = $db->insertid();
How to store empty value as NULL
If your default value of a column is NULL, you should not add that column name in the array. Let the database system store NULL as the default value. If the default value of a column is not NULL and it is allowed to store NULL values, you should specify that in the code. See how to do it in the following example.
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
/** First Case [NULL as default value] **/
// The column 'profile_value' has NULL as default value. So, we will not add it to the array. The database engine will store NULL as value for column 'profile_value'.
// $columns = array('user_id', 'profile_key', 'profile_value', 'ordering');
$columns = array('user_id', 'profile_key', 'ordering');
// Insert values.
$values = array(1001, $db->quote('custom.message'), 1);
/** Second Case [string as default value and you can also store NULL value] **/
// The column 'profile_value' has empty string '' as default value but we can also store NULL value. So, we have to add the column name and NULL value to $columns and $values.
$columns = array('user_id', 'profile_key', 'profile_value', 'ordering');
// Insert values.
$values = array(1001, $db->quote('custom.message'), $db->quote('NULL'), 1);
Utilizando un Objeto
El clase JDatabaseDriver también proporciona un método conveniente para guardar un objeto directamente en la base de datos que nos permite agregar un registro a una tabla sin necesidad de escribir una sola línea de SQL.
// Create and populate an object.
$profile = new stdClass();
$profile->user_id = 1001;
$profile->profile_key='custom.message';
$profile->profile_value='Inserting a record using insertObject()';
$profile->ordering=1;
// Insert the object into the user profile table.
$result = JFactory::getDbo()->insertObject('#__user_profiles', $profile);
Nota que aquí no necesitamos escapar el nombre de la tabla; el método insertObject hace esto por nosotros.
La método insertObject producirá un error si hay un problema al insertar el registro en la tabla de base de datos.
Si estás proporcionando un valor de clave primaria único (como en el ejemplo anterior), se recomienda encarecidamente que selecciones de la tabla el valor de esa columna antes de intentar una inserción.
Si simplemente estás insertando la siguiente fila en la tabla (es decir, la base de datos genera un valor clave principal), puedes especificar la clave primaria nombre-columna como el tercer parámetro del método insertObject () y el método actualizará el objeto con la valor de clave primaria recientemente generado.
Por ejemplo, dada la siguiente declaración:
$result = $dbconnect->insertObject('#__my_table', $object, 'primary_key');
después de la ejecución, $object->primary_key se actualizará con el valor de la clave primaria recién insertada.
CONSEJO: Establece $object->primary_key en null o 0 (cero) antes de insertar.
How to store empty value as NULL when insert an object
If your default value of a column is NULL, you should not add that column name to the object. Let the database system store NULL as the default value. If the default value of a column is not NULL and it is allowed to store NULL values, you should specify that in the code. See how to do it in the following example.
// Create and populate an object.
$profile = new stdClass();
$profile->user_id = 1001;
$profile->profile_key='custom.message';
$profile->ordering=1;
/** First Case [NULL as default value] **/
// The column 'profile_value' has NULL as default value. So, we will not add it to the object. The database engine will store NULL as value for column 'profile_value'.
// $profile->profile_value='Inserting a record using insertObject()';
/** Second Case [string as default value and you can also store NULL value] **/
// The column 'profile_value' has empty string '' as default value but we can also store NULL value. So, we have to add the column name and NULL value as its value.
$profile->profile_value = $db->quote('NULL');
// Insert the object into the user profile table.
$result = JFactory::getDbo()->insertObject('#__user_profiles', $profile);
Actualizar un Registro
Utilizando SQL
La clase JDatabaseQuery también proporciona métodos para la construcción de consultas de actualización, en particular update y set. También podemos reutilizar otro método que hemos utilizado a la hora de crear las instrucciones select, con el método where.
$db = JFactory::getDbo();
$query = $db->getQuery(true);
// Fields to update.
$fields = array(
$db->quoteName('profile_value') . ' = ' . $db->quote('Updating custom message for user 1001.'),
$db->quoteName('ordering') . ' = 2',
// If you would like to store NULL value, you should specify that.
$db->quoteName('avatar') . ' = NULL',
);
// Conditions for which records should be updated.
$conditions = array(
$db->quoteName('user_id') . ' = 42',
$db->quoteName('profile_key') . ' = ' . $db->quote('custom.message')
);
$query->update($db->quoteName('#__user_profiles'))->set($fields)->where($conditions);
$db->setQuery($query);
$result = $db->execute();
Utilizando un Objeto
Como insertObject, la clase JDatabaseDriver proporciona un comodo método para la actualización de un objeto.
A continuación vamos a actualizar nuestra tabla personalizada con los nuevos valores con una id de clave primaria:
$updateNulls = true;
// Create an object for the record we are going to update.
$object = new stdClass();
// Must be a valid primary key value.
$object->id = 1;
$object->title = 'My Custom Record';
$object->description = 'A custom record being updated in the database.';
// If you would like to store NULL value, you should specify that.
$object->short_description = null;
// Update their details in the users table using id as the primary key.
// You should provide forth parameter with value TRUE, if you would like to store the NULL values.
$result = JFactory::getDbo()->updateObject('#__custom_table', $object, 'id', $updateNulls);
Como insertObject, updateObject se ocupa de escapar los nombres de tabla por nosotros.
La método updateObject producirá un error si hay un problema al actualizar el registro en la tabla de base de datos.
Tenemos que asegurarnos que el registro ya existe antes de intentar actualizar, así que se podría añadir algún tipo de verificación de registros antes de la ejecución del método updateObject.
Eliminar un Registro
Por último, también hay un método delete para eliminar registros de la base de datos.
$db = JFactory::getDbo();
$query = $db->getQuery(true);
// delete all custom keys for user 1001.
$conditions = array(
$db->quoteName('user_id') . ' = 1001',
$db->quoteName('profile_key') . ' = ' . $db->quote('custom.%')
);
$query->delete($db->quoteName('#__user_profiles'));
$query->where($conditions);
$db->setQuery($query);
$result = $db->execute();
Código de Módulo de Ejemplo
A continuación se presenta el código de un sencillo módulo Joomla que puede instalarse y ejecutarse para demostrar el uso de la funcionalidad de JDatabase para actualizar los registros de la base de datos, y que puede adaptarse para experimentar con algunos de los conceptos descritos anteriormente. Si no estás seguro del desarrollo e instalación de un módulo de Joomla, entonces te ayudará seguir el tutorial en Creando un módulo simple .
Nota importante: En cualquier extensión de Joomla que desarrolles, debes evitar acceder al núcleo de las tablas de Joomla directamente de esta manera y en su lugar debes usar las APIs de Joomla si es posible, porque las estructuras de la base de datos pueden cambiar sin previo aviso.
En una carpeta con nombre mod_db_update cree los 2 siguientes archivos:
mod_db_update.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.1" client="site" method="upgrade">
<name>Database update demo</name>
<version>1.0.1</version>
<description>Code demonstrating use of Joomla Database class to perform SQL UPDATE statements</description>
<files>
<filename module="mod_db_update">mod_db_update.php</filename>
</files>
</extension>
mod_db_update.php
<?php
defined('_JEXEC') or die('Restricted Access');
use Joomla\CMS\Factory;
$db = Factory::getDbo();
$me = Factory::getUser();
if ($me->id == 0)
{
echo "Not logged on!";
}
else
{
$email = $me->email;
// change the case of the email address
$email_uppercase = strtoupper($email);
if ($email == $email_uppercase)
{
$new_email = strtolower($email);
}
else
{
$new_email = $email_uppercase;
}
$query = $db->getQuery(true);
$fields = array($db->quoteName('email') . " = '{$new_email}'");
$conditions = array($db->quoteName('id') . ' = ' . $me->id);
$query->update($db->quoteName('#__users'))->set($fields)->where($conditions);
echo $db->replacePrefix((string) $query);
$db->setQuery($query);
if ($result = $db->execute())
{
echo "Email case successfully changed!";
}
}
El código anterior actualiza el campo de la dirección de correo electrónico en el registro usuarios del usuario actualmente conectado, alternando entre mayúsculas y minúsculas en sucesivas recargas de la página web. El método Factory::getUser() devuelve el objeto user del usuario actualmente conectado, o si no está conectado, entonces un objeto user en blanco, a cuyo campo id se le asigna el valor cero. La expresión $db->replacePrefix((string) $query) devuelve la sentencia SQL real, y su salida puede ser útil para la depuración.
Comprime el directorio mod_db_update para crear mod_db_update.zip.
Dentro de tu administrador de Joomla ve a Instalar Extensiones y a través de la pestaña Subir Archivo del Paquete sube este archivo zip para instalar este módulo de registro de muestra.
Haz visible este módulo editándolo (haz clic en él dentro de la página de Módulos) entonces:
- modificando su estado a Publicado
- seleccionando una posición en la página para que se muestre
- en la pestaña de asignación de menú, especifique las páginas en las que debe aparecer
Cuando visites la página web del sitio, deberías ver el módulo en la posición seleccionada, y debería emitir la declaración SQL UPDATE y afirmar que ha actualizado el registro con éxito. Para confirmar que ha actualizado el registro correctamente debes ir a phpmyadmin y ver la tabla users dentro de la base de datos de Joomla. Las actualizaciones no son visibles a través de la funcionalidad de administración de usuarios en el back end, ya que Joomla muestra en minúsculas todas las direcciones de correo electrónico en los registros.