Requisitos
1. Java Development Kit (JDK) v1.6
2. MySQL Server 5 o superior
3. IDE de desarrollo, con el que se prefiera trabajar (Netbeans, Eclipse, IntelliJ)
4. MySQL GUI Tools (Descarga para Windows)
5. Conector JDBC para MySQL (Link de Descarga)
Modelo Simple de Datos Relacional
Vamos a partir del siguiente modelo de datos relacional que está conformado por 2 tablas. Una tabla empleado y su relación con una tabla departamento.
En la figura se muestra que un empleado pertenecerá a un departamento.
Creación de la base de datos
Usando la herramienta MySQL Administrator nos conectamos al servidor de base de datos MySQL que se usará. En mi caso MySQL está instalado en la misma máquina (localhost)
Una vez que estemos dentro de la aplicación, vamos a Tools > MySQL Query Browser para ejecutar las siguientes sentencias SQL:
#Usar la base de datos mysql USE mysql; #Crear la base de datos TEST para realizar el ejemplo CREATE DATABASE test DEFAULT CHARACTER SET utf8; #Usar la base de datos test USE test; #Crear un usuario para conectarse a la base de datos TEST CREATE USER 'usuario'@'%' IDENTIFIED BY 'prueba'; #Dar los permisos CRUD al usuario GRANT SELECT,INSERT,UPDATE,DELETE ON *.* TO 'usuario'@'%';
Luego procedemos a crear la estructura de datos física definida en el modelo, a través de las siguientes sentencias SQL:
#Crear la tabla departamento CREATE TABLE departamento ( id INT NOT NULL AUTO_INCREMENT, nombre VARCHAR(64) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB; #Crear la tabla empleado CREATE TABLE empleado ( id INT NOT NULL AUTO_INCREMENT, nombre VARCHAR(64) NOT NULL, sueldo DECIMAL(8,2) NOT NULL, departamentoid INT NOT NULL, PRIMARY KEY (id), FOREIGN KEY (departamentoid) REFERENCES departamento(id) ON DELETE CASCADE ) ENGINE=InnoDB;
Por último insertamos los siguiente datos por defecto en las tablas empleado y departamento.
#Insertar departamentos INSERT INTO departamento (nombre) VALUES ('SISTEMAS'); INSERT INTO departamento (nombre) VALUES ('CONTABILIDAD'); INSERT INTO departamento (nombre) VALUES ('VENTAS'); #Insertar empleado Administrador INSERT INTO empleado (nombre, sueldo, departamentoid) values ('Administrador', 1500, 1); COMMIT;
Creación del proyecto
En el IDE de su preferencia creamos un nuevo proyecto Java, con el nombre que deseen en mi caso EjemploSwingTables y creamos los siguientes paquetes de Java:
En el paquete com.blogspot.ingmmurillo.domain crearemos los POJOs para representar las tablas de la base de datos como objetos. En el paquete com.blogspot.ingmmurillo.domain crearemos los modelos (AbstractTableModel y DefaultComboBoxModel) y en el paquete crearemos un formulario para visualizar los datos.
Diseño del Formulario
Usando Swing crearemos el siguiente formulario (JFrame):
En el formulario se cargarán los datos de departamentos extrayendo de la base de datos y se podrá registrar nuevos empleados o eliminarlos. También se podrá visualizar los datos de la base de datos en un componente JTable y se refrescarán conforme se vaya agregando o eliminando empleados.
Clases de Dominio
Estas clases son POJOs y representan la estructura de las tablas en objetos. Se las creará en el paquete com.blogspot.ingmmurillo.domain
package com.blogspot.ingmmurillo.domain; public class Departamento { private int id; private String nombre; public int getId() { return id; } public String getNombre() { return nombre; } public void setId(int id) { this.id = id; } public void setNombre(String nombre) { this.nombre = nombre; } @Override public String toString() { // TODO Auto-generated method stub return nombre; } }
package com.blogspot.ingmmurillo.domain; public class Empleado { private int id; private String nombre; private double sueldo; private Departamento departamento; public int getId() { return id; } public String getNombre() { return nombre; } public double getSueldo() { return sueldo; } public void setId(int id) { this.id = id; } public void setNombre(String nombre) { this.nombre = nombre; } public void setSueldo(double sueldo) { this.sueldo = sueldo; } public Departamento getDepartamento() { return departamento; } public void setDepartamento(Departamento departamento) { this.departamento = departamento; } }
Modelos para el ComboBox y la Tabla
package com.blogspot.ingmmurillo.model; public class ModeloComboBoxDepartamento extends DefaultComboBoxModel { private Vector<Departamento> departamentos; private static final String JDBC_URL = "jdbc:mysql://localhost:3306/test"; private static final String JDBC_USUARIO = "usuario"; private static final String JDBC_CLAVE = "prueba"; public ModeloComboBoxDepartamento() { departamentos = new Vector<Departamento>(); try { refrescarDatos(); } catch (SQLException e) { System.err.println(e); } } public int getSize() { return departamentos.size(); } public Object getElementAt(int index) { return departamentos.get(index); } private void refrescarDatos() throws SQLException { Connection conexion = null; Statement st = null; ResultSet rs = null; try { MysqlDataSource dataSource = new MysqlDataSource(); dataSource.setUrl(JDBC_URL); dataSource.setUser(JDBC_USUARIO); dataSource.setPassword(JDBC_CLAVE); conexion = dataSource.getConnection(); st = conexion.createStatement(); rs = st.executeQuery("select id, nombre from departamento"); while (rs.next()) { Departamento dep = new Departamento(); dep.setId(rs.getInt("id")); dep.setNombre(rs.getString("nombre")); departamentos.add(dep); } } catch (SQLException e) { System.err.println(e); } finally { if (rs != null) { rs.close(); } if (st != null) { st.close(); } if (conexion != null) { conexion.close(); } } } }
package com.blogspot.ingmmurillo.model; public class ModeloTablaEmpleados extends AbstractTableModel { private Vector<String> columnas; private Vector<Empleado> filas; private static final String JDBC_URL = "jdbc:mysql://localhost:3306/test"; private static final String JDBC_USUARIO = "usuario"; private static final String JDBC_CLAVE = "prueba"; public ModeloTablaEmpleados(Vector<String> columnas) { this.columnas = columnas; filas = new Vector<Empleado>(); try { refrescarDatos(); } catch (SQLException e) { System.err.println(e); } } public int getRowCount() { return filas.size(); } public int getColumnCount() { return columnas.size(); } public Object getValueAt(int rowIndex, int columnIndex) { Empleado emp = filas.get(rowIndex); switch (columnIndex) { case 0: return emp.getId(); case 1: return emp.getNombre(); case 2: return emp.getSueldo(); case 3: return emp.getDepartamento().getNombre(); } return emp; } public String getColumnName(int column) { return columnas.get(column); } public void agregarEmpleado(Empleado emp) { try { insertarEmpleadoBDD(emp); refrescarDatos(); } catch (SQLException e) { System.err.println(e); } } public void eliminarEmpleado(int rowIndex) { try { Empleado emp = filas.get(rowIndex); eliminarEmpleadoBDD(emp); refrescarDatos(); } catch (SQLException e) { System.err.println(e); } } private void refrescarDatos() throws SQLException { Connection conexion = null; Statement st = null; ResultSet rs = null; try { MysqlDataSource dataSource = new MysqlDataSource(); dataSource.setUrl(JDBC_URL); dataSource.setUser(JDBC_USUARIO); dataSource.setPassword(JDBC_CLAVE); conexion = dataSource.getConnection(); st = conexion.createStatement(); rs = st.executeQuery("select e.id as id, e.nombre as nombre, e.sueldo as sueldo, e.departamentoid as depid, d.nombre as departamento from empleado e, departamento d where e.departamentoid = d.id"); filas.clear(); while (rs.next()) { Empleado emp = new Empleado(); emp.setId(rs.getInt("id")); emp.setNombre(rs.getString("nombre")); emp.setSueldo(rs.getDouble("sueldo")); Departamento dep = new Departamento(); dep.setId(rs.getInt("depid")); dep.setNombre(rs.getString("departamento")); emp.setDepartamento(dep); filas.add(emp); } fireTableDataChanged(); } catch (SQLException e) { System.err.println(e); } finally { if (rs != null) { rs.close(); } if (st != null) { st.close(); } if (conexion != null) { conexion.close(); } } } private void insertarEmpleadoBDD(Empleado emp) throws SQLException { Connection conexion = null; PreparedStatement st = null; try { MysqlDataSource dataSource = new MysqlDataSource(); dataSource.setUrl(JDBC_URL); dataSource.setUser(JDBC_USUARIO); dataSource.setPassword(JDBC_CLAVE); conexion = dataSource.getConnection(); st = conexion .prepareStatement("INSERT INTO empleado (nombre, sueldo, departamentoid) values (?, ?, ?)"); st.setString(1, emp.getNombre()); st.setDouble(2, emp.getSueldo()); st.setInt(3, emp.getDepartamento().getId()); st.executeUpdate(); fireTableDataChanged(); } catch (SQLException e) { System.err.println(e); } finally { if (st != null) { st.close(); } if (conexion != null) { conexion.close(); } } } private void eliminarEmpleadoBDD(Empleado emp) throws SQLException { Connection conexion = null; PreparedStatement st = null; try { MysqlDataSource dataSource = new MysqlDataSource(); dataSource.setUrl(JDBC_URL); dataSource.setUser(JDBC_USUARIO); dataSource.setPassword(JDBC_CLAVE); conexion = dataSource.getConnection(); st = conexion.prepareStatement("DELETE FROM empleado WHERE id = ?"); st.setInt(1, emp.getId()); st.executeUpdate(); fireTableDataChanged(); } catch (SQLException e) { System.err.println(e); } finally { if (st != null) { st.close(); } if (conexion != null) { conexion.close(); } } } }
Clase de Presentación
package com.blogspot.ingmmurillo.view; public class FrameEmpleado extends JFrame { private JLabel etiquetaNombre; private JLabel etiquetaSueldo; private JLabel etiquetaDepartamento; private JTextField campoTextoNombre; private JTextField campoTextoSueldo; private JComboBox comboBoxDepartamento; private JButton botonAgregar; private JButton botonEliminar; private JScrollPane panelDatosEmpleado; private JTable tablaDatosEmpleado; private ModeloComboBoxDepartamento modeloComboboxDeps; private ModeloTablaEmpleados modeloTablaEmps; public FrameEmpleado() { init(); } public static void main(String[] args) { FrameEmpleado frame = new FrameEmpleado(); frame.setVisible(true); } public void init() { // Titulo de la pantalla setTitle("Empleado"); // Dimensiones de la pantalla setSize(430, 500); // Operacion de cerrar setDefaultCloseOperation(EXIT_ON_CLOSE); // Centrar el frame en el centro de pantalla setLocationRelativeTo(null); // Asignar el Layout a null para posicionar el formulario en el centro // de la pantalla setLayout(null); setResizable(false); // Creacion de los controles etiquetaNombre = new JLabel("Nombre : "); etiquetaNombre.setLocation(10, 10); etiquetaNombre.setSize(100, 20); etiquetaSueldo = new JLabel("Sueldo :"); etiquetaSueldo.setLocation(10, 50); etiquetaSueldo.setSize(100, 20); etiquetaDepartamento = new JLabel("Departamento :"); etiquetaDepartamento.setLocation(10, 90); etiquetaDepartamento.setSize(100, 20); campoTextoNombre = new JTextField(); campoTextoNombre.setLocation(120, 10); campoTextoNombre.setSize(120, 20); campoTextoSueldo = new JTextField(); campoTextoSueldo.setLocation(120, 50); campoTextoSueldo.setSize(120, 20); modeloComboboxDeps = new ModeloComboBoxDepartamento(); comboBoxDepartamento = new JComboBox(modeloComboboxDeps); comboBoxDepartamento.setLocation(120, 90); comboBoxDepartamento.setSize(120, 20); botonAgregar = new JButton("Agregar"); botonAgregar.setLocation(320, 10); botonAgregar.setSize(80, 20); botonEliminar = new JButton("Eliminar"); botonEliminar.setLocation(320, 50); botonEliminar.setSize(80, 20); Vector<String> columnasTablaEmpleado = new Vector<String>(); columnasTablaEmpleado.add("ID"); columnasTablaEmpleado.add("NOMBRE"); columnasTablaEmpleado.add("SUELDO"); columnasTablaEmpleado.add("DEPARTAMENTO"); modeloTablaEmps = new ModeloTablaEmpleados(columnasTablaEmpleado); tablaDatosEmpleado = new JTable(modeloTablaEmps); panelDatosEmpleado = new JScrollPane(tablaDatosEmpleado); panelDatosEmpleado.setLocation(10, 140); panelDatosEmpleado.setSize(400, 300); // Agregación de los controles al frame add(etiquetaNombre); add(etiquetaSueldo); add(etiquetaDepartamento); add(campoTextoNombre); add(campoTextoSueldo); add(comboBoxDepartamento); add(botonAgregar); add(botonEliminar); add(panelDatosEmpleado); // Eventos de los botones botonAgregar.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub Empleado emp = new Empleado(); emp.setNombre(campoTextoNombre.getText()); emp.setSueldo(Double.valueOf(campoTextoSueldo.getText())); Departamento dep = (Departamento) comboBoxDepartamento .getSelectedItem(); emp.setDepartamento(dep); modeloTablaEmps.agregarEmpleado(emp); } }); botonEliminar.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub modeloTablaEmps.eliminarEmpleado(tablaDatosEmpleado .getSelectedRow()); } }); } }
Aplicación Final
Recomendaciones
En ésta publicación he expuesto el código para usar los modelos de datos para los ComboBox en un JComboBox y para una tabla en una JTable. Cabe destacar que la lógica de conexión a la base de datos que se hace en los 2 modelos no debería estar ahí. En una aplicación real, es importante definir una clase que se encargue de manejar las conexiones a la base de datos y ejecutar las instrucciones SQL; o también se podría usar un ORM como Hibernate.
Ordenado, Didactico y muy Pedagogico.
ResponderEliminarExcelente documento Mauricio.Es de gran ayuda para mi ya que me estoy iniciando en el Desarrollo de Sistemas de Información utilizando el lenguaje de programación Java -Saludos-
Bastante bueno, he implementado los metodos y hasta ahora todo bien, pero al correr la aplicación y tratar de insertar en la base de datos me da el siguiente error:
ResponderEliminarCannot add or update a child row: a foreign key constraint fails (`qxclinica/usuarios`, CONSTRAINT `fk_Usuarios_Perfiles` FOREIGN KEY (`idPerfiles`) REFERENCES `perfiles` (`idPerfiles`) ON DELETE CASCADE)
Me podria ayudar, yasmany003@gmail.com
El ejemplo es bastante claro, y explicativo. Lo estoy implementando en una aplicación pero al tratar de insertar me tira la siguiente excepción.
ResponderEliminarCannot add or update a child row: a foreign key constraint fails (`qxclinica/usuarios`, CONSTRAINT `fk_Usuarios_Perfiles` FOREIGN KEY (`idPerfiles`) REFERENCES `perfiles` (`idPerfiles`) ON DELETE CASCADE).
Por que esto?
Estoy empezando a ver esto, pero creo que no funcionan los insert (todavía no lo probé) porque faltaría el setValueAt, pero no estoy seguro.
ResponderEliminartengo problemas con
ResponderEliminarMysqlDataSource dataSource = new MysqlDataSource();
agradeceria ayuda, no deja importar ni nada
Hola espero y me puedas ayudar lo que pasa esque realise uns vista en mysql el cual me arroja un dato de tipo decimal y en java no se que tipo de datos poner en mi beans para que me arroje mi consulta en el dao
ResponderEliminarSaludos, y agradecer el ejemplo, por necesidad en estso tiempos he tenido que hacer algo en Swing y me ha servido de guia, a continuación expongo como hacer invisible una columna del JTable y como recuperar en este caso el id del modelo.
ResponderEliminarQuitar la columna de Id:
tablaDatosEmpleado.removeColumn(tablaDatosEmpleado.getColumnModel().getColumn(EMPLEADO_ID);
Recuperar el Id:
Integer.parseInt(tablaDatosEmpleado.getModel().getValueAt(tablaDatosEmpleado.getSelectedRow(), EMPLEADO_ID).toString());