Café y Código

14. Proyecto Integrador: Tienda MySQL & Patrón DAO (JDBC)

1. Dependencia Maven y Conexión MySQL (conn/Conexion.java)

Para conectar nuestra aplicación Java con una base de datos MySQL relacional, primero añadimos la dependencia oficial del conector JDBC en nuestro archivo pom.xml:

pom.xml (Dependencia MySQL Connector)
XML
1<dependency>
2 <groupId>mysql</groupId>
3 <artifactId>mysql-connector-java</artifactId>
4 <version>8.0.19</version>
5</dependency>

Luego creamos el paquete conn y la clase Conexion.java encargada de administrar la conexión mediante DriverManager.getConnection():

conn/Conexion.java
JAVA
1package conn;
2
3import java.sql.Connection;
4import java.sql.DriverManager;
5import java.sql.SQLException;
6
7public class Conexion {
8 private static final String URL = "jdbc:mysql://localhost:3306/tienda_db?useSSL=false&serverTimezone=UTC";
9 private static final String USER = "root";
10 private static final String PASSWORD = "admin";
11
12 // Método para obtener una conexión activa
13 public static Connection getConexion() throws SQLException {
14 try {
15 // Cargar Driver JDBC de MySQL
16 Class.forName("com.mysql.cj.jdbc.Driver");
17 return DriverManager.getConnection(URL, USER, PASSWORD);
18 } catch (ClassNotFoundException e) {
19 throw new SQLException("Driver MySQL no encontrado en el classpath.", e);
20 }
21 }
22}

2. Esquema Relacional SQL (schema.sql)

Creamos las tablas relacionales categoria, producto, carrito e item_carrito en MySQL:

schema.sql (Tablas en MySQL)
SQL
1CREATE DATABASE IF NOT EXISTS tienda_db;
2USE tienda_db;
3
4CREATE TABLE categoria (
5 id_categoria INT AUTO_INCREMENT PRIMARY KEY,
6 nombre VARCHAR(100) NOT NULL
7);
8
9CREATE TABLE producto (
10 id_producto INT AUTO_INCREMENT PRIMARY KEY,
11 nombre VARCHAR(150) NOT NULL,
12 precio DECIMAL(10,2) NOT NULL,
13 stock INT NOT NULL,
14 id_categoria INT,
15 FOREIGN KEY (id_categoria) REFERENCES categoria(id_categoria)
16);
17
18CREATE TABLE carrito (
19 id_carrito INT AUTO_INCREMENT PRIMARY KEY,
20 cliente VARCHAR(100) NOT NULL,
21 fecha DATETIME DEFAULT CURRENT_TIMESTAMP
22);
23
24CREATE TABLE item_carrito (
25 id_item INT AUTO_INCREMENT PRIMARY KEY,
26 id_carrito INT NOT NULL,
27 id_producto INT NOT NULL,
28 cantidad INT NOT NULL,
29 FOREIGN KEY (id_carrito) REFERENCES carrito(id_carrito) ON DELETE CASCADE,
30 FOREIGN KEY (id_producto) REFERENCES producto(id_producto)
31);

3. Patrón DAO: Interfaces e Implementaciones JDBC

El Patrón DAO (Data Access Object) abstrae y separa la lógica de acceso a la base de datos de la lógica de negocio del sistema.

dao/ProductoDAO.java (Interfaz DAO)
JAVA
1package dao;
2
3import java.util.List;
4import models.Producto;
5
6public interface ProductoDAO {
7 boolean crear(Producto p);
8 Producto obtenerPorId(int id);
9 List<Producto> listarTodos();
10 boolean actualizarStock(int idProducto, int nuevoStock);
11 boolean eliminar(int id);
12}

Implementación JDBC concreta con PreparedStatement y ResultSet:

dao/impl/ProductoDAOImpl.java (Implementación CRUD JDBC)
JAVA
1package dao.impl;
2
3import conn.Conexion;
4import dao.ProductoDAO;
5import models.Categoria;
6import models.Producto;
7
8import java.sql.*;
9import java.util.ArrayList;
10import java.util.List;
11
12public class ProductoDAOImpl implements ProductoDAO {
13
14 @Override
15 public boolean crear(Producto p) {
16 String sql = "INSERT INTO producto (nombre, precio, stock, id_categoria) VALUES (?, ?, ?, ?)";
17 try (Connection con = Conexion.getConexion();
18 PreparedStatement ps = con.prepareStatement(sql)) {
19 ps.setString(1, p.getNombre());
20 ps.setDouble(2, p.getPrecio());
21 ps.setInt(3, p.getStock());
22 ps.setInt(4, p.getCategoria().getId());
23 return ps.executeUpdate() > 0;
24 } catch (SQLException e) {
25 e.printStackTrace();
26 return false;
27 }
28 }
29
30 @Override
31 public List<Producto> listarTodos() {
32 List<Producto> lista = new ArrayList<>();
33 String sql = "SELECT p.id_producto, p.nombre, p.precio, p.stock, c.id_categoria, c.nombre as cat_nombre " +
34 "FROM producto p JOIN categoria c ON p.id_categoria = c.id_categoria";
35 try (Connection con = Conexion.getConexion();
36 PreparedStatement ps = con.prepareStatement(sql);
37 ResultSet rs = ps.executeQuery()) {
38 while (rs.next()) {
39 Categoria cat = new Categoria(rs.getInt("id_categoria"), rs.getString("cat_nombre"));
40 Producto p = new Producto(
41 rs.getInt("id_producto"),
42 rs.getString("nombre"),
43 rs.getDouble("precio"),
44 rs.getInt("stock"),
45 cat
46 );
47 lista.add(p);
48 }
49 } catch (SQLException e) {
50 e.printStackTrace();
51 }
52 return lista;
53 }
54
55 @Override
56 public Producto obtenerPorId(int id) {
57 String sql = "SELECT p.id_producto, p.nombre, p.precio, p.stock, c.id_categoria, c.nombre as cat_nombre " +
58 "FROM producto p JOIN categoria c ON p.id_categoria = c.id_categoria WHERE p.id_producto = ?";
59 try (Connection con = Conexion.getConexion();
60 PreparedStatement ps = con.prepareStatement(sql)) {
61 ps.setInt(1, id);
62 try (ResultSet rs = ps.executeQuery()) {
63 if (rs.next()) {
64 Categoria cat = new Categoria(rs.getInt("id_categoria"), rs.getString("cat_nombre"));
65 return new Producto(rs.getInt("id_producto"), rs.getString("nombre"), rs.getDouble("precio"), rs.getInt("stock"), cat);
66 }
67 }
68 } catch (SQLException e) {
69 e.printStackTrace();
70 }
71 return null;
72 }
73
74 @Override
75 public boolean actualizarStock(int idProducto, int nuevoStock) {
76 String sql = "UPDATE producto SET stock = ? WHERE id_producto = ?";
77 try (Connection con = Conexion.getConexion();
78 PreparedStatement ps = con.prepareStatement(sql)) {
79 ps.setInt(1, nuevoStock);
80 ps.setInt(2, idProducto);
81 return ps.executeUpdate() > 0;
82 } catch (SQLException e) {
83 e.printStackTrace();
84 return false;
85 }
86 }
87
88 @Override
89 public boolean eliminar(int id) {
90 String sql = "DELETE FROM producto WHERE id_producto = ?";
91 try (Connection con = Conexion.getConexion();
92 PreparedStatement ps = con.prepareStatement(sql)) {
93 ps.setInt(1, id);
94 return ps.executeUpdate() > 0;
95 } catch (SQLException e) {
96 e.printStackTrace();
97 return false;
98 }
99 }
100}

4. Implementación del Carrito DAO y Prueba en Main

main/MainTiendaMySQL.java
JAVA
1package main;
2
3import dao.ProductoDAO;
4import dao.impl.ProductoDAOImpl;
5import models.Producto;
6
7import java.util.List;
8
9public class MainTiendaMySQL {
10 public static void main(String[] args) {
11 System.out.println("⚡ CONECTANDO A MYSQL Y PROBANDO PATRÓN DAO...");
12
13 // Instanciar DAO a través de su interfaz (Inversión de dependencias)
14 ProductoDAO productoDAO = new ProductoDAOImpl();
15
16 // 1. READ: Listar productos almacenados en MySQL
17 List<Producto> productosDB = productoDAO.listarTodos();
18 System.out.println("
19🛒 Catálogo en MySQL (" + productosDB.size() + " productos):");
20 for (Producto p : productosDB) {
21 System.out.println(" - " + p);
22 }
23
24 // 2. UPDATE: Actualizar stock en MySQL
25 if (!productosDB.isEmpty()) {
26 Producto primero = productosDB.get(0);
27 boolean exito = productoDAO.actualizarStock(primero.getId(), primero.getStock() - 1);
28 if (exito) {
29 System.out.println("✅ Stock actualizado en MySQL para " + primero.getNombre());
30 }
31 }
32 }
33}

Ponte a prueba

Demuestra tu dominio sobre el Patrón DAO, JDBC y la persistencia relacional en MySQL.

Dato curioso: JDK 1.0 en 1996; James Gosling y Sun Microsystems. Wikipedia

Ko-fi
Donaciones
Apoyá cafeycodigo con un café en Ko-fi. Colaboradores: insignia, muro y zona exclusiva.