Ejercicio completo desde 0 (VII)

Vamos a implementar las dos cosas que nos faltan: editar y eliminar.

Primero añadimos en la lista de préstamos un enlace a editar y otro a eliminar. La acción en el primero será ‘editar’ y en el segundo eliminar. En los dos casos tenemos que pasar el ‘id’ como parámetro.

Editar tiene un circuito muy parecido a nuevo:
1) Obtenemos los datos y mostramos un formulario con esos datos
2) Enviamos los datos y actualizamos el registro.

Eliminar simplemente captura el id que le pasamos y nos elimina el registro correspondiente.

Código completo:

https://github.com/juanpablofuentes/JavaNetmind/tree/main/prestamos

Ejercicio completo desde 0 (VI)

Una vez nos funcione la lista de préstamos vamos a añadir el botón de nuevo préstamo.

Este es un circuito en dos partes:
1) MOstramos una página para introducir los datos del préstamo
2) Recuperamos los datos y los introducimos en la base de datos.

Todo lo vamos hacer desde el mismo servlet a través de un parámetro accion como en el ejemplo de Categorias.

Si nos pasan la accion ‘nuevo’ mostramos la página para introducir los datos
Si nos pasan la acción insertar recuperamos los parámetros, creamos un objeto préstamo, lo añadimos a la base de datos y redirigimos a la lista.

package com.prestamos.controller;

import java.io.IOException;
import java.sql.Date;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.prestamos.dao.Prestamos;
import com.prestamos.dao.PrestamosDAO;

/**
 * Servlet implementation class PrestamosController
 */
