Datos del Estudiante

Por favor, ingresa tus datos completos, para iniciar la práctica guiada.

Alumno:

Grupo:

Progreso de la Práctica

0%

0 de 8 apartados completados

1. Script de la Base de Datos (MySQL)

Desarrolla el siguiente script en tu servidor local utilizando la interfaz de PHPMyAdmin:

CREATE DATABASE IF NOT EXISTS MiEmpresa;
USE MiEmpresa;

CREATE TABLE empleados (
    id_empleado INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(50) NOT NULL,
    apellidos VARCHAR(100) NOT NULL,
    anio_nacimiento INT NOT NULL,
    edad INT NOT NULL,
    sexo VARCHAR(15) NOT NULL,
    areas_interes VARCHAR(200)
);

Asegúrate de que el servicio de MySQL esté corriendo en tu panel de control de XAMPP antes de ejecutar la sentencia.

Diseño de la Base de Datos en PHPMyAdmin

2. Creación del Proyecto en el IDE

Utilizando el entorno de desarrollo de tu elección (Ej. NetBeans 29), realiza la siguiente configuración inicial:

  • Crea un proyecto de tipo JAVA Application.
  • Asigna al proyecto el nombre exacto de: CRUD.
  • Importante: Desmarca la opción de crear la clase principal (main), ya que la ejecución se controlará de manera independiente desde la interfaz gráfica más adelante.
Configuración del Proyecto en el IDE

3. Clase ConexionDB.java

Crea una clase llamada ConexionDB.java dentro del paquete CRUD. Esta clase se encarga exclusivamente de establecer la comunicación física con el servidor local de XAMPP.

package CRUD;

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

public class ConexionDB {
    private static final String URL = "jdbc:mysql://localhost:3306/MiEmpresa?useSSL=false&serverTimezone=UTC";
    private static final String USER = "root";
    private static final String PASSWORD = ""; // Por defecto vacío en XAMPP

    public Connection conectar() {
        Connection conexion = null;
        try {
            // Carga dinámica del driver para compatibilidad
            Class.forName("com.mysql.cj.jdbc.Driver");
            conexion = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (ClassNotFoundException e) {
            System.err.println("Error: No se encontró el Driver de MySQL: " + e.getMessage());
        } catch (SQLException e) {
            System.err.println("Error de conexión a la BD: " + e.getMessage());
        }
        return conexion;
    }
}
Estructura de la Clase ConexionDB

4. Clase Empleado.java (Modelo / POJO)

Crea la clase Empleado.java dentro del paquete CRUD. Funciona como un molde o contenedor de transporte de datos entre las distintas capas lógicas del sistema.

package CRUD;

public class Empleado {
    private int idEmpleado;
    private String nombre;
    private String apellidos;
    private int anioNacimiento;
    private int edad;
    private String sexo;
    private String areasInteres;

    // Constructor vacío
    public Empleado() {}

    // Constructor completo
    public Empleado(int idEmpleado, String nombre, String apellidos, int anioNacimiento, int edad, String sexo, String areasInteres) {
        this.idEmpleado = idEmpleado;
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.anioNacimiento = anioNacimiento;
        this.edad = edad;
        this.sexo = sexo;
        this.areasInteres = areasInteres;
    }

    // Getters y Setters
    public int getIdEmpleado() { return idEmpleado; }
    public void setIdEmpleado(int idEmpleado) { this.idEmpleado = idEmpleado; }

    public String getNombre() { return nombre; }
    public void setNombre(String nombre) { this.nombre = nombre; }

    public String getApellidos() { return apellidos; }
    public void setApellidos(String apellidos) { this.apellidos = apellidos; }

    public int getAnioNacimiento() { return anioNacimiento; }
    public void setAnioNacimiento(int anioNacimiento) { this.anioNacimiento = anioNacimiento; }

    public int getEdad() { return edad; }
    public void setEdad(int edad) { this.edad = edad; }

    public String getSexo() { return sexo; }
    public void setSexo(String sexo) { this.sexo = sexo; }

