Commit ef715f8f authored by Miguel Reboiro-Jato's avatar Miguel Reboiro-Jato

Updates to Java 21 and 26/27 course

parent b823641e
......@@ -8,4 +8,4 @@ target
#General
bak
bin
# Kata 3: JDBC
En esta Kata utilizaremos JDBC para trabajar con una base de datos, partiendo del siguiente proyecto base: https://sing-group.org/dt/gitlab/dai-2324/kata3-base
En esta Kata utilizaremos JDBC para trabajar con una base de datos, partiendo del siguiente proyecto base: https://sing-group.org/dt/gitlab/dai-2627/kata3-base
Este proyecto contiene un sistema funcional para la gestión de datos de usuarios. El único problema de este sistema es que el almacenamiento de datos realizado por la clase `EmployeesMapDAO` se realiza en memoria, con lo que el sistema no resulta realmente útil.
......@@ -14,8 +14,9 @@ Aunque al principio del Kata se explicará brevemente la estructura del programa
2. Cuando se haya completado la Kata se probará contra dos bases de datos:
* **JavaDB** / **Derby**: es un SGBD ligero y embebible, diseñado, principalmente, para pruebas. En el proyecto tendrás una base de datos Derby en el directorio `db` y las consultas de creación de las tablas en `sql/employees.javadb.sql`. En principio, no debería ser necesario que las ejecutes manualmente, puesto que la tabla ya debería estar creada en la base de datos.
* **H2**: es un SGBD ligero y embebible, diseñado, principalmente, para pruebas. En el proyecto tendrás una base de datos H2 en el directorio `db` y las consultas de creación de las tablas en `sql/employees.h2.sql`.
* **MySQL**: en el fichero `sql/employees.mysql.sql` están las consultas necesarias para crear las base de datos. La base de datos se llamará `employees` y debe tener acceso a ella el usuario `kata3` con password `kata3`.
* En ambos casos, `Launcher` se encargará de crear la base de datos y la tabla necesarios si no existen. En el caso de MySQL sí que tendrás que crear un usuario `kata3` con password `kata3` y permisos de acceso y manipulación a la base de datos `employees`.
# *************************************************************************
# *** DO NOT TOUCH FILES IN THIS DIRECTORY! ***
# *** FILES IN THIS DIRECTORY AND SUBDIRECTORIES CONSTITUTE A DERBY ***
# *** DATABASE, WHICH INCLUDES THE DATA (USER AND SYSTEM) AND THE ***
# *** FILES NECESSARY FOR DATABASE RECOVERY. ***
# *** EDITING, ADDING, OR DELETING ANY OF THESE FILES MAY CAUSE DATA ***
# *** CORRUPTION AND LEAVE THE DATABASE IN A NON-RECOVERABLE STATE. ***
# *************************************************************************
\ No newline at end of file
# *************************************************************************
# *** DO NOT TOUCH FILES IN THIS DIRECTORY! ***
# *** FILES IN THIS DIRECTORY ARE USED BY THE DERBY DATABASE RECOVERY ***
# *** SYSTEM. EDITING, ADDING, OR DELETING FILES IN THIS DIRECTORY ***
# *** WILL CAUSE THE DERBY RECOVERY SYSTEM TO FAIL, LEADING TO ***
# *** NON-RECOVERABLE CORRUPT DATABASES. ***
# *************************************************************************
\ No newline at end of file
# *************************************************************************
# *** DO NOT TOUCH FILES IN THIS DIRECTORY! ***
# *** FILES IN THIS DIRECTORY ARE USED BY THE DERBY DATABASE TO STORE ***
# *** USER AND SYSTEM DATA. EDITING, ADDING, OR DELETING FILES IN THIS ***
# *** DIRECTORY WILL CORRUPT THE ASSOCIATED DERBY DATABASE AND MAKE ***
# *** IT NON-RECOVERABLE. ***
# *************************************************************************
\ No newline at end of file
#/home/michi/git/dai-katas/Kata3/db/employees
# ********************************************************************
# *** Please do NOT edit this file. ***
# *** CHANGING THE CONTENT OF THIS FILE MAY CAUSE DATA CORRUPTION. ***
# ********************************************************************
#Tue Oct 03 13:15:58 CEST 2023
SysconglomeratesIdentifier=32
SyscolumnsIdentifier=144
derby.serviceLocale=en_US
SystablesIdentifier=96
SysconglomeratesIndex3Identifier=81
derby.storage.propertiesId=16
derby.serviceProtocol=org.apache.derby.database.Database
SyscolumnsIndex1Identifier=161
SysschemasIndex2Identifier=225
SystablesIndex2Identifier=129
SyscolumnsIndex2Identifier=177
SysconglomeratesIndex2Identifier=65
SysschemasIndex1Identifier=209
SysschemasIdentifier=192
SystablesIndex1Identifier=113
SysconglomeratesIndex1Identifier=49
#--- last line, don't put anything after this line ---
......@@ -32,14 +32,14 @@
</licenses>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Dependencies versions -->
<mysql-connector-j.version>8.1.0</mysql-connector-j.version>
<derby.version>10.15.2.0</derby.version>
<mysql-connector-j.version>9.7.0</mysql-connector-j.version>
<h2.version>2.5.252</h2.version>
<!-- Plugin versions -->
<license-maven-plugin.version>2.2.0</license-maven-plugin.version>
......@@ -74,9 +74,9 @@
<version>${mysql-connector-j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>${derby.version}</version>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
</dependencies>
......
CREATE SCHEMA IF NOT EXISTS KATA3;
CREATE TABLE IF NOT EXISTS Employees (
id INTEGER AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
surname VARCHAR(100) NOT NULL,
birth DATE NOT NULL,
salary INTEGER NOT NULL,
intern BOOLEAN NOT NULL,
PRIMARY KEY (id)
);
\ No newline at end of file
DROP TABLE Employees;
CREATE TABLE Employees (
id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
name VARCHAR(100) NOT NULL,
surname VARCHAR(100) NOT NULL,
birth DATE NOT NULL,
salary INTEGER NOT NULL,
intern BOOLEAN NOT NULL,
PRIMARY KEY (id)
);
CREATE DATABASE IF NOT EXISTS `employees`;
USE `employees`;
DROP TABLE IF EXISTS Employees;
CREATE TABLE `employees`.`Employees` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(100) NULL ,
`surname` VARCHAR(100) NULL ,
`birth` DATE NULL ,
`salary` INT NULL ,
`intern` BIT NULL ,
CREATE TABLE IF NOT EXISTS `employees`.`Employees` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100),
`surname` VARCHAR(100),
`birth` DATE,
`salary` INT,
`intern` BIT,
PRIMARY KEY (`id`)
);
......@@ -2,7 +2,7 @@
* #%L
* DAI Dojo - Código base Kata 3
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* Copyright (C) 2014 - 2026 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
......
......@@ -2,7 +2,7 @@
* #%L
* DAI Dojo - Código base Kata 3
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* Copyright (C) 2014 - 2026 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
......@@ -21,8 +21,14 @@
*/
package es.uvigo.esei.dai.kata3;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.swing.JFrame;
......@@ -37,12 +43,16 @@ import es.uvigo.esei.dai.kata3.model.dao.EmployeesMapDAO;
import es.uvigo.esei.dai.kata3.view.EmployeesPanel;
public class Launch {
public static void main(String[] args) throws SQLException {
// Una vez completado el ejercicio cambiar el DAO creado
final EmployeesDAO dao = new EmployeesMapDAO();
// final EmployeesDAO dao = createEmployeesJavaDBDAO(false);
// final EmployeesDAO dao = createEmployeesMySQLDBDAO();
private final static Path SQL_PATH = Path.of("sql");
public static void main(String[] args) throws SQLException, IOException {
// Una vez completado el ejercicio cambiar la conexión y el DAO creados.
final Connection connection = null;
// final Connection connection = createH2Connection();
// final Connection connection = createMySQLConnection();
final EmployeesDAO dao = new EmployeesMapDAO();
// final EmployeesDAO dao = new EmployeesDBDAO(connection);
final EmployeesController controller = new DefaultEmployeesController(dao);
SwingUtilities.invokeLater(() -> {
......@@ -55,44 +65,49 @@ public class Launch {
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
// JDBC connection is closed when the window is closed.
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
if (connection != null) {
try {
connection.close();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
});
});
}
/* Una vez completado el ejercicio descomentar este bloque de código.
private final static EmployeesDAO createEmployeesJavaDBDAO(boolean createDatabase) throws SQLException {
final Connection connection;
private final static Connection createH2Connection() throws SQLException, IOException {
final Connection connection = DriverManager.getConnection("jdbc:h2:./db/employees;DB_CLOSE_DELAY=-1", "kata3",
"kata3");
// La base de datos ya debería estar creada
if (createDatabase) {
connection = DriverManager.getConnection("jdbc:derby:db/employees;create=true", "kata3", "kata3");
createJavaDBDatabase(connection);
} else {
connection = DriverManager.getConnection("jdbc:derby:db/employees", "kata3", "kata3");
}
final String sql = Files.readString(SQL_PATH.resolve("employees.h2.sql"));
return new EmployeesDBDAO(connection);
try (PreparedStatement statement = connection.prepareStatement(sql)) {
statement.execute();
}
private final static void createJavaDBDatabase(Connection connection) throws SQLException {
connection.createStatement().execute("CREATE SCHEMA KATA3");
connection.createStatement().execute(
"CREATE TABLE Employees "
+ "(id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), "
+ "name VARCHAR(100) NOT NULL, "
+ "surname VARCHAR(100) NOT NULL, "
+ "birth DATE NOT NULL, "
+ "salary INTEGER NOT NULL, "
+ "intern BOOLEAN NOT NULL, PRIMARY KEY (id)"
+ ")"
);
return connection;
}
private final static EmployeesDAO createEmployeesMySQLDBDAO() throws SQLException {
final Connection connection = DriverManager
.getConnection("jdbc:mysql://localhost:3306/employees", "kata3", "kata3");
private final static Connection createMySQLConnection() throws SQLException, IOException {
final Connection connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/employees?allowMultiQueries=true", "kata3",
"kata3");
final String sql = Files.readString(SQL_PATH.resolve("employees.mysql.sql"));
return new EmployeesDBDAO(connection);
}*/
try (PreparedStatement statement = connection.prepareStatement(sql)) {
statement.execute();
}
return connection;
}
private static void changeLookAndFeelToNimbus() {
try {
......
......@@ -2,7 +2,7 @@
* #%L
* DAI Dojo - Código base Kata 3
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* Copyright (C) 2014 - 2026 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
......
......@@ -2,7 +2,7 @@
* #%L
* DAI Dojo - Código base Kata 3
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* Copyright (C) 2014 - 2026 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
......
......@@ -2,7 +2,7 @@
* #%L
* DAI Dojo - Código base Kata 3
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* Copyright (C) 2014 - 2026 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
......
......@@ -2,7 +2,7 @@
* #%L
* DAI Dojo - Código base Kata 3
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* Copyright (C) 2014 - 2026 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
......
......@@ -2,7 +2,7 @@
* #%L
* DAI Dojo - Código base Kata 3
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* Copyright (C) 2014 - 2026 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
......@@ -21,9 +21,9 @@
*/
package es.uvigo.esei.dai.kata3.model.dao;
import java.time.LocalDate;
import java.time.Month;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
......@@ -40,13 +40,9 @@ public class EmployeesMapDAO implements EmployeesDAO {
public EmployeesMapDAO() {
this.employees = new HashMap<>();
final Calendar calendar = GregorianCalendar.getInstance();
this.idGenerator = 1;
calendar.set(1980, Calendar.FEBRUARY, 10);
this.create(new Employee("Manuel", "Martínez", calendar.getTime(), 10000, false));
calendar.set(1975, Calendar.MARCH, 21);
this.create(new Employee("María", "Muñíz", calendar.getTime(), 12000, true));
this.create(new Employee("Manuel", "Martínez", LocalDate.of(2000, Month.FEBRUARY, 10), 25000, true));
this.create(new Employee("María", "Muñíz", LocalDate.of(1975, Month.MARCH, 21), 52000, false));
}
......
......@@ -2,7 +2,7 @@
* #%L
* DAI Dojo - Código base Kata 3
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* Copyright (C) 2014 - 2026 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
......@@ -22,7 +22,7 @@
package es.uvigo.esei.dai.kata3.model.entity;
import java.io.Serializable;
import java.util.Date;
import java.time.LocalDate;
import java.util.Objects;
public class Employee implements Serializable {
......@@ -32,13 +32,13 @@ public class Employee implements Serializable {
private String name;
private String surname;
private int salary;
private Date birth;
private LocalDate birth;
private boolean intern;
public Employee() {
}
public Employee(String name, String surname, Date birth, int salary, boolean intern) {
public Employee(String name, String surname, LocalDate birth, int salary, boolean intern) {
this.name = name;
this.surname = surname;
this.salary = salary;
......@@ -46,7 +46,7 @@ public class Employee implements Serializable {
this.intern = intern;
}
public Employee(Integer id, String name, String surname, Date birth, int salary, boolean intern) {
public Employee(Integer id, String name, String surname, LocalDate birth, int salary, boolean intern) {
this.id = id;
this.name = name;
this.surname = surname;
......@@ -87,11 +87,11 @@ public class Employee implements Serializable {
this.salary = salary;
}
public Date getBirth() {
public LocalDate getBirth() {
return birth;
}
public void setBirth(Date birth) {
public void setBirth(LocalDate birth) {
this.birth = birth;
}
......
......@@ -2,7 +2,7 @@
* #%L
* DAI Dojo - Código base Kata 3
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* Copyright (C) 2014 - 2026 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
......@@ -30,7 +30,8 @@ import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import javax.swing.AbstractAction;
import javax.swing.JButton;
......@@ -79,7 +80,7 @@ public class EmployeesDataPanel extends JPanel {
this.txtName.setPreferredSize(new Dimension(200, (int) this.txtName.getPreferredSize().getHeight()));
this.txtSurname = new JTextField();
this.ftxtSalary = new JFormattedTextField(NumberFormat.getIntegerInstance());
this.ftxtBirth = new JFormattedTextField(new SimpleDateFormat("dd/MM/yyyy"));
this.ftxtBirth = new JFormattedTextField(DateTimeFormatter.ofPattern("dd/MM/uuuu").toFormat(LocalDate::from));
this.chkIntern = new JCheckBox();
final String[] labels = new String[] { "Name", "Surname", "Salary", "Birth", "Is intern?" };
......@@ -132,7 +133,7 @@ public class EmployeesDataPanel extends JPanel {
this.employee.setName(this.txtName.getText());
this.employee.setSurname(this.txtSurname.getText());
this.employee.setSalary(((Number) this.ftxtSalary.getValue()).intValue());
this.employee.setBirth((Date) this.ftxtBirth.getValue());
this.employee.setBirth((LocalDate) this.ftxtBirth.getValue());
this.employee.setIntern(this.chkIntern.isSelected());
return this.employee;
......
......@@ -2,7 +2,7 @@
* #%L
* DAI Dojo - Código base Kata 3
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* Copyright (C) 2014 - 2026 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
......
......@@ -2,7 +2,7 @@
* #%L
* DAI Dojo - Código base Kata 3
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* Copyright (C) 2014 - 2026 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
......@@ -37,7 +37,6 @@ import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import es.uvigo.esei.dai.kata3.SearchType;
......@@ -96,15 +95,12 @@ public class EmployeesPanel extends JPanel {
this.tableEmployees.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.tableEmployees.setRowSelectionAllowed(true);
this.tableEmployees.setColumnSelectionAllowed(false);
this.tableEmployees.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
this.tableEmployees.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
final int index = EmployeesPanel.this.tableEmployees.getSelectedRow();
if (index >= 0) {
EmployeesPanel.this.mediator.editEmployee(model.getEmployee(index));
}
}
});
this.mediator.setTable(this.tableEmployees);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment