Persistencia de datos con Java y MySQL: Una guía práctica

La persistencia de datos es un aspecto fundamental en el desarrollo de aplicaciones, ya que permite guardar y recuperar información de forma permanente. En este artículo, exploraremos cómo integrar Java con MySQL para manejar la persistencia de datos de manera eficiente.

¿Qué es la persistencia de datos?

La persistencia de datos se refiere a la capacidad de almacenar información de manera que esta persista más allá del ciclo de vida de la aplicación. En aplicaciones modernas, esto generalmente implica el uso de bases de datos como MySQL junto con un lenguaje de programación como Java.

Preparativos iniciales

  1. Instalar MySQL: Descarga e instala XAMPP en tu máquina.
  2. Configurar tu entorno de desarrollo en Java: Asegúrate de tener:
  • Java Development Kit (JDK).
  • Un IDE como IntelliJ IDEA o Netbeans.
  1. Crear la base de datos: Ejecuta un script SQL como el siguiente para crear una base de datos y una tabla simple:
  1. Crear el Proyecto :

Inicia IntelliJ IDEA y selecciona "New Project" desde la pantalla de bienvenida, elige "Maven" en la lista de opciones.

  1. Estructura del Proyecto : La carpeta src se divide en dos subcarpetas principales:
    1. src/main/java: Aquí es donde va el código fuente principal de tu aplicación.
    2. src/main/resources: Para los recursos que necesitas en el tiempo de ejecución, como archivos de configuración, imágenes o archivos de datos.
    3. src/test/java: Aquí va el código de pruebas unitarias.
    4. src/test/resources: Recursos utilizados específicamente para tus pruebas.

Agrega esta dependencia en tu archivo pom.xml:

<dependencies>
     <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>8.0.33</version>
     </dependency>
</dependencies>

Escribe la clase DBConnection para establecer la conexión con la base de datos.

public class DBConnection {

    private static String url = "jdbc:mysql://localhost:3306/negocio";
    private static String usuario = "root";
    private static String password = "";
    
    public static Connection getInstance() throws SQLException {
        return DriverManager.getConnection(url,usuario,password);
    }
    
}

Crear la Entidad : Define una clase que represente la tabla de la base de datos.

public class Producto {
    private Long idProducto;
    private String nombreProducto;
    private Double precio;
    private Integer idCategoria;
    
    public Producto(Long idProducto, String nombreProducto, Double precio, Integer idCategoria) {
        this.idProducto = idProducto;
        this.nombreProducto = nombreProducto;
        this.precio = precio;
        this.idCategoria = idCategoria;
    }

    public Producto() {
    }

    public Long getIdProducto() {
        return idProducto;
    }

    public void setIdProducto(Long idProducto) {
        this.idProducto = idProducto;
    }

    public String getNombreProducto() {
        return nombreProducto;
    }

    public void setNombreProducto(String nombreProducto) {
        this.nombreProducto = nombreProducto;
    }

    public Double getPrecio() {
        return precio;
    }

    public void setPrecio(Double precio) {
        this.precio = precio;
    }

    public Integer getIdCategoria() {
        return idCategoria;
    }

    public void setIdCategoria(Integer idCategoria) {
        this.idCategoria = idCategoria;
    }

    @Override
    public String toString() {
        return "Producto{" +
                "idProducto=" + idProducto +
                ", nombreProducto='" + nombreProducto + '\'' +
                ", precio=" + precio +
                ", idCategoria=" + idCategoria +
                '}';
    }
}

Crear el Repositorio (Interfaz) : Define las operaciones que realizarás con la base de datos.

public interface Repositorio<T> {
    
    List<T> listar();
    
    T buscarPorId(Long id);
    
    void guardar(T t);
    
    void eliminar(Long id);
}

Implementar el Repositorio (Clase Impl) :Implementa las operaciones de la interfaz Repository.

public class ProductoRepository implements Repositorio<Producto>{

    private static final String Tabla = "PRODUCTOS";

    private Connection getConexion() throws SQLException {
        return DBConnection.getInstance();
    }
    
    @Override
    public List<Producto> listar() {
        return List.of();
    }

    @Override
    public Producto buscarPorId(Long id) {
        return null;
    }

    @Override
    public void guardar(Producto producto) {

    }

    @Override
    public void eliminar(Long id) {

    }
}

listar

  @Override
    public List<Producto> listar() {
        List<Producto> productos = new ArrayList<>();
        String sql = "SELECT * FROM " + Tabla;
        try (Statement sta = getConexion().createStatement();
             ResultSet rs = sta.executeQuery(sql)) {
            while (rs.next()) {
                Producto producto = crearProducto(rs);
                productos.add(producto);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return productos;
    }

    private Producto crearProducto(ResultSet rs) throws SQLException {
        Producto producto = new Producto();
        producto.setIdProducto(rs.getLong("id_producto"));
        producto.setNombreProducto(rs.getString("nombre_producto"));
        producto.setPrecio(rs.getDouble("precio"));
        producto.setIdCategoria(rs.getInt("id_categoria"));
        return producto;
    }

Ahora probamos desde el main

public class Main {
    public static void main(String[] args) {
        Repositorio<Producto> repositorio = new ProductoRepository();
        repositorio.listar()
                .stream()
                .forEach(p -> System.out.println(p.toString()));
    }
}

Buscar por id

    @Override
    public Producto buscarPorId(Long id) {
        Producto producto = null;
        String sql = "SELECT * FROM " + Tabla + " WHERE id_producto = " + id;
        try (Statement sta = getConexion().createStatement();
             ResultSet rs = sta.executeQuery(sql)) {

            if (rs.next()) {
                producto = crearProducto(rs);
            }
        } catch (SQLException e) {
            e.printStackTrace(); // Manejar la excepción adecuadamente
        }
        return producto;
    }
Repositorio<Producto> repositorio = new ProductoRepository();
        Producto producto = repositorio.buscarPorId(1L);

        if (producto != null) {
            System.out.println("Producto encontrado: " + producto);
        } else {
            System.out.println("Producto no encontrado.");
        }

Ahora probamos desde el main

guardar o actualizar

 @Override
    public void guardar(Producto producto) {
        String sql;
        if (producto.getIdProducto() != null && producto.getIdProducto() > 0) {
            sql = "UPDATE " + Tabla + " SET nombre_producto = ?, precio = ?, id_categoria = ? WHERE id_producto = ?";
            try (PreparedStatement ps = getConexion().prepareStatement(sql)) {
                ps.setString(1, producto.getNombreProducto());
                ps.setDouble(2, producto.getPrecio());
                ps.setInt(3, producto.getIdCategoria());
                ps.setLong(4, producto.getIdProducto());
                ps.executeUpdate();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else {
            sql = "INSERT INTO " + Tabla + " (nombre_producto, precio, id_categoria) VALUES (?, ?, ?)";
            try (PreparedStatement ps = getConexion().prepareStatement(sql)) {
                ps.setString(1, producto.getNombreProducto());
                ps.setDouble(2, producto.getPrecio());
                ps.setInt(3, producto.getIdCategoria());
                ps.executeUpdate();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

probar desde el main

 Repositorio<Producto> repositorio = new ProductoRepository();
        Producto nuevoProducto = new Producto();
        nuevoProducto.setNombreProducto("Nuevo Producto");
        nuevoProducto.setPrecio(99.99);
        nuevoProducto.setIdCategoria(1);
        repositorio.guardar(nuevoProducto);

Eliminar

@Override
    public void eliminar(Long id) {
        String sql = "DELETE FROM " + Tabla + " WHERE id_producto = ?";
        try (PreparedStatement ps = getConexion().prepareStatement(sql)) {
            ps.setLong(1, id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(); // Handle the exception appropriately
        }
    }

probar desde el main

   Repositorio<Producto> repositorio = new ProductoRepository();
        repositorio.eliminar(2L);