    public String getAreasInteres() { return areasInteres; }
    public void setAreasInteres(String areasInteres) { this.areasInteres = areasInteres; }
}
Estructura de la Clase Empleado

5. Clase EmpleadoDAO.java (Data Access Object)

Crea la clase EmpleadoDAO.java. Su objetivo esencial es la persistencia, encargándose de enviar y procesar las sentencias SQL (INSERT, SELECT, UPDATE, DELETE) directo en el motor de Base de Datos.

package CRUD;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class EmpleadoDAO {
    private final ConexionDB conexionDB = new ConexionDB();

    // 1. CREATE (Insertar)
    public boolean agregar(Empleado emp) {
        String sql = "INSERT INTO empleados (nombre, apellidos, anio_nacimiento, edad, sexo, areas_interes) VALUES (?, ?, ?, ?, ?, ?)";
        try (Connection con = conexionDB.conectar();
             PreparedStatement ps = con.prepareStatement(sql)) {
            ps.setString(1, emp.getNombre());
            ps.setString(2, emp.getApellidos());
            ps.setInt(3, emp.getAnioNacimiento());
            ps.setInt(4, emp.getEdad());
            ps.setString(5, emp.getSexo());
            ps.setString(6, emp.getAreasInteres());
            return ps.executeUpdate() > 0;
        } catch (SQLException e) {
            System.err.println("Error al agregar: " + e.getMessage());
            return false;
        }
    }

    // 2. READ (Listar todos)
    public List<Empleado> listar() {
        List<Empleado> lista = new ArrayList<>();
        String sql = "SELECT * FROM empleados";
        try (Connection con = conexionDB.conectar();
             PreparedStatement ps = con.prepareStatement(sql);
             ResultSet rs = ps.executeQuery()) {
            while (rs.next()) {
                Empleado emp = new Empleado();
                emp.setIdEmpleado(rs.getInt("id_empleado"));
                emp.setNombre(rs.getString("nombre"));
                emp.setApellidos(rs.getString("apellidos"));
                emp.setAnioNacimiento(rs.getInt("anio_nacimiento"));
                emp.setEdad(rs.getInt("edad"));
                emp.setSexo(rs.getString("sexo"));
                emp.setAreasInteres(rs.getString("areas_interes"));
                lista.add(emp);
            }
        } catch (SQLException e) {
            System.err.println("Error al listar: " + e.getMessage());
        }
        return lista;
    }

    // 3. UPDATE (Modificar)
    public boolean modificar(Empleado emp) {
        String sql = "UPDATE empleados SET nombre=?, apellidos=?, anio_nacimiento=?, edad=?, sexo=?, areas_interes=? WHERE id_empleado=?";
        try (Connection con = conexionDB.conectar();
             PreparedStatement ps = con.prepareStatement(sql)) {
            ps.setString(1, emp.getNombre());
            ps.setString(2, emp.getApellidos());
            ps.setInt(3, emp.getAnioNacimiento());
            ps.setInt(4, emp.getEdad());
            ps.setString(5, emp.getSexo());
            ps.setString(6, emp.getAreasInteres());
            ps.setInt(7, emp.getIdEmpleado());
            return ps.executeUpdate() > 0;
        } catch (SQLException e) {
            System.err.println("Error al modificar: " + e.getMessage());
            return false;
        }
    }

    // 4. DELETE (Eliminar)
    public boolean eliminar(int id) {
        String sql = "DELETE FROM empleados WHERE id_empleado=?";
        try (Connection con = conexionDB.conectar();
             PreparedStatement ps = con.prepareStatement(sql)) {
            ps.setInt(1, id);
            return ps.executeUpdate() > 0;
        } catch (SQLException e) {
            System.err.println("Error al eliminar: " + e.getMessage());
            return false;
        }
    }
}
Métodos CRUD en EmpleadoDAO

6. Interfaz y Controlador: FrmEmpleados.java

Crea un formulario utilizando la biblioteca de javax.swing. Esta clase une la representación visual con los controladores de acción del CRUD. Es la clase que contiene el Método Principal Main ()



package CRUD;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Calendar;
import java.util.List;

public class FrmEmpleados extends JFrame {
    // Componentes del Formulario
    private JTextField txtNombre, txtApellidos, txtEdad, txtOtro;
    private JComboBox cbAnioNacimiento;
    private JRadioButton rbFemenino, rbMasculino;
    private ButtonGroup grupoSexo;
    private JCheckBox chkFutbol, chkVoleiball, chkOtro;
    private JTable tblEmpleados;
    private DefaultTableModel modeloTabla;
    
    // Botones de Acción
    private JButton btnAgregar, btnModificar, btnEliminar, btnCerrar;
    
    // Instancia del DAO para operaciones
    private final EmpleadoDAO empleadoDAO = new EmpleadoDAO();
    private int idSeleccionado = -1; // Almacena el ID del registro seleccionado de la tabla

    public FrmEmpleados() {
        setTitle("Mantenimiento de Empleados");
        setSize(850, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setResizable(false);
        initComponents();
        listarEmpleados();
    }

    private void initComponents() {
        // Contenedor principal con Layout nulo para posicionamiento absoluto fiel a la captura
        JPanel panelPrincipal = new JPanel(null);
        panelPrincipal.setBackground(new Color(245, 245, 245));
        setContentPane(panelPrincipal);

        // --- SECCIÓN: Datos Generales del Empleado ---
        JPanel panelDatos = new JPanel(null);
        panelDatos.setBounds(20, 20, 790, 240);
        panelDatos.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createEtchedBorder(), "Datos Generales del Empleado", TitledBorder.LEFT, TitledBorder.TOP, new Font("Arial", Font.BOLD, 12)));
        panelPrincipal.add(panelDatos);

        JLabel lblNombre = new JLabel("Nombre del emplea...");
        lblNombre.setBounds(20, 30, 130, 25);
        panelDatos.add(lblNombre);

        txtNombre = new JTextField();
        txtNombre.setBounds(160, 30, 150, 25);
        panelDatos.add(txtNombre);

        JLabel lblApellidos = new JLabel("Apellidos:");
        lblApellidos.setBounds(20, 70, 130, 25);
        panelDatos.add(lblApellidos);

        txtApellidos = new JTextField();
        txtApellidos.setBounds(160, 70, 610, 25);
        panelDatos.add(txtApellidos);

        JLabel lblAnio = new JLabel("Año de nacimiento:");
        lblAnio.setBounds(20, 110, 130, 25);
        panelDatos.add(lblAnio);

        cbAnioNacimiento = new JComboBox<>();
        int anioActual = Calendar.getInstance().get(Calendar.YEAR);
        for (int i = anioActual; i >= 1920; i--) {
            cbAnioNacimiento.addItem(i);
        }
        cbAnioNacimiento.setBounds(160, 110, 90, 25);
        // Evento para calcular automáticamente la edad al cambiar el año de nacimiento
        cbAnioNacimiento.addActionListener(e -> {
            int anioSeleccionado = (int) cbAnioNacimiento.getSelectedItem();
            txtEdad.setText(String.valueOf(anioActual - anioSeleccionado));
        });
        panelDatos.add(cbAnioNacimiento);

        JLabel lblEdad = new JLabel("Edad:");
        lblEdad.setBounds(270, 110, 40, 25);
        panelDatos.add(lblEdad);

        txtEdad = new JTextField("0");
        txtEdad.setBounds(310, 110, 110, 25);
        txtEdad.setEditable(false);
        txtEdad.setBackground(Color.WHITE);
        panelDatos.add(txtEdad);

        JLabel lblSexo = new JLabel("Sexo:");
        lblSexo.setBounds(450, 110, 40, 25);
        panelDatos.add(lblSexo);

