From d1fab1ab536e93c3a036a93b2cf84013c039dc30 Mon Sep 17 00:00:00 2001 From: Trebellar Date: Tue, 24 Feb 2026 17:48:00 +0100 Subject: [PATCH] Inicio --- .gitignore | 55 +++ .vscode/settings.json | 3 + README.md | 11 + pom.xml | 57 +++ .../com/example/hibernate/AccountWindow.java | 409 ++++++++++++++++++ .../hibernate/CreateUpdateAccountDialog.java | 133 ++++++ .../com/example/hibernate/model/dao/README.md | 1 + .../model/servicio/AccountServicio.java | 50 +++ .../model/servicio/EmpleadoServicio.java | 28 ++ .../model/servicio/IAccountServicio.java | 20 + .../model/servicio/IEmpleadoServicio.java | 10 + .../model/util/GenericDaoHibernate.java | 89 ++++ .../hibernate/model/util/IGenericDao.java | 67 +++ .../model/util/OperacionHibernate.java | 6 + .../model/util/TransactionManager.java | 28 ++ .../exceptions/InstanceNotFoundException.java | 35 ++ .../example/hibernate/util/HibernateUtil.java | 66 +++ src/main/resources/hibernate.properties | 17 + .../scripts/mariadb/1_scripts_empresa.sql | 131 ++++++ .../scripts/mariadb/2_create_user.sql | 3 + 20 files changed, 1219 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/com/example/hibernate/AccountWindow.java create mode 100644 src/main/java/com/example/hibernate/CreateUpdateAccountDialog.java create mode 100644 src/main/java/com/example/hibernate/model/dao/README.md create mode 100644 src/main/java/com/example/hibernate/model/servicio/AccountServicio.java create mode 100644 src/main/java/com/example/hibernate/model/servicio/EmpleadoServicio.java create mode 100644 src/main/java/com/example/hibernate/model/servicio/IAccountServicio.java create mode 100644 src/main/java/com/example/hibernate/model/servicio/IEmpleadoServicio.java create mode 100644 src/main/java/com/example/hibernate/model/util/GenericDaoHibernate.java create mode 100644 src/main/java/com/example/hibernate/model/util/IGenericDao.java create mode 100644 src/main/java/com/example/hibernate/model/util/OperacionHibernate.java create mode 100644 src/main/java/com/example/hibernate/model/util/TransactionManager.java create mode 100644 src/main/java/com/example/hibernate/model/util/exceptions/InstanceNotFoundException.java create mode 100644 src/main/java/com/example/hibernate/util/HibernateUtil.java create mode 100644 src/main/resources/hibernate.properties create mode 100644 src/main/resources/scripts/mariadb/1_scripts_empresa.sql create mode 100644 src/main/resources/scripts/mariadb/2_create_user.sql diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff811dd --- /dev/null +++ b/.gitignore @@ -0,0 +1,55 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +# https://github.com/takari/maven-wrapper#usage-without-binary-jar +.mvn/wrapper/maven-wrapper.jar + +# Eclipse m2e generated files +# Eclipse Core +.project +# JDT-specific (Eclipse Java Development Tools) +.classpath diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c5f3f6b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..70e7682 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Respostas ás preguntas da Tarefa03.1 + +2- Axudándote do plugin de Maven de Hibernate Tools, +xenera as clases a partir da BD empresa no paquete com.example.hibernate.model. +Indica no arquivo README.md na raíz do proxecto o comando que utilizaches (0,1 puntos). + +O comando e: +mvn clean generate-sources + +En el pom.xml +com.example.hibernate.model \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..1a25e3d --- /dev/null +++ b/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + com.example.hibernate + tarea03-1 + 1.0-SNAPSHOT + + + 21 + 21 + + + + + + org.hibernate.tool + hibernate-tools-maven + 6.6.0.Final + + + org.hibernate.tool + hibernate-tools-orm + 6.6.0.Final + + + com.mysql + mysql-connector-j + 9.1.0 + + + + + entity-generation + generate-sources + + hbm2java + + + true + true + com.example.hibernate.model + + src/main/java + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/AccountWindow.java b/src/main/java/com/example/hibernate/AccountWindow.java new file mode 100644 index 0000000..abf62cb --- /dev/null +++ b/src/main/java/com/example/hibernate/AccountWindow.java @@ -0,0 +1,409 @@ +package com.example.hibernate; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.math.BigDecimal; +import java.util.List; + +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; +import javax.swing.border.EmptyBorder; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import org.hibernate.SessionFactory; + +import com.example.hibernate.model.AccMovement; +import com.example.hibernate.model.Account; +import com.example.hibernate.model.Emp; +import com.example.hibernate.model.dao.AccMovementDaoHibernate; +import com.example.hibernate.model.dao.AccountDaoHibernate; +import com.example.hibernate.model.dao.EmpleadoDaoHibernate; +import com.example.hibernate.model.dao.IAccMovementDao; +import com.example.hibernate.model.dao.IAccountDao; +import com.example.hibernate.model.dao.IEmpleadoDao; +import com.example.hibernate.model.servicio.AccountServicio; +import com.example.hibernate.model.servicio.EmpleadoServicio; +import com.example.hibernate.model.servicio.IAccountServicio; +import com.example.hibernate.model.servicio.IEmpleadoServicio; +import com.example.hibernate.model.util.TransactionManager; +import com.example.hibernate.util.HibernateUtil; + + +public class AccountWindow extends JFrame { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private JPanel contentPane; + + private JTextArea mensajes_text_Area; + private JList JListAllAccounts; + + private IEmpleadoServicio empleadoServicio; + private IAccountServicio accountServicio; + + private CreateUpdateAccountDialog createDialog; + private JButton btnModificarImporteCuenta; + private JButton btnEliminarCuenta; + private JTextField JtextFieldEmpno; + private JLabel lblEmpno; + + private Emp empleado = null; + + /** + * Launch the application. + */ + public static void main(String[] args) { + EventQueue.invokeLater(new Runnable() { + public void run() { + try { + AccountWindow frame = new AccountWindow(); + frame.setVisible(true); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + /** + * Create the frame. + */ + public AccountWindow() { + SessionFactory sessionFactory = HibernateUtil.getInstance().getSessionFactory(); + + TransactionManager transactionManager = new TransactionManager(sessionFactory); + IEmpleadoDao empleadoDao = new EmpleadoDaoHibernate(sessionFactory); + IAccountDao accountDao = new AccountDaoHibernate(sessionFactory); + IAccMovementDao accMovementDao = new AccMovementDaoHibernate(sessionFactory); + empleadoServicio = new EmpleadoServicio(empleadoDao, transactionManager); + accountServicio = new AccountServicio( accMovementDao, accountDao, transactionManager); + + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setBounds(100, 100, 847, 772); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + + setContentPane(contentPane); + contentPane.setLayout(null); + + JPanel panel = new JPanel(); + panel.setBounds(8, 8, 821, 707); + contentPane.add(panel); + panel.setLayout(null); + + JScrollPane scrollPane = new JScrollPane(); + scrollPane.setBounds(19, 450, 669, 228); + panel.add(scrollPane); + + mensajes_text_Area = new JTextArea(); + scrollPane.setViewportView(mensajes_text_Area); + mensajes_text_Area.setEditable(false); + mensajes_text_Area.setText("Panel de mensajes"); + mensajes_text_Area.setForeground(new Color(255, 0, 0)); + mensajes_text_Area.setFont(new Font("Monospaced", Font.PLAIN, 13)); + + JButton btnShowAllAccounts = new JButton("Mostrar cuentas"); + + btnShowAllAccounts.setFont(new Font("Tahoma", Font.PLAIN, 14)); + btnShowAllAccounts.setBounds(38, 132, 208, 36); + panel.add(btnShowAllAccounts); + + JScrollPane scrollPanel_in_JlistAllAccounts = new JScrollPane(); + panel.add(scrollPanel_in_JlistAllAccounts); + + btnModificarImporteCuenta = new JButton("Modificar importe cuenta"); + + JListAllAccounts = new JList(); + + JListAllAccounts.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + panel.add(JListAllAccounts); + JListAllAccounts.setBounds(403, 37, 377, 362); + + JButton btnCrearNuevaAccount = new JButton("Crear nueva cuenta"); + + btnCrearNuevaAccount.setFont(new Font("Tahoma", Font.PLAIN, 14)); + btnCrearNuevaAccount.setBounds(38, 201, 208, 36); + panel.add(btnCrearNuevaAccount); + + btnModificarImporteCuenta.setEnabled(false); + btnModificarImporteCuenta.setFont(new Font("Tahoma", Font.PLAIN, 14)); + btnModificarImporteCuenta.setBounds(38, 266, 208, 36); + panel.add(btnModificarImporteCuenta); + + btnEliminarCuenta = new JButton("Eliminar cuenta"); + + btnEliminarCuenta.setFont(new Font("Tahoma", Font.PLAIN, 14)); + btnEliminarCuenta.setEnabled(false); + btnEliminarCuenta.setBounds(38, 342, 208, 36); + panel.add(btnEliminarCuenta); + + lblEmpno = new JLabel("Introduzca el nº de empleado"); + lblEmpno.setFont(new Font("Tahoma", Font.PLAIN, 14)); + lblEmpno.setBounds(35, 37, 243, 31); + panel.add(lblEmpno); + + JtextFieldEmpno = new JTextField(); + JtextFieldEmpno.setFont(new Font("Tahoma", Font.PLAIN, 14)); + JtextFieldEmpno.setBounds(38, 77, 136, 36); + panel.add(JtextFieldEmpno); + JtextFieldEmpno.setColumns(10); + JtextFieldEmpno.addKeyListener(null); + + // Eventos + ActionListener showAllAccountsActionListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + getAllAccounts(); + } + }; + btnShowAllAccounts.addActionListener(showAllAccountsActionListener); + + ActionListener crearListener = new ActionListener() { + + public void actionPerformed(ActionEvent e) { + int empno = getEmpnoFromTextField(); + try { + + if (empno != -1) { + Account nuevaAcc = new Account(); + + if ((AccountWindow.this.empleado == null) + || (empno != AccountWindow.this.empleado.getEmpno())) { + + AccountWindow.this.empleado = empleadoServicio.find(empno); + } + // Establezco la relación entre la nueva Account y el empleado + nuevaAcc.setEmp(AccountWindow.this.empleado); + JFrame owner = (JFrame) SwingUtilities.getRoot((Component) e.getSource()); + + createDialog = new CreateUpdateAccountDialog(owner, "Crear nueva cuenta", + Dialog.ModalityType.DOCUMENT_MODAL, nuevaAcc); + showDialog(BigDecimal.ZERO); + } else { + addMensaje(true, "El número de empleado no es correcto"); + } + } catch (Exception ex) { + addMensaje(true, "El empno " + empno + " no se encontró"); + } + } + }; + btnCrearNuevaAccount.addActionListener(crearListener); + + ActionListener modificarListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + int selectedIx = JListAllAccounts.getSelectedIndex(); + if (selectedIx > -1) { + // Estas cuentas ya vienen con un proxy de su empleado y con su empno + Account account = (Account) JListAllAccounts.getModel().getElementAt(selectedIx); + if (account != null) { + + JFrame owner = (JFrame) SwingUtilities.getRoot((Component) e.getSource()); + + createDialog = new CreateUpdateAccountDialog(owner, "Modificar importe cuenta", + Dialog.ModalityType.DOCUMENT_MODAL, account); + + showDialog(account.getAmount()); + } + } + } + }; + + btnModificarImporteCuenta.addActionListener(modificarListener); + + ListSelectionListener selectionListListener = new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + if (e.getValueIsAdjusting() == false) { + int selectedIx = JListAllAccounts.getSelectedIndex(); + btnModificarImporteCuenta.setEnabled((selectedIx > -1)); + btnEliminarCuenta.setEnabled((selectedIx > -1)); + + if (selectedIx > -1) { + Account accountd = (Account) JListAllAccounts.getModel().getElementAt(selectedIx); + if (accountd != null) { + addMensaje(true, "Se ha seleccionado la cuenta con id: " + accountd); + } + } + } + } + }; + JListAllAccounts.addListSelectionListener(selectionListListener); + + ActionListener deleteListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + int selectedIx = JListAllAccounts.getSelectedIndex(); + if (selectedIx > -1) { + Account account = (Account) JListAllAccounts.getModel().getElementAt(selectedIx); + if (account != null) { + try { + accountServicio.delete(account.getAccountno()); + + addMensaje(true, "Se ha eliminado la cuenta con id: " + account.getAccountno()); + getAllAccounts(); + + } catch (Exception ex) { + addMensaje(true, "No se ha podido borrar la cuenta. "); + System.out.println("Exception: " + ex.getMessage()); + ex.printStackTrace(); + } + } + } + } + }; + btnEliminarCuenta.addActionListener(deleteListener); + + KeyAdapter enterKeyAdapter = new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + String textIntroducido = ""; + + int key = e.getKeyCode(); + // Cuando se presiona la tecla enter, intentamos obtener el saldo de la cuenta + if ((key == KeyEvent.VK_ENTER)) { + + textIntroducido = ((JTextField) e.getSource()).getText().trim(); + try { + int accId = Integer.parseInt(textIntroducido); + // Se guarda en un atributo de la clase + AccountWindow.this.empleado = empleadoServicio.find(accId); + + if (empleado != null) { + addMensaje(true, "Se ha encontrado el empleado con id: " + accId); + } + + } catch (NumberFormatException nfe) { + + addMensaje(true, "Introduzca un número entero"); + AccountWindow.this.empleado = null; + + + } catch (Exception ex) { + System.out.println("Ha ocurrido una excepción: " + ex.getMessage()); + addMensaje(true, "Ha ocurrido un error y no se ha podido recuperar el empleado con id: " + + textIntroducido); + AccountWindow.this.empleado = null; + + } + } + } + + }; + JtextFieldEmpno.addKeyListener(enterKeyAdapter); + } + + private void addMensaje(boolean keepText, String msg) { + String oldText = ""; + if (keepText) { + oldText = mensajes_text_Area.getText(); + + } + oldText = oldText + "\n" + msg; + mensajes_text_Area.setText(oldText); + + } + + private void showDialog(BigDecimal oldAmount) { + createDialog.setVisible(true); + Account cuentaACrearOActualizar = createDialog.getResult(); + if (cuentaACrearOActualizar != null) { + if (cuentaACrearOActualizar.getAccountno() != null) { + // update + update(cuentaACrearOActualizar, oldAmount); + } else + save(cuentaACrearOActualizar); + } + } + + private void update(Account cuenta, BigDecimal oldAmount) { + addMensaje(true, "La diferencia entre importes es: old:" + oldAmount + " new: " + cuenta.getAmount()); + BigDecimal diferencia = oldAmount.subtract(cuenta.getAmount()); + // oldAmount < cantidad actual, diferencia es negativa-> se ha ingresado dinero + // +diferencia + // oldAmount > cantidad actual, diferencia es positiva-> se ha retirado dinero + // -diferencia + // si cantidades iguales no hacemos nada + // En el movimiento hay que invertir los signos + + if (diferencia.compareTo(BigDecimal.ZERO) != 0) { + try { + AccMovement movimiento = accountServicio.autoTransferir(cuenta.getAccountno(), + diferencia.doubleValue() * (-1)); + + getAllAccounts(); + addMensaje(true, "Se ha creado el movimiento: " + movimiento); + + + } catch (Exception e2) { + addMensaje(true, "No se ha podido modificar la cuenta con número: " + cuenta.getAccountno()); + + } + } else { + addMensaje(true, "No ha habido variación de cantidad en la cuenta" + cuenta.getAccountno()); + } + + } + + private void save(Account cuenta) { + try { + accountServicio.crear(cuenta); + + addMensaje(true, "Se ha creado una cuenta con id: " + cuenta.getAccountno()); + getAllAccounts(); + + + } catch (Exception ex) { + addMensaje(true, "Ha ocurrido un error y no se ha podido crear la cuenta"); + } + } + + private void getAllAccounts() { + int empno = getEmpnoFromTextField(); + if (empno != -1) { + try { + List accounts = accountServicio.getAccountsByEmpno(empno); + addMensaje(true, "Se han recuperado: " + accounts.size() + " cuentas"); + DefaultListModel defModel = new DefaultListModel<>(); + + defModel.addAll(accounts); + + JListAllAccounts.setModel(defModel); + } catch (Exception ex) { + ex.printStackTrace(); + addMensaje(true, "Ha habido un error y no se han podido recuperar las cuentas del empleado: " + empno); + } + } else { + addMensaje(true, "El número de empleado no es correcto"); + } + + } + + private int getEmpnoFromTextField() { + int empno = -1; + String textIntroducido = JtextFieldEmpno.getText().trim(); + try { + empno = Integer.parseInt(textIntroducido); + } catch (Exception nfe) { + empno = -1; + } + return empno; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/CreateUpdateAccountDialog.java b/src/main/java/com/example/hibernate/CreateUpdateAccountDialog.java new file mode 100644 index 0000000..703d9ac --- /dev/null +++ b/src/main/java/com/example/hibernate/CreateUpdateAccountDialog.java @@ -0,0 +1,133 @@ +package com.example.hibernate; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.math.BigDecimal; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.border.EmptyBorder; + +import com.example.hibernate.model.Account; + +public class CreateUpdateAccountDialog extends JDialog { + + /** + * + */ + private static final long serialVersionUID = 1L; + private final JPanel contentPanel = new JPanel(); + private JTextField textFieldAmount; + private JButton okButton; + private JLabel lblError=null; + + private Account cuentaACrearOActualizar = null; + + public Account getResult() { + return this.cuentaACrearOActualizar; + } + + /** + * Create the dialog. + */ + public void initComponents() { + + setBounds(100, 100, 450, 300); + getContentPane().setLayout(new BorderLayout()); + contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); + getContentPane().add(contentPanel, BorderLayout.CENTER); + contentPanel.setLayout(null); + + JLabel lblImporte = new JLabel("Importe cuenta"); + lblImporte.setFont(new Font("Tahoma", Font.PLAIN, 14)); + lblImporte.setBounds(46, 76, 140, 24); + contentPanel.add(lblImporte); + + textFieldAmount = new JTextField(); + textFieldAmount.setFont(new Font("Tahoma", Font.PLAIN, 14)); + textFieldAmount.setBounds(215, 77, 197, 23); + contentPanel.add(textFieldAmount); + textFieldAmount.setColumns(10); + + lblError = new JLabel("Importe inicial"); + lblError.setVisible(false); + lblError.setForeground(new Color(255, 0, 0)); + lblError.setFont(new Font("Tahoma", Font.PLAIN, 14)); + lblError.setBounds(33, 169, 379, 24); + contentPanel.add(lblError); + + JPanel buttonPane = new JPanel(); + buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT)); + getContentPane().add(buttonPane, BorderLayout.SOUTH); + + okButton = new JButton("Guardar"); + + okButton.setActionCommand("OK"); + buttonPane.add(okButton); + getRootPane().setDefaultButton(okButton); + + JButton cancelButton = new JButton("Cancel"); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + cuentaACrearOActualizar = null; + CreateUpdateAccountDialog.this.dispose(); + + } + }); + cancelButton.setActionCommand("Cancel"); + buttonPane.add(cancelButton); + + ActionListener crearBtnActionListener = new ActionListener() { + + public void actionPerformed(ActionEvent e) { + if (!(textFieldAmount.getText().trim().equals(""))) { + try { + BigDecimal cantidad = getAmountFromTextField(); + + cuentaACrearOActualizar.setAmount(cantidad); + CreateUpdateAccountDialog.this.dispose(); + } catch (Exception ex) { + System.out.println("Ha ocurrido un problema obteniendo la cantidad: " + ex.getMessage()); + lblError.setText("La cantidad introducida no es correcta"); + lblError.setVisible(true); + + } + + } + } + }; + + this.okButton.addActionListener(crearBtnActionListener); + + } + + public CreateUpdateAccountDialog(Window owner, String title, ModalityType modalityType, Account acc) { + super(owner, title, modalityType); + initComponents(); + cuentaACrearOActualizar = acc; + lblError.setVisible(false); + if (cuentaACrearOActualizar != null && cuentaACrearOActualizar.getAmount()!=null ) { + + textFieldAmount.setText(cuentaACrearOActualizar.getAmount().toString()); + + } + this.setLocationRelativeTo(owner); + } + + private BigDecimal getAmountFromTextField() throws NumberFormatException { + + lblError.setVisible(false); + String textIntroducido = textFieldAmount.getText().trim(); + + return new BigDecimal(textIntroducido); + + } +} \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/model/dao/README.md b/src/main/java/com/example/hibernate/model/dao/README.md new file mode 100644 index 0000000..f364a2f --- /dev/null +++ b/src/main/java/com/example/hibernate/model/dao/README.md @@ -0,0 +1 @@ +# En esta carpeta deberíais añadir las clases e interfaces DAO \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/model/servicio/AccountServicio.java b/src/main/java/com/example/hibernate/model/servicio/AccountServicio.java new file mode 100644 index 0000000..98b357e --- /dev/null +++ b/src/main/java/com/example/hibernate/model/servicio/AccountServicio.java @@ -0,0 +1,50 @@ +package com.example.hibernate.model.servicio; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +import com.example.hibernate.model.AccMovement; +import com.example.hibernate.model.Account; +import com.example.hibernate.model.dao.IAccMovementDao; +import com.example.hibernate.model.dao.IAccountDao; +import com.example.hibernate.model.util.TransactionManager; + +public class AccountServicio implements IAccountServicio { + + private IAccountDao accountDao; + private IAccMovementDao accmovDao; + private TransactionManager transactionManager; + + public AccountServicio(IAccMovementDao accmovDao, IAccountDao accountDao, TransactionManager transactionManager) { + this.accountDao = accountDao; + this.accmovDao = accmovDao; + this.transactionManager = transactionManager; + } + + public List getAccountsByEmpno(Integer empno) { + throw new UnsupportedOperationException("Not implemented yet"); + + } + + @Override + public AccMovement autoTransferir(Integer accountno, double diferencia) { + throw new UnsupportedOperationException("Not implemented yet"); + } + + @Override + public void crear(Account account) { + throw new UnsupportedOperationException("Not implemented yet"); + } + + @Override + public void update(Account account) { + throw new UnsupportedOperationException("Not implemented yet"); + } + + @Override + public void delete(Integer accountno) { + throw new UnsupportedOperationException("Not implemented yet"); + + } +} diff --git a/src/main/java/com/example/hibernate/model/servicio/EmpleadoServicio.java b/src/main/java/com/example/hibernate/model/servicio/EmpleadoServicio.java new file mode 100644 index 0000000..72453f1 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/servicio/EmpleadoServicio.java @@ -0,0 +1,28 @@ +package com.example.hibernate.model.servicio; + + +import com.example.hibernate.model.Emp; +import com.example.hibernate.model.dao.EmpleadoDaoHibernate; +import com.example.hibernate.model.dao.IEmpleadoDao; +import com.example.hibernate.model.util.TransactionManager; +import com.example.hibernate.model.util.exceptions.InstanceNotFoundException; + + + +public class EmpleadoServicio implements IEmpleadoServicio { + + private IEmpleadoDao empleadoDao; + + + private TransactionManager transactionManager; + public EmpleadoServicio(IEmpleadoDao empleadoDao, TransactionManager transactionManager) { + this.empleadoDao = empleadoDao; + this.transactionManager = transactionManager; + } + + public Emp find(Integer empno) throws InstanceNotFoundException { + throw new UnsupportedOperationException("Not implemented yet"); + } + + +} diff --git a/src/main/java/com/example/hibernate/model/servicio/IAccountServicio.java b/src/main/java/com/example/hibernate/model/servicio/IAccountServicio.java new file mode 100644 index 0000000..c28dff3 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/servicio/IAccountServicio.java @@ -0,0 +1,20 @@ +package com.example.hibernate.model.servicio; + +import java.util.List; + +import com.example.hibernate.model.AccMovement; +import com.example.hibernate.model.Account; + +public interface IAccountServicio { + + public AccMovement autoTransferir(Integer accountno, double diferencia); + + public void crear(Account account); + + public void update(Account account); + + public List getAccountsByEmpno(Integer empno); + + public void delete(Integer accountno); + +} diff --git a/src/main/java/com/example/hibernate/model/servicio/IEmpleadoServicio.java b/src/main/java/com/example/hibernate/model/servicio/IEmpleadoServicio.java new file mode 100644 index 0000000..e932ced --- /dev/null +++ b/src/main/java/com/example/hibernate/model/servicio/IEmpleadoServicio.java @@ -0,0 +1,10 @@ +package com.example.hibernate.model.servicio; + +import com.example.hibernate.model.Emp; +import com.example.hibernate.model.util.exceptions.InstanceNotFoundException; + +public interface IEmpleadoServicio { + public Emp find(Integer empno) throws InstanceNotFoundException; + + +} diff --git a/src/main/java/com/example/hibernate/model/util/GenericDaoHibernate.java b/src/main/java/com/example/hibernate/model/util/GenericDaoHibernate.java new file mode 100644 index 0000000..46a59ff --- /dev/null +++ b/src/main/java/com/example/hibernate/model/util/GenericDaoHibernate.java @@ -0,0 +1,89 @@ +package com.example.hibernate.model.util; + +import java.io.Serializable; +import java.lang.reflect.ParameterizedType; +import java.util.List; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import com.example.hibernate.model.util.exceptions.InstanceNotFoundException; + +/** + * Implementación xenérica do DAO en Hibernate. + * + * @author maria + */ +public class GenericDaoHibernate implements IGenericDao { + + private final Class entityClass; + private final SessionFactory sessionFactory; + + @SuppressWarnings("unchecked") + public GenericDaoHibernate(SessionFactory sessionFactory) { + // getClass(): accedemos a la clase de la instancia que extienda esta clase + // (será ProfesorDaoHibernate u XDaoHibernate) + // .getGenericSuperclass(): obtenemos el tipo de la clase madre directa: + // GenericDaoHibernate En el caso de que sea una clase parametrizada (con + // Generics),devuelve el tipo del parámetro de tipo E: ParameterizedType: + // https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getGenericSuperclass-- + // .getActualTypeArguments(): devuelve un array de los tipos de los argumentos + // que se le pasan al tipo parametrizado + // finalmente obtenemos el nombre del tipo parametrizado: que será + // Profesor + this.entityClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass()) + .getActualTypeArguments()[0]; + + this.sessionFactory = sessionFactory; + } + + protected Session getSession() { + return sessionFactory.getCurrentSession(); + } + + + @Override + public void create(E entity) { + Session session = getSession(); + session.persist(entity); + } + + @Override + public E update(E entity) { + Session session = getSession(); + return session.merge(entity); + } + + @Override + public boolean exists(PK id) { + Session session = getSession(); + return session.get(entityClass, id) != null; + } + + @Override + public E find(PK id) throws InstanceNotFoundException { + Session session = getSession(); + E entity = session.get(entityClass, id); + if (entity == null) { + throw new InstanceNotFoundException(id, entityClass.getName()); + } + return entity; + } + + @Override + public void remove(PK id) throws InstanceNotFoundException { + Session session = getSession(); + E entity = session.get(entityClass, id); + if (entity == null) { + throw new InstanceNotFoundException(id, entityClass.getName()); + } + session.remove(entity); + } + + @Override + public List findAll() { + Session session = getSession(); + return session.createSelectionQuery("SELECT c FROM " + entityClass.getName() + " c", entityClass) + .getResultList(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/model/util/IGenericDao.java b/src/main/java/com/example/hibernate/model/util/IGenericDao.java new file mode 100644 index 0000000..b124877 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/util/IGenericDao.java @@ -0,0 +1,67 @@ +package com.example.hibernate.model.util; + +import java.io.Serializable; +import java.util.List; + +import com.example.hibernate.model.util.exceptions.InstanceNotFoundException; + +/** + * + * @author maria + * @param + */ +public interface IGenericDao { + // Usamos un tipo genérico para indicar que la interfaz IGenericDao tendrá un + // parámetro de cualquier tipo (clases del modelo), salvo tipos primitivos + // https://docs.oracle.com/javase/tutorial/java/generics/types.html + //Se usa un segundo tipo parametrizado para la clave primaria + + /*** + * Guarda una entidad en el sistema de persistencia + * + * @param entity + * @return la entidad con la clave primaria asignada + */ + public void create(E entity); + + /*** + * Busca en el sistema de persistencia una entidad por su clave primaria + * + * @param id + * @return la entidad si la encuentra + * @throws InstanceNotFoundException si no encuentra la entidad + */ + public E find(PK id) throws InstanceNotFoundException; + + /*** + * Comprueba si existe la entidad con ese id como clave primaria + * + * @param id + * @return true si se ha encontrado, false en caso contrario. + */ + public boolean exists(PK id); + + /*** + * Elimina una entidad del sistema de persistencia + * + * @param id clave primaria para encontrar la entidad + * @throws InstanceNotFoundException si no encuentra la entidad + */ + public void remove(PK id) throws InstanceNotFoundException; + + /** + * Obtiene una lista de todas las entidades en el sistema persistente + * + * @return + */ + public List findAll(); + + /** + * Actualiza una entidad del sistema de persistencia + * @param entidad a actualizar + * @return entidad actualizada y persistente + */ + public E update(E entity); + + +} \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/model/util/OperacionHibernate.java b/src/main/java/com/example/hibernate/model/util/OperacionHibernate.java new file mode 100644 index 0000000..be050f7 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/util/OperacionHibernate.java @@ -0,0 +1,6 @@ +package com.example.hibernate.model.util; + +@FunctionalInterface +public interface OperacionHibernate { + public R ejecutar() throws Exception; +} \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/model/util/TransactionManager.java b/src/main/java/com/example/hibernate/model/util/TransactionManager.java new file mode 100644 index 0000000..5bbf637 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/util/TransactionManager.java @@ -0,0 +1,28 @@ +package com.example.hibernate.model.util; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +public class TransactionManager { + + private final SessionFactory sessionFactory; + + public TransactionManager(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public R ejecutar(OperacionHibernate operacion) { + Transaction tx = null; + try { + Session session = sessionFactory.getCurrentSession(); + tx = session.beginTransaction(); + R resultado = operacion.ejecutar(); + tx.commit(); + return resultado; + } catch (Exception e) { + if (tx != null) tx.rollback(); + throw new RuntimeException("Error en la transacción", e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/example/hibernate/model/util/exceptions/InstanceNotFoundException.java b/src/main/java/com/example/hibernate/model/util/exceptions/InstanceNotFoundException.java new file mode 100644 index 0000000..1c19301 --- /dev/null +++ b/src/main/java/com/example/hibernate/model/util/exceptions/InstanceNotFoundException.java @@ -0,0 +1,35 @@ +package com.example.hibernate.model.util.exceptions; + + + + +/** + * + * @author maria + */ +public class InstanceNotFoundException extends Exception { + + + private Object key; + private String className; + + private static final String DEFAULT_MSG = "Instance not found"; + + public InstanceNotFoundException( Object key, + String className) { + + super(DEFAULT_MSG + " (key = '" + key + "' - className = '" + + className + "')"); + this.key = key; + this.className = className; + + } + + public Object getKey() { + return key; + } + + public String getClassName() { + return className; + } +} diff --git a/src/main/java/com/example/hibernate/util/HibernateUtil.java b/src/main/java/com/example/hibernate/util/HibernateUtil.java new file mode 100644 index 0000000..32a3e6f --- /dev/null +++ b/src/main/java/com/example/hibernate/util/HibernateUtil.java @@ -0,0 +1,66 @@ +package com.example.hibernate.util; + +import org.hibernate.SessionFactory; +import org.hibernate.boot.registry.StandardServiceRegistry; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; + +import com.example.hibernate.model.AccMovement; +import com.example.hibernate.model.Account; +import com.example.hibernate.model.Dept; +import com.example.hibernate.model.Emp; +import com.example.hibernate.model.Project; + + + +public class HibernateUtil { + + private static HibernateUtil instance; + private static SessionFactory sessionFactory; + private static StandardServiceRegistry serviceRegistry; + + // Private constructor to prevent external instantiation + private HibernateUtil() { + try { + // Automatically reads hibernate.properties or hibernate.cfg.xml from classpath + serviceRegistry = + new StandardServiceRegistryBuilder() + .build(); + + // Build SessionFactory using the service registry + sessionFactory = new org.hibernate.boot.MetadataSources(serviceRegistry) + + + + .buildMetadata() + .buildSessionFactory(); + } catch (Exception ex) { + throw new ExceptionInInitializerError("Failed to create SessionFactory: " + ex); + } + } + + // Singleton accessor method + public static HibernateUtil getInstance() { + if (instance == null) { + instance = new HibernateUtil(); + } + return instance; + } + + // Get the SessionFactory + public SessionFactory getSessionFactory() { + return sessionFactory; + } + + // Shutdown Hibernate and clean up resources + public static void shutdown() { + if (serviceRegistry != null) { + StandardServiceRegistryBuilder.destroy(serviceRegistry); + } + } + + public void close() { + if (sessionFactory != null) { + sessionFactory.close(); + } + } +} diff --git a/src/main/resources/hibernate.properties b/src/main/resources/hibernate.properties new file mode 100644 index 0000000..37c6938 --- /dev/null +++ b/src/main/resources/hibernate.properties @@ -0,0 +1,17 @@ +# Database connection settings +hibernate.connection.url= +hibernate.connection.driver_class= +hibernate.connection.username= +hibernate.connection.password= + +# Echo all executed SQL to console +hibernate.show_sql=true +hibernate.format_sql=true +hibernate.highlight_sql=true + +hibernate.default_schema= +hibernate.dialect=org.hibernate.dialect.MySQLDialect +hibernate.hbm2ddl.auto=update +hibernate.default_catalog= + +hibernate.current_session_context_class=thread diff --git a/src/main/resources/scripts/mariadb/1_scripts_empresa.sql b/src/main/resources/scripts/mariadb/1_scripts_empresa.sql new file mode 100644 index 0000000..6fd463a --- /dev/null +++ b/src/main/resources/scripts/mariadb/1_scripts_empresa.sql @@ -0,0 +1,131 @@ +-- Select the database only if it doesn't already exist +CREATE DATABASE IF NOT EXISTS empresa; + +-- Switch to empresa database +USE empresa; + +-- Create the DEPT table only if it doesn't already exist +CREATE TABLE IF NOT EXISTS DEPT ( + DEPTNO INT AUTO_INCREMENT PRIMARY KEY, + DNAME VARCHAR(20), + LOC VARCHAR(20) +); + +-- Create the EMP table only if it doesn't already exist +CREATE TABLE IF NOT EXISTS EMP ( + EMPNO INT AUTO_INCREMENT PRIMARY KEY, + ENAME VARCHAR(20), + JOB VARCHAR(20), + MGR INT, + HIREDATE DATE, + SAL DECIMAL(15,2), + COMM DECIMAL(15,2), + DEPTNO INT, + FOREIGN KEY (MGR) REFERENCES EMP(EMPNO), + FOREIGN KEY (DEPTNO) REFERENCES DEPT(DEPTNO) +); + +-- Switch to empresa database +USE empresa; + +-- Insert values into the DEPT table with specific DEPTNO values +INSERT INTO DEPT (DEPTNO, DNAME, LOC) VALUES + (10, 'ACCOUNTING', 'NEW YORK'), + (20, 'RESEARCH', 'DALLAS'), + (30, 'SALES', 'CHICAGO'), + (40, 'OPERATIONS', 'BOSTON'); + +-- Insert values into the EMP table with specific EMPNO values +INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES + (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000, NULL, 10), + (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, NULL, 20), + (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, NULL, 10), + (7788, 'SCOTT', 'ANALYST', 7566, '1982-12-09', 3000, NULL, 20), + (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, NULL, 20), + (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, NULL, 30), + (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, NULL, 20), + (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30), + (7521, 'WARD', 'SALESMAN', 7698, '1981-02-20', 1250, 500, 30), + (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30), + (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500, 0, 30), + (7876, 'ADAMS', 'CLERK', 7788, '1983-01-12', 1100, NULL, 20), + (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, NULL, 30), + (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, NULL, 10); + + +-- Seleccionar la base de datos +USE empresa; + +-- Crear tabla ACCOUNT solo si no existe +CREATE TABLE IF NOT EXISTS ACCOUNT ( + ACCOUNTNO INT NOT NULL AUTO_INCREMENT, + EMPNO INT NOT NULL, + AMOUNT DECIMAL(19, 4) NOT NULL, + PRIMARY KEY (ACCOUNTNO), + FOREIGN KEY (EMPNO) REFERENCES EMP(EMPNO) +) ENGINE=InnoDB; + +-- Eliminar restricción si existe y crear tabla ACC_MOVEMENT solo si no existe +CREATE TABLE IF NOT EXISTS ACC_MOVEMENT ( + ACCOUNT_MOV_ID INT NOT NULL AUTO_INCREMENT, + ACCOUNT_ORIGIN_ID INT NOT NULL, + ACCOUNT_DEST_ID INT NOT NULL, + AMOUNT DECIMAL(19, 4) NOT NULL, + DATETIME DATETIME NOT NULL, + PRIMARY KEY (ACCOUNT_MOV_ID), + FOREIGN KEY (ACCOUNT_ORIGIN_ID) REFERENCES ACCOUNT(ACCOUNTNO), + FOREIGN KEY (ACCOUNT_DEST_ID) REFERENCES ACCOUNT(ACCOUNTNO) +) ENGINE=InnoDB; + + +USE empresa; + +-- Insertar en la tabla ACCOUNT para cada empleado que no tenga una cuenta +INSERT INTO ACCOUNT (EMPNO, AMOUNT) +SELECT DISTINCT EMPNO, 1000 + IFNULL(COMM, 0) +FROM EMP +WHERE EMPNO NOT IN (SELECT DISTINCT EMPNO FROM ACCOUNT); + + +USE empresa; + +CREATE TABLE IF NOT EXISTS PROJECT ( + PROJNO INT AUTO_INCREMENT NOT NULL, + PROJNAME VARCHAR(50) NOT NULL, + PRIMARY KEY (PROJNO) +) ENGINE=InnoDB; + +CREATE TABLE IF NOT EXISTS PROJECT_EMP ( + PROJECTNO INT NOT NULL, + EMPNO INT NOT NULL, + PRIMARY KEY (PROJECTNO, EMPNO), + FOREIGN KEY (EMPNO) REFERENCES EMP(EMPNO) ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (PROJECTNO) REFERENCES PROJECT(PROJNO) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + + +use empresa; +INSERT INTO PROJECT (PROJNAME) VALUES +('Desenvolvemento de Software Libre'), +('Inteligencia Artificial para Empresas'), +('Plataforma de Comercio Electrónico'), +('Seguridade Informática Avanzada'), +('Automatización con Internet das Cousas'); + + +INSERT INTO PROJECT_EMP (PROJECTNO, EMPNO) VALUES +-- Primeiro proxecto: Desenvolvemento de Software Libre +(1, 7369), (1, 7566), (1, 7788), + +-- Segundo proxecto: Intelixencia Artificial para Empresas +(2, 7521), (2, 7839), (2, 7902), + +-- Terceiro proxecto: Plataforma de Comercio Electrónico +(3, 7654), (3, 7499), (3, 7782), + +-- Cuarto proxecto: Seguridade Informática Avanzada +(4, 7698), (4, 7844), + +-- Quinto proxecto: Automatización con Internet das Cousas +(5, 7876), (5, 7934); + diff --git a/src/main/resources/scripts/mariadb/2_create_user.sql b/src/main/resources/scripts/mariadb/2_create_user.sql new file mode 100644 index 0000000..da33752 --- /dev/null +++ b/src/main/resources/scripts/mariadb/2_create_user.sql @@ -0,0 +1,3 @@ +CREATE USER 'user_empresa'@'localhost' IDENTIFIED BY 'password'; +GRANT ALL PRIVILEGES ON empresa.* TO 'user_empresa'@'localhost'; +FLUSH PRIVILEGES; \ No newline at end of file