¿Cómo implementar la actualización de mensajes en una base de datos con Java?
Actualizar un mensaje en una base de datos es una operación fundamental para cualquier aplicación de gestión de datos. En este artículo, te guiaremos paso a paso para actualizar un mensaje en una base de datos utilizando Java. Analizaremos cómo establecer la conexión con la base de datos, preparar y ejecutar la consulta SQL, y manejar excepciones. ¡Empecemos!
¿Cómo estructurar el método de actualización en la capa de datos?
Para manejar la actualización en la capa de datos, se necesita un método que gestione la interacción directa con la base de datos. Aquí te mostramos cómo hacerlo:
Crear el objeto de conexión: Reutiliza el objeto de conexión que ya has utilizado en otros métodos. Puedes copiar el siguiente bloque de código de otros métodos de conexión:
Manejo de excepciones: Utiliza bloques try-catch para gestionar las excepciones que puedan ocurrir al conectarte a la base de datos y ejecutar sentencias SQL.
try{// Código de conexión y ejecución de sentencias}catch(SQLException e){ e.printStackTrace();}
Preparar la consulta SQL: Necesitarás una consulta para actualizar el mensaje en la base de datos. Anteriormente, desde tu navegador usando una herramienta como phpMyAdmin, puedes identificar la consulta SQL que corresponde a una acción de actualización y modificarla para ser usada en Java:
String query ="UPDATE mensajes SET cuerpo = ? WHERE id_mensaje = ?";
Pasar parámetros a la consulta: Usa un PreparedStatement para introducir los parámetros del mensaje y su ID, que necesitas para identificar el registro a actualizar.
Ejecutar la consulta y manejar resultados: Una vez definidos los parámetros, ejecuta la sentencia y confirma el resultado.
int resultado = ps.executeUpdate();if(resultado >0){System.out.println("El mensaje se ha actualizado correctamente.");}else{System.out.println("No se pudo actualizar el mensaje.");}
¿Cómo obtener datos del usuario en la capa de servicio?
La interacción con el usuario para obtener los datos necesarios para actualizar el mensaje se realiza en la capa de servicio:
Solicitar el nuevo mensaje: Usa la clase Scanner para leer el nuevo mensaje desde la entrada estándar.
Scanner scanner =newScanner(System.in);System.out.println("Escribe tu nuevo mensaje:");String nuevoMensaje = scanner.nextLine();
Solicitar el ID del mensaje a actualizar: Pide al usuario el ID del mensaje que se desea actualizar.
System.out.println("Indica el ID del mensaje que deseas editar:");int idMensaje = scanner.nextInt();
Crear un objeto mensaje: Una vez que se tienen los datos, crea un objeto de tipo Mensaje para pasarlo a la capa de datos.
Después de implementar tu método de actualización, es crucial verificar que los cambios se han aplicado correctamente en la base de datos. Ejecuta la aplicación, intenta actualizar un mensaje y revisa tanto la salida por consola como el contenido de los registros en la base de datos para asegurar la correcta actualización.
Este enfoque de actualización no solo permite realizar cambios en la base de datos con seguridad, sino que también enseña a manejar las operaciones de CRUD mediante una aplicación Java. ¡Anímate a seguir practicando! Realiza una réplica de este proyecto y experimenta con cambios para afianzar tus conocimientos en la gestión de bases de datos.
Que buena practica has hecho!!
Pero tengo muchas dudas como por ejemplo: @SneakyThrows, @NonNull, @SneakyThrows
¿Podrías compartir sus usos?
De manera sucinta, son anotaciones que modifican el ByteCode del código que las emplea, y forman parte del proyecto Lombok.
@NonNull Inserta una verificación para gatillar un error al asignar null a un nombre marcado con la anotación.
@SneakyThrows convierte toda excepción que debe ser manejada, en una que no es obligatorio manejarla (checked vs no-checked exception)
Me alegra que lo hayas encontrado interesante. Saludos!
genialllll que esta el CRUD, aun que lo de Scanner considero que se hubiera puesto como variable global pa todo :D
Exactamente, de igual manera el objeto db_connect de la clase Conexion, desde que copia y pega está fallanda a DRY.
Scanner en el proyecto del profe, tiene un alcance local, y su ciclo de vida solo está en la ejecución del método.
Un saludo para todas las personas que ven este video, actualicé el proyecto en mi repositorio de github con buenas prácticas.
Si pido primero el id del mensaje y luego el mensaje a actualizar, en la segunda lectura del scanner no espera mi respuesta. Estuve leyendo que es un problema común al leer un texto luego de leer un entero pero me gustaría saber cual seria la solución a esto
Rayos! me acaba de pasar lo mismo... a investigar
Intenta utilizando la función next()
<System.out.println("ID del mensaje a editar:"); int id_mensaje=sc.nextInt();System.out.println("Ingrese su Mensaje:");String mensaje=sc.next();System.out.println("Su autor:");String autor=sc.next();>
Listo!
¿Donde puedo encontrar el ejercicio propuesto al final del vídeo?
Creo que se refiere al proyecto en github que está en la pestaña de Archivos y enlaces
Como puedes ver, además del módulo de Mensajes, también podemos ver nuevo código con la implementación del módulo de Usuarios. :wink:
Como ya me había pasado en un curso anterior eso de que el Scanner se quedara con problemas después de leer un entero, la solución que yo uso es tener un Scanner para cadenas de texto y otro Scanner para valores enteros.
publicstaticvoideditarMensaje(){Scanner scId =newScanner(System.in);Scanner scMensaje =newScanner(System.in);Mensaje mensaje =newMensaje();System.out.println("Seleccione el ID del mensaje que desee modificar"); int idMensaje = scId.nextInt();System.out.println("Indique el mensaje que desee guardar");String textoMensaje = scMensaje.nextLine(); mensaje.setId_mensaje(idMensaje); mensaje.setMensaje(textoMensaje);MensajesDAO.actualizarMensaje(mensaje);}```
Hola
de hecho podria manejar uno solo, y lo unico diferente es que cuando consumas elScanner para un entero parsearlo así.
int dato =Integer.parseInt(sc.nextLine())
Me encantan sus clases profe, gracias.
Del projecto propuesto por el profe Santiago el import de las clases de
import org.apache.commons.codec.digest.DigestUtils;
no existe a la fecha.
Que opción tenemos?
Carlos, en este enlace puedes encontrar el .jar que necesitas
Haciendo la práctica noté que el orden en el que se piden los datos de ingreso es importante porque al pedir primero el id y luego el nuevo mensaje, el codigo no funciona correctamente.
Recomendación 2023.
El profe actualizo su repositorio con buenas practicas. Pero aun este curso dejo de lado el Mapeo de entidades que hace parte de las buenas practicas, entiendo que al ser un proyecto pequeño no se vea la necesidad, pero en el sector empresarial es fundamental aplicar el mapeo de entidades (en el curso no fue necesario, porque nombramos las entidades del objeto mensaje igual como se nombra sus columna representativa en BD).
Así que los compañeros que están viendo este curso les recomiendo que traten de implementar el mapeo de la entidades.
aquí les dejo la consulta que le hice CahtGPT para que me brindara información con la duda que tenia:
en un proyecto java, si nombro las entidades de los clases de los objetos creados igual como esta nombrado en sus columnas representativas en base de datos no es necesario aplicar el Mapeo de entidades ?
Respuesta:
Si las entidades de las clases de los objetos en tu proyecto Java tienen el mismo nombre que las columnas de la base de datos, no necesitas aplicar un mapeo explícito de entidades. Sin embargo, es importante tener en cuenta que esto solo funciona si el esquema de la base de datos es muy simple y consiste solo en tablas con columnas simples y relaciones simples.
En situaciones más complejas, en las que se tienen tablas con relaciones más complejas o columnas que no se pueden representar directamente como campos en una clase, es necesario realizar un mapeo explícito de entidades.
Además, es una buena práctica separar la definición de las entidades de las clases de los objetos de la definición de la base de datos, para que los cambios en una no afecten la otra. Esto permite una mayor flexibilidad y mantenibilidad del sistema a largo plazo.
En resumen, si tu base de datos es muy simple, puedes utilizar los mismos nombres en tus clases de objetos y en las columnas de la base de datos y evitar el mapeo explícito de entidades. Pero para esquemas más complejos y para tener una arquitectura más flexible y mantenible, es recomendable realizar el mapeo explícito de entidades y separar la definición de las entidades de la definición de la base de datos.
Por mi lado voy a tratar de implementar esto, espero en un posterior comentario poderles compartir mi repositorio con esta implementación.
yo johnkegd, le agregue algunas cosas para que sea un poco mas fácil a la hora de usar.
Sin problemas ...
:D interesante
Buenas una consulta, cual es el procedimiento para configurar el archivo .env? Gracias,
Se instala la dependencia en el pom y luego de accede a las variables que están en el archivo .env como explican en la guía oficial
Me surge una duda amigos, es necesario poner al PreparedStatement en un try y la sentencia sql en otro try? porque pongo todo en un solo try e igual me funciona, creo que resulta hasta mejor, alguien que me saque la duda? gracias
Así es, puedes poner todo en un try, pero al separarlos, puedes obtener un mensaje de error más específico en caso de que falle la ejecución de la consulta
Como seria este proyecto en profesional como para aprender a manejar todo como si estuviera trabajando, bueno ps aqui mi proyecto: , psdt: es mi humilde proyecto, realmente no soy profesional aun hice clickbait xd, pero si me parece que lo hice muy bien, espero les guste y les ayude, tambien estoy abierto a sugerencia, saludos
Listo:
package com.platzi.dao;import com.platzi.Conexion;import com.platzi.dao.model.Mensajes;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.util.Objects;import java.util.logging.Logger;publicclassMensajesDAO{staticLogger logger =Logger.getLogger(MensajesDAO.class.getName());publicstaticvoidcrearMensajeDB(Mensajes mensaje){Conexion claseConexion =newConexion();try(Connection connection = claseConexion.getConection()){PreparedStatement ps =null;try{String query ="INSERT INTO mensajes (mensaje, autor_mensaje) VALUES (?, ?)"; ps = connection.prepareStatement(query); ps.setString(1, mensaje.getMensaje()); ps.setString(2, mensaje.getAutorMensaje()); ps.executeUpdate(); logger.info("Mensaje creado correctamente");}catch(Exception e){ logger.severe("Error al crear mensaje: "+ e); connection.rollback();}finally{Objects.requireNonNull(ps).close(); connection.close();}}catch(Exception e){ logger.severe("Error al conectar a la base de datos: "+ e);}}publicstaticvoidleerMensajesDB(){Conexion claseConexion =newConexion();try(Connection connection = claseConexion.getConection()){PreparedStatement ps =null;ResultSet rs =null;try{String query ="SELECT * FROM mensajes"; ps = connection.prepareStatement(query); rs = ps.executeQuery();while(rs.next()){System.out.println("ID: "+ rs.getInt("id_mensaje"));System.out.println("Mensaje: "+ rs.getString("mensaje"));System.out.println("Autor: "+ rs.getString("autor_mensaje"));System.out.println("Fecha: "+ rs.getString("fecha_mensaje"));System.out.println();}}catch(Exception e){ logger.severe("Error al leer mensajes: "+ e);}finally{Objects.requireNonNull(rs).close();Objects.requireNonNull(ps).close(); connection.close();}}catch(Exception e){ logger.severe("Error al conectar a la base de datos: "+ e);}}publicstaticvoidborrarMensajeDB(int idMensaje){Conexion claseConexion =newConexion();try(Connection connection = claseConexion.getConection()){PreparedStatement ps =null;try{String query ="DELETE FROM mensajes WHERE id_mensaje = ?"; ps = connection.prepareStatement(query); ps.setInt(1, idMensaje); ps.executeUpdate(); logger.info("Mensaje eliminado correctamente");}catch(Exception e){ logger.severe("Error al borrar mensaje: "+ e); connection.rollback();}finally{Objects.requireNonNull(ps).close(); connection.close();}}catch(Exception e){ logger.severe("Error al conectar a la base de datos: "+ e);}}publicstaticvoidactualizarMensajeDB(Mensajes mensaje){Conexion claseConexion =newConexion();try(Connection connection = claseConexion.getConection()){PreparedStatement ps =null;try{String query ="UPDATE mensajes SET mensaje = ?, fecha_mensaje = CURRENT_TIMESTAMP WHERE id_mensaje = ?"; ps = connection.prepareStatement(query); ps.setString(1, mensaje.getMensaje()); ps.setInt(2, mensaje.getIdMensaje()); ps.executeUpdate(); logger.info("Mensaje actualizado correctamente");}catch(Exception e){ logger.severe("Error al actualizar mensaje: "+ e); connection.rollback();}finally{Objects.requireNonNull(ps).close(); connection.close();}}catch(Exception e){ logger.severe("Error al conectar a la base de datos: "+ e);}}}
Así me quedó el método editar en el service:
publicstaticvoideditarMensaje(){Scanner sc =newScanner(System.in); int id_mensaje;String mensaje;System.out.println("Ingrese el ID del mensaje a Editar: "); id_mensaje =Integer.parseInt(sc.nextLine());System.out.println("Ingrese el nuevo mensaje: "); mensaje = sc.nextLine();System.out.println("El mensaje es: "+mensaje);MensajesModel message =newMensajesModel(); message.setId_mensaje(id_mensaje); message.setMensaje(mensaje);MensajesDAO.actualizarMensajeDB(message);}``` saludos