        rbFemenino = new JRadioButton("Femenino");
        rbFemenino.setBounds(490, 105, 100, 20);
        rbFemenino.setOpaque(false);
        rbMasculino = new JRadioButton("Masculino");
        rbMasculino.setBounds(490, 125, 100, 20);
        rbMasculino.setOpaque(false);
        grupoSexo = new ButtonGroup();
        grupoSexo.add(rbFemenino);
        grupoSexo.add(rbMasculino);
        panelDatos.add(rbFemenino);
        panelDatos.add(rbMasculino);

        JLabel lblInteres = new JLabel("Areas de Interés:");
        lblInteres.setBounds(20, 170, 130, 25);
        panelDatos.add(lblInteres);

        chkFutbol = new JCheckBox("Fútbol");
        chkFutbol.setBounds(160, 170, 80, 25);
        chkFutbol.setOpaque(false);
        panelDatos.add(chkFutbol);

        chkVoleiball = new JCheckBox("Voleiball");
        chkVoleiball.setBounds(250, 170, 90, 25);
        chkVoleiball.setOpaque(false);
        panelDatos.add(chkVoleiball);

        chkOtro = new JCheckBox("Otro");
        chkOtro.setBounds(370, 170, 60, 25);
        chkOtro.setOpaque(false);
        panelDatos.add(chkOtro);

        txtOtro = new JTextField();
        txtOtro.setBounds(430, 170, 340, 25);
        panelDatos.add(txtOtro);

        // --- SECCIÓN: Lista de Empleados ---
        JPanel panelLista = new JPanel(null);
        panelLista.setBounds(20, 280, 790, 210);
        panelLista.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createEtchedBorder(), "Lista de Empleados", TitledBorder.LEFT, TitledBorder.TOP, new Font("Arial", Font.BOLD, 12)));
        panelPrincipal.add(panelLista);

        modeloTabla = new DefaultTableModel(new Object[]{"Nombre", "Apellidos", "Año", "Edad", "Sexo", "Areas"}, 0);
        tblEmpleados = new JTable(modeloTabla);
        JScrollPane scrollPane = new JScrollPane(tblEmpleados);
        scrollPane.setBounds(15, 25, 760, 165);
        panelLista.add(scrollPane);

        // Evento al dar clic sobre un registro de la JTable
        tblEmpleados.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                cargarCamposDesdeTabla();
            }
        });

        // --- SECCIÓN: Botones de Acción de la Interfaz ---
        btnAgregar = new JButton("Agregar");
        btnAgregar.setBounds(40, 510, 160, 40);
        btnAgregar.addActionListener(e -> accionAgregar());
        panelPrincipal.add(btnAgregar);

        btnModificar = new JButton("Modificar");
        btnModificar.setBounds(230, 510, 160, 40);
        btnModificar.addActionListener(e -> accionModificar());
        panelPrincipal.add(btnModificar);

        btnEliminar = new JButton("Eliminar");
        btnEliminar.setBounds(420, 510, 160, 40);
        btnEliminar.addActionListener(e -> accionEliminar());
        panelPrincipal.add(btnEliminar);

        btnCerrar = new JButton("Cerrar");
        btnCerrar.setBounds(610, 510, 160, 40);
        btnCerrar.addActionListener(e -> System.exit(0));
        panelPrincipal.add(btnCerrar);
    }

    // --- CONTROLADOR: Métodos Lógicos del CRUD ---

    private void listarEmpleados() {
    modeloTabla.setRowCount(0); // Vaciar tabla visual
    List lista = empleadoDAO.listar();
    
    // Usamos un ciclo for tradicional por índice para evitar conflictos de tipo 'Object'
        for (int i = 0; i < lista.size(); i++) {
        Empleado e = (Empleado) lista.get(i); 
        modeloTabla.addRow(new Object[]{
                e.getNombre(),
                e.getApellidos(),
                e.getAnioNacimiento(),
                e.getEdad(),
                e.getSexo(),
                e.getAreasInteres()
        });
      }
    }