@WebServlet("/prestamos")
public class PrestamosController extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private PrestamosDAO modelo;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public PrestamosController() {
		super();
		modelo = new PrestamosDAO();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		String accion = request.getParameter("accion");
		System.out.println(accion);
		if (accion==null) {
			accion="";
		}
		if (accion.equals("nuevo")) {
			// Pondré el código para mostrar la página para introducir los nuevos datos
			RequestDispatcher dispatcher = request.getRequestDispatcher("nuevo.jsp");
			dispatcher.forward(request, response);
		} else if (accion.equals("insertar")) {
			// Aquí recuperaré los datos y los añadiré a la base de datos
			System.out.println("Hola, preparado para insertar");
			
			// Recupero los datos que me pasan
			String nombre=request.getParameter("nombre");
			String titulo=request.getParameter("titulo");
			Date fecha=Date.valueOf(request.getParameter("fecha"));
			
			// Tengo que darlos de alta en la base de datos ¿Cómo?
			// Con el modelo
			Prestamos nuevo=new Prestamos(0,nombre,titulo,fecha);
			modelo.addPrestamo(nuevo);
			request.setAttribute("prestamos", modelo.getPrestamos());
			RequestDispatcher dispatcher = request.getRequestDispatcher("prestamos.jsp");
			dispatcher.forward(request, response);
			
		} else if (accion.equals("borrar")) {
			// Recupero el id y elimino el registro
			System.out.println("Aquí hay que borrar");
			
			int id=Integer.parseInt(request.getParameter("id"));
			System.out.println(id);
			
		} else if (accion.equals("editar")) {
			// Recuperaré el registro que tenga el id que me pasan y
			// Mandaré los datos a una página para que el usuario los modifique
			System.out.println("recuperar los datos (id) y formulario editar");
		} else if (accion.equals("modificar")) {
			// Recupero los datos que me pasan y modifico el registro en la base de datos
			System.out.println("recuperar los datos (id,nombre,titulo,fecha) y modificar en la base de datos");
		} else {
			request.setAttribute("prestamos", modelo.getPrestamos());
			RequestDispatcher dispatcher = request.getRequestDispatcher("prestamos.jsp");
			dispatcher.forward(request, response);
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mantenimiento prestamos</title>
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

<!-- jQuery library -->
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<!-- Popper JS -->
<script
	src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>

<!-- Latest compiled JavaScript -->
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="container">
	<h1>Lista de préstamos</h1>
	<a href="./prestamos?accion=nuevo" class="btn btn-primary">Nuevo préstamo</a>
	<table class="table table-bordered">
		<thead>
			<tr>
				<th>ID</th>
				<th>Nombre</th>
				<th>Titulo</th>
				<th>Fecha</th>
				<th>Acciones</th>
			</tr>
		</thead>
		<tbody>
			<c:forEach var="prestamo" items="${prestamos}">
				<tr>
					<td><c:out value="${prestamo.idprestamos}" /></td>
					<td><c:out value="${prestamo.nombre}" /></td>
					<td><c:out value="${prestamo.titulo}" /></td>
					<td><c:out value="${prestamo.fecha}" /></td>
					<td><a href="./prestamos?accion=editar&id=${prestamo.idprestamos}">Editar</a> | 
					<a href="./prestamos?accion=borrar&id=${prestamo.idprestamos}">Borrar</a> </td>
				</tr>
			</c:forEach>
		</tbody>

	</table>
	</div>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mantenimiento prestamos</title>
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

<!-- jQuery library -->
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<!-- Popper JS -->
<script
	src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>

<!-- Latest compiled JavaScript -->
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
	<div class="container">
		<h1>Nuevo préstamo</h1>
		<form action="./prestamos?accion=insertar" method="post">
			<div class="form-group">
				<label for="nombre">Nombre:</label> <input type="text"
					class="form-control" placeholder="Nombre" name="nombre">
			</div>
			<div class="form-group">
				<label for="titulo">Título:</label> <input type="text"
					class="form-control" placeholder="Titulo" name="titulo">
			</div>
			<div class="form-group">
				<label for="fecha">Fecha:</label> <input type="text"
					class="form-control" placeholder="Fecha" name="fecha">
			</div>
			<input type="submit"/>
		</form>
	</div>
</body>
</html>

Ejercicio completo desde 0 (V)

Vamos a crear un servlet que nos capture la url ‘/prestamos’.

En el doget vamos a redirigir a la página ‘prestamos.jsp’.

En nuestro index.jsp vamos a poner un enlace a /prestamos.

Si funciona, modificamos el doget del servlet para que recupere todos los prestamos y los envíe a prestamos.jsp

Y modificamos la página prestamos.jsp para que nos mueste el id, nombre, titulo y fecha de los préstamos que nos pasan.

package com.prestamos.controller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.prestamos.dao.PrestamosDAO;

/**
 * Servlet implementation class PrestamosController
 */
@WebServlet("/prestamos")
public class PrestamosController extends HttpServlet {
	private static final long serialVersionUID = 1L;
    private PrestamosDAO modelo;   
    /**
     * @see HttpServlet#HttpServlet()
     */
    public PrestamosController() {
        super();
        modelo=new PrestamosDAO();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		request.setAttribute("prestamos", modelo.getPrestamos());
		RequestDispatcher dispatcher = request.getRequestDispatcher("prestamos.jsp");
		dispatcher.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mantenimiento prestamos</title>
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

<!-- jQuery library -->
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<!-- Popper JS -->
<script
	src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>

<!-- Latest compiled JavaScript -->
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="container">
	<h1>Lista de préstamos</h1>
	<table class="table table-bordered">
		<thead>
			<tr>
				<th>ID</th>
				<th>Nombre</th>
				<th>Titulo</th>
				<th>Fecha</th>
				<th>Acciones</th>
			</tr>
		</thead>
		<tbody>
			<c:forEach var="prestamo" items="${prestamos}">

				<tr>
					<td><c:out value="${prestamo.idprestamos}" /></td>
					<td><c:out value="${prestamo.nombre}" /></td>
					<td><c:out value="${prestamo.titulo}" /></td>
					<td><c:out value="${prestamo.fecha}" /></td>
					<td>Aquí irán las acciones</td>
				</tr>
			</c:forEach>
		</tbody>

	</table>
	</div>
</body>
</html>

Ejercicio completo desde 0 (IV)

Una vez creados los métodos de recuperar vamos a añadir los de modificación:

int addPrestamo(Prestamo prestamo) -> Nos añade un préstamo

int deletePrestamo(int id) -> Nos elimina el préstamo que tenga ese id

int updatePrestamo(Prestamo prestamo) -> Nos modifica el préstamo con los valores que le pasemos.

Probamos todos estos métodos en el Test

package com.prestamos.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class PrestamosDAO {

	// En esta variable almacenamos la conexión a la base de datos
	private Connection con;

	public PrestamosDAO() {
		try {
			// Esta línea registra el driver
			Class.forName("com.mysql.cj.jdbc.Driver");
			// Aquí creamos la conexión con:
			// driver: jdbc:mysql
			// url del servidor: localhost
			// Puerto del servidor: 3306
			// Base de datos: prestamos
			// Usuario: root
			// Contraseña: ""
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/prestamos", "root", "");

		} catch (Exception ex) {
			System.out.println(ex);
		}
	}

	/**
	 * Paso al método el id del préstamo que quiero obtener Me devuelve un POJO que
	 * almacena los datos del registro de la base de datos
	 * 
	 * @param id del registro de la base de datos
	 * @return Prestamos (pojo con los datos)
	 */
	public Prestamos getPrestamo(int id) {
		try {

			// Ir a la base de datos, recuperar el registro que tenga el id
			// Meterlo dentro de un POJO y devolverlo

			// Me creo la sentencia sql que recupera un préstamo con un id
			// Y le pongo un parámetro que será el id. Se representa con un ?
			String sql = "select * from prestamos where idprestamos=?";

			// Una vez tengo el sql me creo la sentencia preparada
			PreparedStatement stmt = con.prepareStatement(sql);

			// Poniendo en el primer parámetro el valor que me están pasando del id
			stmt.setInt(1, id);

			// Recuperamos los resultados dentro de un ResultSet
			ResultSet rs = stmt.executeQuery();

			// El resultset NO COGE todos los registros del select y los tiene como en un
			// array
			// El resultset es como si fuera un puntero, una flecha que nos apunta al primer
			// Registro del select. Para recuperar hay que usar next
			if (rs.next()) {
				// Si hemos podido obtener un registro en rs tenemos todos los datos
				// del registro de la base de datos. ¿Cómo? con rs.get del tipo y nombre
				// de la columna. Ej. rs.getInt(1) o rs.getInt("idprestamos")

				// ¿Qué hago con estos datos? Empaquetarlos dentro de un POJO para poder
				// devolverlos
				Prestamos resultado = new Prestamos(rs.getInt("idprestamos"), rs.getString("nombre"),
						rs.getString("titulo"), rs.getDate("fecha"));

				return resultado;

			} else {
				return null;
			}

		} catch (Exception ex) {
			System.out.println(ex);
			return null;
		}
	}

	public List<Prestamos> getPrestamos() {
		try {

			String sql = "select * from prestamos";

			PreparedStatement stmt = con.prepareStatement(sql);

			ResultSet rs = stmt.executeQuery();

			// Para almacenar todos los registros tengo que crear un arraylist
			List<Prestamos> resultado = new ArrayList<Prestamos>();

			// En esta ocasión no tengo un if porque son varios registros.
			// Tengo que hacer un bucle hasta que no haya registros o lo que es lo mismo
			// MIENTRAS tengamos registros vamos recorriendo
			while (rs.next()) {
				Prestamos elemento = new Prestamos(rs.getInt("idprestamos"), rs.getString("nombre"),
						rs.getString("titulo"), rs.getDate("fecha"));
				resultado.add(elemento);
			}
			return resultado;

		} catch (Exception ex) {
			System.out.println(ex);
			return null;
		}

	}

	public int addPrestamo(Prestamos prestamo) {
		try {

			// Igual que en los métodos anteriores tengo que poner el sql
			// De lo que quiero hacer. En este caso es un insert y... tengo tres parámetros
			String sql="insert into prestamos (nombre,titulo,fecha) values (?,?,?)";
			
			PreparedStatement stmt = con.prepareStatement(sql);

			// Tengo que pasar los parámetros
			stmt.setString(1,prestamo.getNombre() );
			stmt.setString(2, prestamo.getTitulo());
			stmt.setDate(3, prestamo.getFecha());
			
			// Utilizo executeUpdate porque modifico los datos, no obtengo resultados
			// Devuelvo lo que me devuelve el método que son el número de filas afectadas
			return stmt.executeUpdate();
			
		} catch (Exception ex) {
			System.out.println(ex);
			return 0;
		}

	}
	
	public int deletePrestamo(int id) {
		try {

			// Igual que en los métodos anteriores tengo que poner el sql
			// De lo que quiero hacer. En este caso es un delete y... tengo un parámetro
			String sql="delete from prestamos where idprestamos=?";
			
			PreparedStatement stmt = con.prepareStatement(sql);

			// Tengo que pasar los parámetros
			stmt.setInt(1, id);
			
			// Utilizo executeUpdate porque modifico los datos, no obtengo resultados
			// Devuelvo lo que me devuelve el método que son el número de filas afectadas
			return stmt.executeUpdate();
			
		} catch (Exception ex) {
			System.out.println(ex);
			return 0;
		}

	}
	
	public int updatePrestamo(Prestamos prestamo) {
		try {

			// Igual que en los métodos anteriores tengo que poner el sql
			// De lo que quiero hacer. En este caso es un update y... tengo cuatro parámetros
			String sql="update prestamos set nombre=?,titulo=?,fecha=? where idprestamos=?";
			
			PreparedStatement stmt = con.prepareStatement(sql);

			// Tengo que pasar los parámetros
			stmt.setString(1,prestamo.getNombre() );
			stmt.setString(2, prestamo.getTitulo());
			stmt.setDate(3, prestamo.getFecha());
			stmt.setInt(4, prestamo.getIdprestamos());
			
			// Utilizo executeUpdate porque modifico los datos, no obtengo resultados
			// Devuelvo lo que me devuelve el método que son el número de filas afectadas
			return stmt.executeUpdate();
			
		} catch (Exception ex) {
			System.out.println(ex);
			return 0;
		}

	}
	
	
}

package com.prestamos.dao;

import java.sql.Date;
import java.util.List;

public class TestDAO {

	public static void main(String[] args) {
		
		//Creo un POJO con el constructor a ver si va bien
		Prestamos pepe=new Prestamos(1,"hola","adios",Date.valueOf("2021-01-01"));
		
		// Probamos el objeto DAO. No hace nada, pero si hay error saltará
		PrestamosDAO modelo=new PrestamosDAO();
		
		modelo.addPrestamo(pepe);
		
		modelo.deletePrestamo(4);

		Prestamos modificar=new Prestamos(6,"hola","adios",Date.valueOf("2021-01-01"));
		
		modelo.updatePrestamo(modificar);

	}

}

Ejercicio completo desde 0 (III)

Vamos a crear algunas funciones de la capa de datos. Recordemos que para hacer un mantenimiento necesitamos como mímino cinco funciones en nuestra lista de la compra.

Empecemos por las funciones de recuperar objetos. Crearemos los métodos siguientes:

Prestamos getPrestamo(int id) ->Nos devuelve el préstamo que tenga ese id

List getPrestamos() -> Nos devuelve todos los préstamos de la base de datos

Probamos estos métodos en nuestro Test para ver si funcionan.


package com.prestamos.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class PrestamosDAO {

	// En esta variable almacenamos la conexión a la base de datos
	private Connection con;

	public PrestamosDAO() {
		try {
			// Esta línea registra el driver
			Class.forName("com.mysql.cj.jdbc.Driver");
			// Aquí creamos la conexión con:
			// driver: jdbc:mysql
			// url del servidor: localhost
			// Puerto del servidor: 3306
			// Base de datos: prestamos
			// Usuario: root
			// Contraseña: ""
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/prestamos", "root", "");

		} catch (Exception ex) {
			System.out.println(ex);
		}
	}

	/**
	 * Paso al método el id del préstamo que quiero obtener Me devuelve un POJO que
	 * almacena los datos del registro de la base de datos
	 * 
	 * @param id del registro de la base de datos
	 * @return Prestamos (pojo con los datos)
	 */
	public Prestamos getPrestamo(int id) {
		try {

			// Ir a la base de datos, recuperar el registro que tenga el id
			// Meterlo dentro de un POJO y devolverlo

			// Me creo la sentencia sql que recupera un préstamo con un id
			// Y le pongo un parámetro que será el id. Se representa con un ?
			String sql = "select * from prestamos where idprestamos=?";

			// Una vez tengo el sql me creo la sentencia preparada
			PreparedStatement stmt = con.prepareStatement(sql);

			// Poniendo en el primer parámetro el valor que me están pasando del id
			stmt.setInt(1, id);

			// Recuperamos los resultados dentro de un ResultSet
			ResultSet rs = stmt.executeQuery();

			// El resultset NO COGE todos los registros del select y los tiene como en un
			// array
			// El resultset es como si fuera un puntero, una flecha que nos apunta al primer
			// Registro del select. Para recuperar hay que usar next
			if (rs.next()) {
				// Si hemos podido obtener un registro en rs tenemos todos los datos
				// del registro de la base de datos. ¿Cómo? con rs.get del tipo y nombre
				// de la columna. Ej. rs.getInt(1) o rs.getInt("idprestamos")

				// ¿Qué hago con estos datos? Empaquetarlos dentro de un POJO para poder
				// devolverlos
				Prestamos resultado = new Prestamos(rs.getInt("idprestamos"), rs.getString("nombre"),
						rs.getString("titulo"), rs.getDate("fecha"));

				return resultado;

			} else {
				return null;
			}

		} catch (Exception ex) {
			System.out.println(ex);
			return null;
		}
	}

	public List<Prestamos> getPrestamos() {
		try {

			String sql="select * from prestamos";
			
			PreparedStatement stmt=con.prepareStatement(sql);
			
			ResultSet rs=stmt.executeQuery();
			
			// Para almacenar todos los registros tengo que crear un arraylist
			List<Prestamos> resultado=new ArrayList<Prestamos>();
			
			// En esta ocasión no tengo un if porque son varios registros.
			// Tengo que hacer un bucle hasta que no haya registros o lo que es lo mismo
			// MIENTRAS tengamos registros vamos recorriendo
			while(rs.next()) {
				Prestamos elemento = new Prestamos(rs.getInt("idprestamos"), rs.getString("nombre"),
						rs.getString("titulo"), rs.getDate("fecha"));
				resultado.add(elemento);
			}
			return resultado;
			
		} catch (Exception ex) {
			System.out.println(ex);
			return null;
		}

	}
}

package com.prestamos.dao;

import java.sql.Date;
import java.util.List;

public class TestDAO {

	public static void main(String[] args) {
		
		//Creo un POJO con el constructor a ver si va bien
		Prestamos pepe=new Prestamos(1,"hola","adios",Date.valueOf("2021-01-01"));
		
		// Al imprimir el POJO compruebo que el método toString funciona
		System.out.println(pepe);
		
		// También puedo probar los getters
		System.out.println(pepe.getNombre());
		
		// Probamos el objeto DAO. No hace nada, pero si hay error saltará
		PrestamosDAO modelo=new PrestamosDAO();
		
		Prestamos ana = modelo.getPrestamo(1);
		System.out.println(ana);
		
		Prestamos foo=modelo.getPrestamo(100);
		System.out.println(foo);
		
		List<Prestamos> lista=modelo.getPrestamos();
		
		System.out.println(lista);

	}

}

Ejercicio completo desde 0 (II)

Vamos a crear un proyecto web dinámico, creamos una página index.jsp, le ponemos los estilos de bootstrap y ponemos algo del tipo ‘Mantenimiento de préstamos’. Nada más.

En la carpeta de java creamos un paquete ‘com.prestamos.dao’ y dentro vamos a crear un archivo ‘Prestamos.java’ que es un POJO de la tabla préstamos.

Crearemos también un archivo ‘PrestamosDAO.java’ donde crearemos nuestra capa de datos, de momento con la conexión nada más.

Crearemos un archivo ‘TestDAO.java’ con un main para probar. De momento creando un objeto PrestamosDao para ver si se conecta bien.

package com.prestamos.dao;

import java.sql.Date;

// el pojo PRESTAMOS sólo nos sirve para almacenar valores de la base de datos
// Es como un 'pack' donde yo meto toda la información de un registro
public class Prestamos {
	// Lo importante son las propiedades, porque en un POJO el resto de cosas
	// Se generan automáticamente
	private int idprestamos;
	private String nombre;
	private String titulo;
	private Date fecha;
	
	
	@Override
	public String toString() {
		return "Prestamos [idprestamos=" + idprestamos + ", nombre=" + nombre + ", titulo=" + titulo + ", fecha="
				+ fecha + "]";
	}
	
	public Prestamos(int idprestamos, String nombre, String titulo, Date fecha) {
		super();
		this.idprestamos = idprestamos;
		this.nombre = nombre;
		this.titulo = titulo;
		this.fecha = fecha;
	}
	/**
	 * @return the idprestamos
	 */
	public int getIdprestamos() {
		return idprestamos;
	}
	/**
	 * @param idprestamos the idprestamos to set
	 */
	public void setIdprestamos(int idprestamos) {
		this.idprestamos = idprestamos;
	}
	/**
	 * @return the nombre
	 */
	public String getNombre() {
		return nombre;
	}
	/**
	 * @param nombre the nombre to set
	 */
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
	/**
	 * @return the titulo
	 */
	public String getTitulo() {
		return titulo;
	}
	/**
	 * @param titulo the titulo to set
	 */
	public void setTitulo(String titulo) {
		this.titulo = titulo;
	}
	/**
	 * @return the fecha
	 */
	public Date getFecha() {
		return fecha;
	}
	/**
	 * @param fecha the fecha to set
	 */
	public void setFecha(Date fecha) {
		this.fecha = fecha;
	}
	
	
	
}

package com.prestamos.dao;

import java.sql.Connection;
import java.sql.DriverManager;

public class PrestamosDAO {

	// En esta variable almacenamos la conexión a la base de datos
	private Connection con;

	public PrestamosDAO() {
		try {
			// Esta línea registra el driver
			Class.forName("com.mysql.cj.jdbc.Driver");
			// Aquí creamos la conexión con:
			// driver: jdbc:mysql
			// url del servidor: localhost
			// Puerto del servidor: 3306
			// Base de datos: prestamos
			// Usuario: root
			// Contraseña: ""
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/prestamos", "root", "");

		} catch (Exception ex) {
			System.out.println(ex);
		}
	}
	
}


package com.prestamos.dao;

import java.sql.Date;

public class TestDAO {

	public static void main(String[] args) {
		
		//Creo un POJO con el constructor a ver si va bien
		Prestamos pepe=new Prestamos(1,"hola","adios",Date.valueOf("2021-01-01"));
		
		// Al imprimir el POJO compruebo que el método toString funciona
		System.out.println(pepe);
		
		// También puedo probar los getters
		System.out.println(pepe.getNombre());
		
		// Probamos el objeto DAO. No hace nada, pero si hay error saltará
		PrestamosDAO modelo=new PrestamosDAO();

	}

}

Ejercicio completo desde 0 (I)

Quiero guardar un listado de los libros que presto y lo almacenaré en una tabla como la siguiente:

prestamos

id int
nombre varchar(45)
titulo varchar(100)
fecha date

Crearemos una base de datos con esta tabla e introduciremos un par de datos a ver si funciona.

Mantenimiento Web III (vistas)

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mantenimiento web</title>
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
	<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Patrick+Hand&display=swap" rel="stylesheet"> 
<link href="css/estilo.css" rel="stylesheet"> 

</head>
<body>
	<div class="container">
		<div class="jumbotron">
			<h1>Mantenimiento web</h1>
			<p>Página de ejemplo de todo el contenido del curso
		</div>
		<a href="categorias">Mantenimiento de categorías</a>
	</div>
</body>
</html>

categoria_nueva.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mantenimiento web</title>
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link
	href="https://fonts.googleapis.com/css2?family=Patrick+Hand&display=swap"
	rel="stylesheet">
<link href="css/estilo.css" rel="stylesheet">

</head>
<body>
	<div class="container">
		<div class="jumbotron">
			<h1>Nueva categoría</h1>
			<p>Introduzca los datos de la categoría</p>
		</div>

		<form action="./categorias?accion=insertar" method="post">
			<div class="form-group">
				<label for="nombre">Nombre:</label> <input type="text"
					class="form-control" placeholder="Introduzca el nombre" name="nombre">
			</div>
			
			<button type="submit" class="btn btn-primary">Enviar</button>
		</form>

	</div>
</body>
</html>

categoria_editar.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mantenimiento web</title>
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link
	href="https://fonts.googleapis.com/css2?family=Patrick+Hand&display=swap"
	rel="stylesheet">
<link href="css/estilo.css" rel="stylesheet">

</head>
<body>
	<div class="container">
		<div class="jumbotron">
			<h1>Editar categoría</h1>
			<p>Introduzca los datos de la categoría</p>
		</div>

		<form action="./categorias?accion=actualizar" method="post">
			<div class="form-group">
				<label for="nombre">Id:</label> <input type="text"
					class="form-control" readonly placeholder="Introduzca el nombre" name="id" value="${categoria.category_id }">
			</div>
			<div class="form-group">
				<label for="nombre">Nombre:</label> <input type="text"
					class="form-control" placeholder="Introduzca el nombre" name="nombre" value="${categoria.name }">
			</div>
			
			<button type="submit" class="btn btn-primary">Enviar</button>
		</form>

	</div>
</body>
</html>

catgorias.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mantenimiento web</title>
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link
	href="https://fonts.googleapis.com/css2?family=Patrick+Hand&display=swap"
	rel="stylesheet">
<link href="css/estilo.css" rel="stylesheet">

</head>
<body>
	<div class="container">
		<div class="jumbotron">
			<h1>Mantenimiento de Categorías</h1>
			<p>Aquí podrá usted hacer el mantenimiento de todas las
				categorías</p>
		</div>
		<a href="categorias?accion=nueva">Añadir una categoría</a>

		<table class="table table-striped">
			<thead>
				<tr>
					<th>Id</th>
					<th>Nombre</th>
					<th>Fecha</th>
					<th>Acciones</th>
				</tr>
			</thead>
			<tbody>
			<c:forEach var="categoria" items="${categorias}">
				<tr>
					<td><c:out value="${categoria.category_id}"/></td>
					<td><c:out value="${categoria.name}"/></td>
					<td><c:out value="${categoria.last_update}"/></td>
					<td><a href="categorias?accion=borrar&id=<c:out value="${categoria.category_id}"/>">Eliminar</a>
					 | <a href="categorias?accion=editar&id=<c:out value="${categoria.category_id}"/>">Editar</a></td>
				</tr>
				</c:forEach>
			</tbody>
		</table>

	</div>
</body>
</html>

Mantenimiento web II (Controlador)

package com.mantenimiento.controller;

import java.io.IOException;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.mantenimiento.dao.Categoria;
import com.mantenimiento.dao.CategoriaDAO;

/**
 * Servlet implementation class Categorias
 */
@WebServlet("/categorias")
public class Categorias extends HttpServlet {
	private static final long serialVersionUID = 1L;

	CategoriaDAO modelo;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public Categorias() {
		super();
		modelo = new CategoriaDAO();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// Tendré que tener una serie de urls para el mantenimiento CRUD
		// Cuando me pongan esa url tendré que hacer lo que haga falta

		// EJemplo: si yo quiero añadir una categoría tendré dos 'pantallas'
		// 1) Un formulario que nos pida los datos de la categoría: accion=nueva
		// 2) Una acción que recupere esos datos y dé de alta la categoría
		// accion=insertar
		String accion = request.getParameter("accion");
		if (accion == null) {
			accion = "";
		}
		Integer id;
		switch (accion) {
		case "nueva":
			response.sendRedirect("categoria_nueva.jsp");
			break;
		case "insertar":
			System.out.println("Insertar");
			String nombre = request.getParameter("nombre");
			System.out.println(nombre);
			modelo.addCategoria(nombre);
			response.sendRedirect("categorias");
			break;

		case "editar":
			id = Integer.parseInt(request.getParameter("id"));
			if (id != null) {
				Categoria cat = modelo.getCategoria(id);
				request.setAttribute("categoria", cat);
				RequestDispatcher dispatcher = request.getRequestDispatcher("categoria_editar.jsp");
				dispatcher.forward(request, response);

			}
			break;
		case "actualizar":
			System.out.println("Actualizar");
			String nombre2 = request.getParameter("nombre");
			id = Integer.parseInt(request.getParameter("id"));
			Categoria cat = new Categoria(id, nombre2);
			System.out.println(nombre2);
			modelo.updateCategoria(cat);
			response.sendRedirect("categorias");
			break;
		case "borrar":
			System.out.println("Eliminar");
			id = Integer.parseInt(request.getParameter("id"));
			if (id != null) {
				modelo.deleteCategoria(id);
			}
			response.sendRedirect("categorias");
			break;

		default:
			List<Categoria> categorias = modelo.getCategorias();
			request.setAttribute("categorias", categorias);
			RequestDispatcher dispatcher = request.getRequestDispatcher("categorias.jsp");
			dispatcher.forward(request, response);

			break;
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

Mantenimiento web (I) Modelo

POJO categorías:

package com.mantenimiento.dao;

import java.sql.Date;


//Esto es un POJO que representa a los registros de la tabla category
public class Categoria {

	// Los campos los llamamos igual que en la base de datos
	private int category_id;
	private String name;
	private Date last_update;
	
	// Creamos un constructor para crear fácilmente objetos
	public Categoria(int category_id, String name) {
		super();
		this.category_id = category_id;
		this.name = name;
	}
	public Categoria(int category_id, String name, Date last_update) {
		this(category_id,name);
		this.last_update= last_update;
	}
	// Getters y setters que son imprescindibles
	/**
	 * @return the category_id
	 */
	public int getCategory_id() {
		return category_id;
	}
	/**
	 * @param category_id the category_id to set
	 */
	public void setCategory_id(int category_id) {
		this.category_id = category_id;
	}
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	/**
	 * @return the last_update
	 */
	public Date getLast_update() {
		return last_update;
	}
	/**
	 * @param last_update the last_update to set
	 */
	public void setLast_update(Date last_update) {
		this.last_update = last_update;
	}

	@Override
	public String toString() {
		return "Categoria [category_id=" + category_id + ", name=" + name + ", last_update=" + last_update + "]";
	}
	
	
	
}

Acceso a datos (DAO):

package com.mantenimiento.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class CategoriaDAO {

	// Tengo que crear una conexión a la base de datos
	private Connection con;
	private int max_records = 1000;

	public CategoriaDAO() {
		try {
			// Me conecto a la base de datos. Si no da error todo OK
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/sakila", "root", "");

		} catch (Exception ex) {
			System.out.println(ex);
		}
	}

	// Tengo que implementar todas las opciones del CRUD

	// Obtener una categoría
	public Categoria getCategoria(int id) {
		try {
			String sql = "select * from category where category_id=?";
			PreparedStatement stmt = con.prepareStatement(sql);

			stmt.setInt(1, id);
			
			ResultSet rs = stmt.executeQuery();
			if (rs.next()) {
				Categoria categoria=new Categoria(rs.getInt("category_id"),rs.getString("name"),rs.getDate("last_update"));
				return categoria;
			}else {
				return null;
			}
			
		} catch (Exception ex) {
			System.out.println(ex);
			return null;
		}
	}

	// Obtener todas las categorías
	public List<Categoria> getCategorias() {
		try {
			// Consulta sql para obtener todas las categorías
			String sql = "select * from category limit ?";
			PreparedStatement stmt = con.prepareStatement(sql);
			// Con la salvedad de que ponemos un límite de 1000 registros por si acaso
			stmt.setInt(1, max_records);
			
			// Obtenemos el puntero a los resultados
			ResultSet rs = stmt.executeQuery();
			
			// Yo necesito almacenar todos los registros que voy obteniendo
			// ¿Dónde? En un ArrayList del tipo Categoria
			List<Categoria> categorias=new ArrayList<Categoria>();
			
			// MIentras haya registros en la base de datos
			while (rs.next()) {
				// Creame un objeto categoría con los datos de la base de datos
				Categoria categoria=new Categoria(rs.getInt("category_id"),rs.getString("name"),rs.getDate("last_update"));
				// Lo añadimos al arraylist
				categorias.add(categoria);
			}
			// Devolvemos la lista con todas las categorías que hemos creado
			// A partir de los registros de la base de datos
			return categorias;
		} catch (Exception ex) {
			System.out.println(ex);
			return null;
		}
	}
	// Crear una categoría
	public int addCategoria(Categoria categoria) {
		return addCategoria(categoria.getName());
	}

	// Crear una categoría
	public int addCategoria(String name) {
		try {
			String sql = "insert into category (name) values (?)";
			PreparedStatement stmt = con.prepareStatement(sql);

			stmt.setString(1, name);

			int res = stmt.executeUpdate();
			return res;
		} catch (Exception ex) {
			System.out.println(ex);
			return -1;
		}
	}

	// Eliminar categoría
	public int deleteCategoria(Categoria categoria) {
		return deleteCategoria(categoria.getCategory_id());

	}

	// Eliminar categoría
	public int deleteCategoria(int id) {
		try {
			String sql = "delete from category where category_id=?";
			PreparedStatement stmt = con.prepareStatement(sql);

			stmt.setInt(1, id);

			int res = stmt.executeUpdate();
			return res;

		} catch (Exception ex) {
			System.out.println(ex);
			return -1;
		}
	}

	// Modificar categoría
	public int updateCategoria(Categoria categoria) {
		try {
			String sql = "update category set name=? where category_id=?";
			PreparedStatement stmt = con.prepareStatement(sql);

			stmt.setString(1, categoria.getName());
			stmt.setInt(2, categoria.getCategory_id());

			int res = stmt.executeUpdate();
			return res;
		} catch (Exception ex) {
			System.out.println(ex);
			return -1;
		}
	}
}

Por si lo queremos probar:


package com.mantenimiento.dao;

import java.util.List;

public class TestDao {

	public static void main(String[] args) {
		Categoria drama=new Categoria(1,"Terrorífica");
		System.out.println(drama);
		System.out.println(drama.getName());
		
		CategoriaDAO modelo=new CategoriaDAO();
		
		System.out.println(modelo.getCategorias());
		List<Categoria> categorias=modelo.getCategorias();
		for(Categoria categoria:categorias) {
			System.out.println(categoria.getName());
		}
	}

}