Consultado registros de una BD usando JSP y Servlets
Consultado registros de una BD usando JSP y Servlets
Continuando con lo visto en la entrada anterior, hoy veremos como podemos mostrar los resultados devueltos por la base de datos en nuestro JSP.
Para esto el usuario ingresara el nombre de usuario a buscar, y aparecera toda la informacion en la BD de ese usuario.
Codigo
Clase BeanUsuario
Clase Usuario
Clase Conexion
Clase ServletConsulta
Archivo JSP index.jsp
Archivo JSP mostrar.jsp
Descargar
Podrán descargar el proyecto completo directamente desde aquí. Sigan visitándonos en Java Zone para mas informacion.
- roger1345's blog
- Inicie sesión o regístrese para enviar comentarios
Ojo con esas conexiones a BDD
Hola,
Quería advertirte, y a todos los lectores, que la forma que muestras de conectarse a la BDD y trabajar con ella es incorrecta y sería una fuente de problemas importantes a nada que se intententará usar más allá de una simple consulta de prueba.
Entre otros detalles: no se cierran las conexiones, no se cierran los statements, se usa una sola conexión compartida en un entorno multi-hilo, y además sin las protecciones de sincronización adecuadas...
Ese código es un peligro :)
Buena observacion!
Greeneyed, gracias por tu observacion, y claro que este es solo para ejemplos con un solo usuario consultando en la BD, este es solo un comienzo en JEE, iremos viendo mas adelante como podemos crear un pool de conexiones a la BD, como usar algun framework como hibernate, y asi iremos avanzando cada vez mas en el tema. Por supuesto aceptamos cualquier comentario o sugerencia, si tienes alguna idea que aportar, estaremos atentos todos a escuchar y mas si tienes experiencias que puedas compartir.
de acuerdo con greeneyed
Aunque sea sólo un simple ejemplo, no deja de ser un ejemplo de una aplicación web, que por naturaleza es multiusuario, y por lo tanto debe contemplar la concurrencia en todo momento. Es mejor que desde el inicio se incluya lo necesario para cerrar conexiones, no compartir conexiones, etc; de lo contrario, son ejemplos erróneos y si alguien simplemente toma como base este código para hacer "una aplicación sencilla" que después crece, y ya no se toman la molestia de leer los ejemplos subsecuentes donde se corrigen estos problemas, ya hay más código allá afuera que tiene problemas que luego no saben ni por qué se les cae el sitio y lo tienen que estar reiniciando, etc.
Primero: que bueno que te
Primero: que bueno que te animes a postear tus ejemplos.
Segundo ( y sé que parecerá injusto pero ) ten cuidado con esto:
Acá se ha posteado mucho sobre la injección de SQL. Utiliza un prepared statement. Recueda a Bobby tables
Entendido y Anotado!
Primero agradecerles por las observaciones y opiniones, lo que se planeo fue publicar una secuencia de entradas en las que se fuera profundizando en el tema del manejo de conexiones a la BD y el uso de Servlets y JSP's, esto es solo el comienzo, entiendo las recomendaciones que me hacen pero como saben los usuarios que esta mal hecho sino se muestra como es mejor, me parece que si mostramos desde como se hace de la forma mas sencilla, arriesgando la seguridad y la disponibilidad, entre muchas otras cosas, y luego hacer el mismo ejercicio implementando ya metodologias mas complejas, lo que quiero mostrar es que no es dificil entrar a tocar temas como pool de conexiones, hibernate, struts, etc. Me acuerdo que en mis epocas de estudiante veia un ejemplo JEE complejo y me asustaba de lo complejo que era, de no entender que eran estos frameworks. XD. Pero seguiremos mostrando mas de JEE. Seguiremos adelante!!!
Entendido pero...
Entiendo lo que quieres decir, pero una cosa es mostrar código simplificado y otra código erróneo y sin ningún tipo de aviso. No hace falta entrar en temas complejos de datasources, si no lo consideras necesario, pero el código JDBC a pelo se puede escribir de forma correcta y sin causar muchos problemas excepto que no sea muy eficiente. Pero el código que muestras tú es inseguro, dejar conexiones sin cerrar y con un simple frame o un reolad demasiado rápido daría problemas difíciles de entender para un novato, debidos a la concurrencia.
Dejar código así "suelto" por Internet es un peligro :D
y cómo, según ustedes sería
y cómo, según ustedes sería un ejemplo muy sencillo de una conexión correcta ?
cambios en tu diseño
Para empezar, tu clase Conexion no debería existir. En serio, usarla es peor que si no existiera; si la quitas del ejemplo, entonces tienes que poner la única línea de código que vale la pena de esa clase, en el código donde normalmente usas Conexion (la otra línea, donde cargas el driver JDBC, debería ir en el inicializador de la aplicación, o de alguna clase, si es que el contenedor no la carga por ti).
Luego,
debe usar
. Ese patrón no es nada nuevo bajo el sol:
Ese patrón de uso es tan común, que en Java 7 ya metieron azúcar sintáctica para hacerlo más fácil, el famoso try with resources. aquí un ejemplo de uso.
lo mismo que dicen todos
buenos consejos compañeros
salduos :I
MUCHO BLA BLA BLA
a todos los señores que llegaron a corregir, pongan algunos ejemplos de la manera correcta que se debe hacer porfavor... no se vale nada mas dar sombrerazos! a los que tratan de aportar algo...
Ok
En un rato subo una forma de hacerlo de forma sencilla pero slavando los puntos ya indicados
Re:Ok
Puras falsas promesas D: , yo también quiero ver como realizan las conexiones ustedes porque yo lo hago según el libro de Deitel y no es como el ejemplo que coloco Enrique.
Una pequeña mejora con Spring JDBC
Hola, actualmente estoy ayudando a unos amigos a aprender Spring JDBC, quizas el material que estamos creando pueda ayudar para este post
Saludos:)
Apoyo Spring JDBC
Aún en la aplicación más patito de base de datos se terminan realizando siempre las mismas operaciones, abrir conexión, crear sentencia, ejecutar sentencia,.. cerrar conexión...
Los primeros ejemplos y tutoriales que leemos nos guían a utilizar JDBC "pelón", dígamos a bajo nivel.
Luego viene lo más sofisticado cuando nos pasamos a los frameworks tipo Hibernate, Toplink, etc.
Algo intermedio, y que a mí en lo particular me gusta mucho para cierto tipo de apps, es el framework JDBC de Spring.
Sí tienen oportunidad hay que darle una leída. Cito:
"The Spring Framework takes care of all the grungy, low-level details that can make JDBC such a tedious API to develop with."
Sale y vale
Byte
Algo como esto podría ser
package conexion;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Conexion {
public static Conexion instance; // Singleton
private Connection cnn;
private Conexion() {
try {
Class.forName("com.mysql.jdbc.Driver");
cnn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testmvc?zeroDateTimeBehavior=convertToNull", "root", "");
} catch (ClassNotFoundException ex) {
Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ex);
}
}
public synchronized static Conexion saberEstado() {
if (instance == null) {
instance = new Conexion();
}
return instance;
}
public Connection getCnn() {
return cnn;
}
public void cerrarConxecion() {
instance = null;
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package controlador;
import dao.PersonaDAO;
import dto.PersonaDTO;
import interfaces.Obligacion;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Procesar extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PersonaDAO exec = new PersonaDAO();
boolean exitoCreate = false;
String infoMensaje = "";
String nombre = request.getParameter("txtNombre");
String edad = request.getParameter("txtEdad");
if (nombre.equals("") || edad.equals("")) {
infoMensaje = "Campos Vacios ...";
request.getSession().setAttribute("error", infoMensaje);
request.getRequestDispatcher("error.jsp").forward(request, response);
} else {
int ed = 0;
try {
ed = Integer.parseInt(edad);
} catch (NumberFormatException exc) {
infoMensaje = "Solo se acepta numero en la edad ...";
request.getSession().setAttribute("error", infoMensaje);
request.getRequestDispatcher("error.jsp").forward(request, response);
}
PersonaDTO pers = new PersonaDTO(nombre, ed);
exitoCreate = exec.create(pers);
if (exitoCreate) {
infoMensaje = "Informacion procesada correctamente ...";
request.getSession().setAttribute("infocorrecto", infoMensaje);
request.getSession().setAttribute("personaOk", pers);
request.getRequestDispatcher("exito.jsp").forward(request, response);
}else{
infoMensaje = "Lo sentimos no se ha podido ingresar a la Persona ...";
request.getSession().setAttribute("error", infoMensaje);
request.getRequestDispatcher("error.jsp").forward(request, response);
}
}
}
package dao;
import conexion.Conexion;
import dto.PersonaDTO;
import interfaces.Obligacion;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class PersonaDAO implements Obligacion {
private static final String SQL_INSERT = "INSERT INTO persona(nombre, edad) VALUE(?, ?)";
private static final String SQL_DELETE = "DELETE FROM persona WHERE id = ? ";
private static final String SQL_UPDATE = "UPDATE persona SET nombre = ?, edad = ? WHERE id = ? ";
private static final String SQL_READ = "SELECT * FROM persona WHERE id = ? ";
private static final String SQL_READALL = "SELECT * FROM persona";
private static final Conexion con = Conexion.saberEstado();
@Override
public boolean create(PersonaDTO c) {
PreparedStatement ps;
try {
ps = con.getCnn().prepareStatement(SQL_INSERT);
ps.setString(1, c.getNombre());
ps.setInt(2, c.getEdad());
if (ps.executeUpdate() > 0) {
return true;
}
} catch (SQLException ex) {
Logger.getLogger(PersonaDAO.class.getName()).log(Level.SEVERE, null, ex);
} finally {
con.cerrarConxecion();
}
return false;
}
@Override
public boolean delete(Object key) {
PreparedStatement ps;
try {
ps = con.getCnn().prepareStatement(SQL_DELETE);
ps.setString(1, key.toString());
if (ps.executeUpdate() > 0) {
return true;
}
} catch (SQLException ex) {
Logger.getLogger(PersonaDAO.class.getName()).log(Level.SEVERE, null, ex);
} finally {
con.cerrarConxecion();
}
return false;
}
@Override
public boolean update(PersonaDTO c) {
PreparedStatement ps;
try {
ps = con.getCnn().prepareStatement(SQL_UPDATE);
ps.setString(1, c.getNombre());
ps.setInt(2, c.getEdad());
ps.setInt(3, c.getId());
if (ps.executeUpdate() > 0) {
return true;
}
} catch (SQLException ex) {
Logger.getLogger(PersonaDAO.class.getName()).log(Level.SEVERE, null, ex);
} finally {
con.cerrarConxecion();
}
return false;
}
@Override
public PersonaDTO read(Object key) {
PreparedStatement ps;
ResultSet rs;
PersonaDTO pers = null;
try {
ps = con.getCnn().prepareStatement(SQL_READ);
ps.setString(1, key.toString());
rs = ps.executeQuery();
while (rs.next()) {
pers = new PersonaDTO(rs.getInt(1), rs.getString(2), rs.getInt(3));
}
return pers;
} catch (SQLException ex) {
Logger.getLogger(PersonaDAO.class.getName()).log(Level.SEVERE, null, ex);
} finally {
con.cerrarConxecion();
}
return pers;
}
@Override
public List readAll() {
PreparedStatement ps;
ResultSet rs;
List pers = null;
try {
ps = con.getCnn().prepareStatement(SQL_READALL);
rs = ps.executeQuery();
while (rs.next()) {
pers.add(new PersonaDTO(rs.getInt(1), rs.getString(2), rs.getInt(3)));
}
return pers;
} catch (SQLException ex) {
Logger.getLogger(PersonaDAO.class.getName()).log(Level.SEVERE, null, ex);
} finally {
con.cerrarConxecion();
}
return pers;
}
}
package dto;
public class PersonaDTO {
private int id;
private String nombre;
private int edad;
public PersonaDTO() {
}
public PersonaDTO(int id) {
this.id = id;
}
public PersonaDTO(String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;
}
public PersonaDTO(int id, String nombre, int edad) {
this.id = id;
this.nombre = nombre;
this.edad = edad;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public int getEdad() {
return edad;
}
public void setEdad(int edad) {
this.edad = edad;
}
}
package interfaces;
import java.util.List;
public interface Obligacion {
public boolean create(Cualquiercosa c);
public boolean delete(Object key);
public boolean update(Cualquiercosa c);
public Cualquiercosa read(Object key);
public List readAll();
}
<%@page contentType="text/html" pageEncoding="UTF-8"%>
Registro de Datos
Formulario
Id :
Nombre :
Edad :
<%@page import="dto.PersonaDTO"%>
<%
PersonaDTO pers = (PersonaDTO)request.getSession().getAttribute("personaOk");
String infocorrecto = (String)request.getSession().getAttribute("infocorrecto");
%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
Consulta de Datos
<%= infocorrecto.toString() %>
Id : <%= pers.getId() %>
Nombre : <%= pers.getNombre() %>
Edad : <%= pers.getEdad() %>
<%@page import="dto.PersonaDTO" %>
<%
String error = (String)request.getSession().getAttribute("error");
%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
Pagina de Error
Mensaje de Error : <%= error %>
La forma correcta
Creo que es importante recalcar que hacer una aplicación utilizando unicamente JDBC es un sucidio y que la forma correcta de configurar una conexión a la base de datos es por JNDI dando de alta el data source en el server, por que asi el server es quien maneja el numero de conexiones, en la mayoria de los casos los servidores tienen su propio pool de conexiones, también decir que la forma de crear la conexión depende mucho de los frameworks que se esten utilizando, actualmente tengo como hacerlo con Spring y Hibernate que son los frameworks con los que trabajo hoy en dia, asi que los pondre de ejemplo por lo de mucho ruido y pocas nueces:
Configuracón a la base de datos en Spring con Hibernate en la aplicación.
Configuración de la base de datos en Spring con Hibernate por JNDI