private void accionAgregar() {
        Empleado emp = mapearFormulario();
        if (emp != null) {
            if (empleadoDAO.agregar(emp)) {
                JOptionPane.showMessageDialog(this, "¡Empleado guardado exitosamente!");
                limpiarFormulario();
                listarEmpleados();
            } else {
                JOptionPane.showMessageDialog(this, "Error crítico al guardar en la BD.");
            }
        }
    }

    private void accionModificar() {
        if (idSeleccionado == -1) {
            JOptionPane.showMessageDialog(this, "Por favor, seleccione un empleado de la lista.");
            return;
        }
        Empleado emp = mapearFormulario();
        if (emp != null) {
            emp.setIdEmpleado(idSeleccionado);
            if (empleadoDAO.modificar(emp)) {
                JOptionPane.showMessageDialog(this, "¡Registro actualizado!");
                limpiarFormulario();
                listarEmpleados();
            } else {
                JOptionPane.showMessageDialog(this, "Error al intentar modificar.");
            }
        }
    }

    private void accionEliminar() {
        if (idSeleccionado == -1) {
            JOptionPane.showMessageDialog(this, "Por favor, seleccione un empleado de la lista.");
            return;
        }
        int confirmacion = JOptionPane.showConfirmDialog(this, "¿Está seguro de eliminar este registro?", "Confirmar eliminación", JOptionPane.YES_NO_OPTION);
        if (confirmacion == JOptionPane.YES_OPTION) {
            if (empleadoDAO.eliminar(idSeleccionado)) {
                JOptionPane.showMessageDialog(this, "Empleado eliminado correctamente.");
                limpiarFormulario();
                listarEmpleados();
            } else {
                JOptionPane.showMessageDialog(this, "Error al eliminar el registro.");
            }
        }
    }

    private Empleado mapearFormulario() {
        if (txtNombre.getText().trim().isEmpty() || txtApellidos.getText().trim().isEmpty()) {
            JOptionPane.showMessageDialog(this, "Por favor ingrese Nombre y Apellidos.");
            return null;
        }

        String sexo = "";
        if (rbFemenino.isSelected()) sexo = "Femenino";
        else if (rbMasculino.isSelected()) sexo = "Masculino";
        else {
            JOptionPane.showMessageDialog(this, "Seleccione el sexo del empleado.");
            return null;
        }

        // Concatenación de Áreas de Interés como String plano legible
        StringBuilder areas = new StringBuilder();
        if (chkFutbol.isSelected()) areas.append("Fútbol, ");
        if (chkVoleiball.isSelected()) areas.append("Voleiball, ");
        if (chkOtro.isSelected() && !txtOtro.getText().trim().isEmpty()) {
            areas.append(txtOtro.getText().trim()).append(", ");
        }

        String areasStr = areas.toString();
        if (areasStr.endsWith(", ")) {
            areasStr = areasStr.substring(0, areasStr.length() - 2);
        }

        Empleado emp = new Empleado();
        emp.setNombre(txtNombre.getText().trim());
        emp.setApellidos(txtApellidos.getText().trim());
        emp.setAnioNacimiento((int) cbAnioNacimiento.getSelectedItem());
        emp.setEdad(Integer.parseInt(txtEdad.getText()));
        emp.setSexo(sexo);
        emp.setAreasInteres(areasStr);

        return emp;
    }

    private void cargarCamposDesdeTabla() {
        int fila = tblEmpleados.getSelectedRow();
        if (fila >= 0) {
            // Recuperamos los datos del objeto directo en el DAO usando el índice
            List lista = empleadoDAO.listar();
            Empleado emp = (Empleado) lista.get(fila);
            idSeleccionado = emp.getIdEmpleado(); // LLAVE PRIMARIA PARA EL UPDATE/DELETE
            
            txtNombre.setText(emp.getNombre());
            txtApellidos.setText(emp.getApellidos());
            cbAnioNacimiento.setSelectedItem(emp.getAnioNacimiento());
            txtEdad.setText(String.valueOf(emp.getEdad()));
            
            if (emp.getSexo().equalsIgnoreCase("Femenino")) rbFemenino.setSelected(true);
            else rbMasculino.setSelected(true);

            // Reseteo de Checks
            chkFutbol.setSelected(emp.getAreasInteres().contains("Fútbol"));
            chkVoleiball.setSelected(emp.getAreasInteres().contains("Voleiball"));
            
            // Si el texto almacenado tiene más cosas aparte de Fútbol y Voleiball, se mapea al campo "Otro"
            String cleanAreas = emp.getAreasInteres().replace("Fútbol", "").replace("Voleiball", "").replace(",", "").trim();
            if (!cleanAreas.isEmpty()) {
                chkOtro.setSelected(true);
                txtOtro.setText(cleanAreas);
            } else {
                chkOtro.setSelected(false);
                txtOtro.setText("");
            }
        }
    }

    private void limpiarFormulario() {
        txtNombre.setText("");
        txtApellidos.setText("");
        cbAnioNacimiento.setSelectedIndex(0);
        txtEdad.setText("0");
        grupoSexo.clearSelection();
        chkFutbol.setSelected(false);
        chkVoleiball.setSelected(false);
        chkOtro.setSelected(false);
        txtOtro.setText("");
        idSeleccionado = -1;
    }

    public static void main(String[] args) {
        // Ejecución de la interfaz con el hilo de Swing de forma segura
        SwingUtilities.invokeLater(() -> new FrmEmpleados().setVisible(true));
    }
}



                
Diseño Visual de la Interfaz Gráfica Formulario

7. Roles Funcionales de las Clases

Analiza el comportamiento y la responsabilidad de cada estructura generada en el proyecto:

Clase Rol Principal Funcionalidad Clave
ConexionDB Canal de Comunicación Abre y gestiona el puente físico (Connection) entre Java y MySQL en XAMPP.
Empleado Contenedor de Datos (POJO) Molde que almacena en memoria los datos del empleado mediante Getters/Setters.
EmpleadoDAO Persistencia (CRUD) Ejecuta las consultas SQL (INSERT, SELECT, UPDATE, DELETE) en la BD.
FrmEmpleados Interfaz y Controlador Dibuja la pantalla, captura los clics del usuario y actualiza la tabla visual.
Diagrama de Arquitectura de Clases

8. Configuración de Dependencias (Driver SQL)

Para lograr la intercomunicación del sistema con la BD, vincula el conector oficial mediante alguno de los siguientes dos métodos:

Método A: Automatizado por Maven

Paso Acción en NetBeans Datos a Ingresar
1. Ubicar Desplegar el árbol del proyecto; clic derecho en la carpeta Dependencies. Ninguno
2. Abrir Seleccionar la opción Add Dependency... del menú. Ninguno
3. Llenar Introducir coordenadas Maven oficiales del driver de MySQL. Group ID: com.mysql
Artifact ID: mysql-connector-j
Version: 8.3.0
4. Finalizar Clic en Add para descargar e indexar automáticamente. Ninguno
Dependencias

Método B: Configuración Manual (.JAR)

Paso Acción en NetBeans / Sistema Detalle
1. Descargar Entrar al portal de MySQL y bajar el conector. Elegir Platform Independent y descomprimir el zip para obtener el archivo mysql-connector-j-8.x.x.jar.
2. Ubicar Ir al panel Projects y expandir el árbol de carpetas. Clic derecho sobre la carpeta Libraries (Bibliotecas).
3. Agregar Seleccionar la opción Add JAR/Folder... Se abrirá un explorador de archivos integrado del IDE.
4. Vincular Buscar y seleccionar el archivo .jar extraído. Clic en Abrir/Aceptar para enlazar la librería permanentemente.
Vinculación de Librerías y Dependencias en NetBeans

Tus Notas de Desarrollo

Escribe apuntes, errores detectados o recordatorios durante tu práctica.

© Copyright EduCer, Dr. Niels Henryk Aranda Cuevas. Todos los derechos reservados.