diff --git a/010_spring_boot/README.md b/010_spring_boot/README.md index 8d1f57c..b7b499a 100644 --- a/010_spring_boot/README.md +++ b/010_spring_boot/README.md @@ -7,3 +7,5 @@ Java y [bases de datos](./base_de_datos.md) - Lectura [JDBC](https://www.aluracursos.com/blog/conociendo-el-jdbc) - [Curso](https://app.aluracursos.com/course/java-jdbc-trabajando-base-datos) Java y [JDBC](./jdbc.md) +- [Curso](https://app.aluracursos.com/course/persistencia-jpa-hibernate) +Persistencia con [JPA - Hibernate](./jpa_persistencia_hibernate.md) diff --git a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/controller/CategoriaController.java b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/controller/CategoriaController.java index 4a6bb94..aa7947c 100644 --- a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/controller/CategoriaController.java +++ b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/controller/CategoriaController.java @@ -11,13 +11,13 @@ public class CategoriaController { private CategoriaDAO categoriaDAO; public CategoriaController() { - var factory = new ConnectionFactory(); + ConnectionFactory factory = new ConnectionFactory(); this.categoriaDAO = new CategoriaDAO(factory.recuperaConexion()); } - public List listar() { - return categoriaDAO.listar(); - } + public List listar() { + return categoriaDAO.listar(); + } public List cargaReporte() { return this.categoriaDAO.listarConProductos(); diff --git a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/controller/ProductoController.java b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/controller/ProductoController.java index 44ac0d7..a84bbd0 100644 --- a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/controller/ProductoController.java +++ b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/controller/ProductoController.java @@ -8,33 +8,33 @@ import com.alura.jdbc.modelo.Categoria; import com.alura.jdbc.modelo.Producto; public class ProductoController { - + private ProductoDAO productoDAO; - public ProductoController() { + public ProductoController() { this.productoDAO = new ProductoDAO(new ConnectionFactory().recuperaConexion()); } public int modificar(Producto producto) { return productoDAO.modificar(producto); - } + } - public int eliminar(Integer id) { - return productoDAO.eliminar(id); - } + public int eliminar(Integer id) { + return productoDAO.eliminar(id); + } - public List listar() { - return productoDAO.listar(); - } + public List listar() { + return productoDAO.listar(); + } - public List listar(Categoria categoria) { - return productoDAO.listar(categoria.getId()); - } + public List listar(Categoria categoria) { + return productoDAO.listar(categoria.getId()); + } public void guardar(Producto producto, Integer categoriaId) { producto.setCategoriaId(categoriaId); productoDAO.guardar(producto); - } + } -} \ No newline at end of file +} diff --git a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/dao/CategoriaDAO.java b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/dao/CategoriaDAO.java index 5c96438..a093129 100644 --- a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/dao/CategoriaDAO.java +++ b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/dao/CategoriaDAO.java @@ -18,7 +18,7 @@ public class CategoriaDAO { } public void guardar(Categoria categoria) { - try { + try { final PreparedStatement statement = con.prepareStatement( "INSERT INTO categoria(nombre) VALUES(?)", Statement.RETURN_GENERATED_KEYS); @@ -33,22 +33,22 @@ public class CategoriaDAO { private void ejecutaRegistro(Categoria categoria, PreparedStatement statement) throws SQLException { statement.setString(1, categoria.getNombre()); - statement.execute(); - final ResultSet resultSet = statement.getGeneratedKeys(); - try (resultSet) { + statement.execute(); + final ResultSet resultSet = statement.getGeneratedKeys(); + try (resultSet) { while (resultSet.next()) { categoria.setId(resultSet.getInt(1)); System.out.println(String.format("Categoria agregada %s: ", categoria)); } - } + } } public List listar() { List resultado = new ArrayList<>(); final String query = "SELECT ID, NOMBRE FROM categoria;"; System.out.println(query); - try { - + try { + final PreparedStatement statement = con.prepareStatement(query); try (statement) { statement.execute(); @@ -62,14 +62,14 @@ public class CategoriaDAO { } return resultado; } - } catch (SQLException e) { - throw new RuntimeException(e); - } + } catch (SQLException e) { + throw new RuntimeException(e); + } } public int modificar(Categoria categoria) { - try { - final String query = "UPDATE categoria SET NOMBRE=? WHERE ID=?;"; + try { + final String query = "UPDATE categoria SET NOMBRE=? WHERE ID=?;"; final PreparedStatement statement = con.prepareStatement(query); try (statement) { statement.setString(1, categoria.getNombre()); @@ -78,13 +78,13 @@ public class CategoriaDAO { int resultado = statement.getUpdateCount(); return resultado; } - } catch (SQLException e) { - throw new RuntimeException(e); - } + } catch (SQLException e) { + throw new RuntimeException(e); + } } public int eliminar(Integer id) { - try { + try { final PreparedStatement statement = con.prepareStatement("DELETE FROM categoria WHERE ID=?;"); try (statement) { statement.setInt(1, id); @@ -92,9 +92,9 @@ public class CategoriaDAO { int resultado = statement.getUpdateCount(); return resultado; } - } catch (SQLException e) { - throw new RuntimeException(e); - } + } catch (SQLException e) { + throw new RuntimeException(e); + } } public List listarConProductos() { @@ -102,7 +102,7 @@ public class CategoriaDAO { final String query = "SELECT C.ID, C.NOMBRE, P.ID, P.NOMBRE, P.CANTIDAD FROM categoria C " + "INNER JOIN producto P ON C.ID = P.CATEGORIA_ID "; System.out.println(query); - try { + try { final PreparedStatement statement = con.prepareStatement(query); try (statement) { statement.execute(); @@ -126,9 +126,9 @@ public class CategoriaDAO { } }; } - } catch (SQLException e) { - throw new RuntimeException(e); - } + } catch (SQLException e) { + throw new RuntimeException(e); + } return resultado; } diff --git a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/dao/ProductoDAO.java b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/dao/ProductoDAO.java index 6582262..83e2173 100644 --- a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/dao/ProductoDAO.java +++ b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/dao/ProductoDAO.java @@ -17,7 +17,7 @@ public class ProductoDAO { } public void guardar(Producto producto) { - try { + try { final PreparedStatement statement = con.prepareStatement( "INSERT INTO producto(nombre, descripcion, cantidad, categoria_id) VALUES(?,?,?,?)", Statement.RETURN_GENERATED_KEYS); @@ -32,22 +32,22 @@ public class ProductoDAO { private void ejecutaRegistro(Producto producto, PreparedStatement statement) throws SQLException { statement.setString(1, producto.getNombre()); - statement.setString(2, producto.getDescripcion()); - statement.setInt(3, producto.getCantidad()); - statement.setInt(4, producto.getCategoriaId()); - statement.execute(); - final ResultSet resultSet = statement.getGeneratedKeys(); - try (resultSet) { + statement.setString(2, producto.getDescripcion()); + statement.setInt(3, producto.getCantidad()); + statement.setInt(4, producto.getCategoriaId()); + statement.execute(); + final ResultSet resultSet = statement.getGeneratedKeys(); + try (resultSet) { while (resultSet.next()) { producto.setId(resultSet.getInt(1)); System.out.println(String.format("Producto insertado %s: ", producto)); } - } + } } public List listar() { List resultado = new ArrayList<>(); - try { + try { final PreparedStatement statement = con.prepareStatement( "SELECT ID, NOMBRE, DESCRIPCION, CANTIDAD, CATEGORIA_ID FROM producto;"); try (statement) { @@ -65,9 +65,9 @@ public class ProductoDAO { } return resultado; } - } catch (SQLException e) { - throw new RuntimeException(e); - } + } catch (SQLException e) { + throw new RuntimeException(e); + } } public int modificar(Producto producto) { @@ -78,7 +78,7 @@ public class ProductoDAO { query += " WHERE ID=?;"; } - try { + try { final PreparedStatement statement = con.prepareStatement(query); try (statement) { statement.setString(1, producto.getNombre()); @@ -95,13 +95,13 @@ public class ProductoDAO { int resultado = statement.getUpdateCount(); return resultado; } - } catch (SQLException e) { - throw new RuntimeException(e); - } + } catch (SQLException e) { + throw new RuntimeException(e); + } } public int eliminar(Integer id) { - try { + try { final PreparedStatement statement = con.prepareStatement("DELETE FROM producto WHERE ID=?;"); try (statement) { statement.setInt(1, id); @@ -109,16 +109,16 @@ public class ProductoDAO { int resultado = statement.getUpdateCount(); return resultado; } - } catch (SQLException e) { - throw new RuntimeException(e); - } + } catch (SQLException e) { + throw new RuntimeException(e); + } } public List listar(Integer id) { List resultado = new ArrayList<>(); final String query = "SELECT ID, NOMBRE, DESCRIPCION, CANTIDAD, CATEGORIA_ID FROM producto WHERE categoria_id=?;"; //System.out.println(query); - try { + try { final PreparedStatement statement = con.prepareStatement(query); statement.setInt(1, id); try (statement) { @@ -136,9 +136,9 @@ public class ProductoDAO { } return resultado; } - } catch (SQLException e) { - throw new RuntimeException(e); - } + } catch (SQLException e) { + throw new RuntimeException(e); + } } } diff --git a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/factory/ConnectionFactory.java b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/factory/ConnectionFactory.java index 87e4420..837e90e 100644 --- a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/factory/ConnectionFactory.java +++ b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/factory/ConnectionFactory.java @@ -6,18 +6,18 @@ import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class ConnectionFactory { - - private final static String driver = "jdbc:mysql://"; - private final static String dbaddr = "192.168.0.8:3306/"; - private final static String params = "?useTimeZone=true&serverTimeZone=UTC"; - private final static String dbname = "control_de_stock"; - private final static String dburl = driver+dbaddr+dbname+params; - private final static String dbuser = "alura"; - private final static String dbpass = "alura"; - - private DataSource datasource; - - public ConnectionFactory() { + + private final static String driver = "jdbc:mysql://"; + private final static String dbaddr = "192.168.0.8:3306/"; + private final static String params = "?useTimeZone=true&serverTimeZone=UTC"; + private final static String dbname = "control_de_stock"; + private final static String dburl = driver+dbaddr+dbname+params; + private final static String dbuser = "alura"; + private final static String dbpass = "alura"; + + private DataSource datasource; + + public ConnectionFactory() { var pooledDataSource = new ComboPooledDataSource(); pooledDataSource.setJdbcUrl(dburl); pooledDataSource.setUser(dbuser); @@ -25,13 +25,13 @@ public class ConnectionFactory { pooledDataSource.setMaxPoolSize(10); this.datasource = pooledDataSource; } - - public Connection recuperaConexion() { - //return DriverManager.getConnection(dburl, dbuser, dbpass); - try { - return this.datasource.getConnection(); + + public Connection recuperaConexion() { + //return DriverManager.getConnection(dburl, dbuser, dbpass); + try { + return this.datasource.getConnection(); } catch (Exception e) { throw new RuntimeException(e); } - } + } } diff --git a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/pruebas/PruebaConexion.java b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/pruebas/PruebaConexion.java index 1e54b07..bb68bd2 100644 --- a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/pruebas/PruebaConexion.java +++ b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/pruebas/PruebaConexion.java @@ -6,11 +6,12 @@ import java.sql.SQLException; import com.alura.jdbc.factory.ConnectionFactory; public class PruebaConexion { - - public static void main(String[] args) throws SQLException { - Connection con = new ConnectionFactory().recuperaConexion(); - System.out.println("Cerrando conexión"); - con.close(); - } + + public static void main(String[] args) throws SQLException { + System.out.println("Intentando conexión con Connetion Factory"); + Connection con = new ConnectionFactory().recuperaConexion(); + System.out.println("Prueba OK, cerrando conexión"); + con.close(); + } } diff --git a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/pruebas/PruebaDelete.java b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/pruebas/PruebaDelete.java index c4e14a1..2bc65c4 100644 --- a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/pruebas/PruebaDelete.java +++ b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/pruebas/PruebaDelete.java @@ -7,10 +7,10 @@ import java.sql.Statement; import com.alura.jdbc.factory.ConnectionFactory; public class PruebaDelete { - public static void main(String[] args) throws SQLException { - Connection con = new ConnectionFactory().recuperaConexion(); - Statement stmnt = con.createStatement(); - stmnt.execute("DELETE FROM producto WHERE ID=99"); - System.out.println(stmnt.getUpdateCount()); - } + public static void main(String[] args) throws SQLException { + Connection con = new ConnectionFactory().recuperaConexion(); + Statement stmnt = con.createStatement(); + stmnt.execute("DELETE FROM producto WHERE ID=99"); + System.out.println(stmnt.getUpdateCount()); + } } diff --git a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/view/ControlDeStockFrame.java b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/view/ControlDeStockFrame.java index 751ea03..76709f0 100644 --- a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/view/ControlDeStockFrame.java +++ b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/view/ControlDeStockFrame.java @@ -223,7 +223,7 @@ public class ControlDeStockFrame extends JFrame { Integer id = Integer.valueOf(modelo.getValueAt(tabla.getSelectedRow(), 0).toString()); int cantidadEliminada; - cantidadEliminada = this.productoController.eliminar(id); + cantidadEliminada = this.productoController.eliminar(id); modelo.removeRow(tabla.getSelectedRow()); JOptionPane.showMessageDialog(this, cantidadEliminada+" Item eliminado con éxito!"); @@ -231,17 +231,17 @@ public class ControlDeStockFrame extends JFrame { } private void cargarTabla() { - var productos = this.productoController.listar(); - productos.forEach(producto -> modelo.addRow( - new Object[] { + var productos = this.productoController.listar(); + productos.forEach(producto -> modelo.addRow( + new Object[] { producto.getId(), producto.getNombre(), producto.getDescripcion(), producto.getCantidad(), producto.getCategoriaId() - } - ) - ); + } + ) + ); } private void guardar() { @@ -270,7 +270,7 @@ public class ControlDeStockFrame extends JFrame { var categoria = (Categoria) comboCategoria.getSelectedItem(); - this.productoController.guardar(producto, categoria.getId()); + this.productoController.guardar(producto, categoria.getId()); JOptionPane.showMessageDialog(this, "Registrado con éxito!"); this.limpiarFormulario(); } diff --git a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/view/ReporteFrame.java b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/view/ReporteFrame.java index 88fabf5..ba1b2d1 100644 --- a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/view/ReporteFrame.java +++ b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/jdbc/view/ReporteFrame.java @@ -47,18 +47,18 @@ public class ReporteFrame extends JFrame { private void cargaReporte() { var contenido = categoriaController.cargaReporte(); - contenido.forEach(categoria -> { - modelo.addRow(new Object[] { categoria.getId(), - categoria.getNombre(), - "Artículo", "Stock" }); - var productos = categoria.getProductos(); - productos.forEach(producto -> - modelo.addRow(new Object[] { "", - producto.getId(), - producto.getNombre(), - producto.getCantidad() } - )); - }); + contenido.forEach(categoria -> { + modelo.addRow(new Object[] { categoria.getId(), + categoria.getNombre(), + "Artículo", "Stock" }); + var productos = categoria.getProductos(); + productos.forEach(producto -> + modelo.addRow(new Object[] { "", + producto.getId(), + producto.getNombre(), + producto.getCantidad() } + )); + }); } } diff --git a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/tests/PruebaConexion.java b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/tests/PruebaConexion.java index ccd0380..e9bfab0 100644 --- a/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/tests/PruebaConexion.java +++ b/010_spring_boot/java_jdbc/control-de-stock/src/main/java/com/alura/tests/PruebaConexion.java @@ -15,10 +15,10 @@ public class PruebaConexion { private final static String dbpass = "alura"; public static void main(String[] args) throws SQLException { - System.out.println("hola"); + System.out.println("Intentando conexión con DB"); Connection con = DriverManager.getConnection(dburl, dbuser, dbpass); con.close(); - System.out.println("chao"); + System.out.println("Prueba OK, conexión cerrada"); } } diff --git a/010_spring_boot/jpa/tienda/pom.xml b/010_spring_boot/jpa/tienda/pom.xml new file mode 100644 index 0000000..17a84e2 --- /dev/null +++ b/010_spring_boot/jpa/tienda/pom.xml @@ -0,0 +1,45 @@ + + 4.0.0 + com.latam.alura.tienda + tienda + 0.0.1-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + ${java.version} + ${java.version} + true + UTF-8 + ${java.version} + true + /usr/bin/java + + + + + + + org.hibernate + hibernate-entitymanager + 5.6.15.Final + + + com.h2database + h2 + 2.2.222 + runtime + + + + 17 + ${java.version} + ${java.version} + UTF-8 + + \ No newline at end of file diff --git a/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/dao/CategoriaDao.java b/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/dao/CategoriaDao.java new file mode 100644 index 0000000..369514b --- /dev/null +++ b/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/dao/CategoriaDao.java @@ -0,0 +1,38 @@ +package com.latam.alura.tienda.dao; + +import java.util.List; + +import javax.persistence.EntityManager; + +import com.latam.alura.tienda.modelo.Categoria; + +public class CategoriaDao { + + private EntityManager em; + + public CategoriaDao(EntityManager em) { + this.em = em; + } + + public void guardar(Categoria categoria) { + this.em.persist(categoria); + } + + public void actualizar(Categoria categoria) { + this.em.merge(categoria); + } + + public void remover(Categoria categoria) { + categoria = this.em.merge(categoria); + this.em.remove(categoria); + } + + public Categoria consultaPorId(Long id) { + return em.find(Categoria.class, id); + } + + public List consultarTodos() { + String jpql = "SELECT P FROM Categoria AS P"; + return em.createQuery(jpql, Categoria.class).getResultList(); + } +} diff --git a/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/dao/ProductoDao.java b/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/dao/ProductoDao.java new file mode 100644 index 0000000..4688d56 --- /dev/null +++ b/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/dao/ProductoDao.java @@ -0,0 +1,54 @@ +package com.latam.alura.tienda.dao; + +import java.math.BigDecimal; +import java.util.List; + +import javax.persistence.EntityManager; + +import com.latam.alura.tienda.modelo.Producto; + +public class ProductoDao { + + private EntityManager em; + + public ProductoDao(EntityManager em) { + this.em = em; + } + + public void guardar(Producto producto) { + this.em.persist(producto); + } + + public void actualizar(Producto producto) { + this.em.merge(producto); + } + + public void remover(Producto producto) { + producto = this.em.merge(producto); + this.em.remove(producto); + } + + public Producto consultaPorId(Long id) { + return em.find(Producto.class, id); + } + + public List consultarTodos() { + String jpql = "SELECT P FROM Producto AS P"; + return em.createQuery(jpql, Producto.class).getResultList(); + } + + public List consultaPorNombre(String nombre) { + String jpql = "SELECT P FROM Producto AS P WHERE P.nombre=:nombre"; + return em.createQuery(jpql, Producto.class).setParameter("nombre", nombre).getResultList(); + } + + public List consultaPorNombreDeCategoria(String nombre) { + String jpql = "SELECT P FROM Producto AS P WHERE P.categoria.nombre=:nombre"; + return em.createQuery(jpql, Producto.class).setParameter("nombre", nombre).getResultList(); + } + + public BigDecimal consultaPrecioPorNombreDeProducto(String nombre) { + String jpql = "SELECT P.precio FROM Producto AS P WHERE P.nombre=:nombre"; + return em.createQuery(jpql, BigDecimal.class).setParameter("nombre", nombre).getSingleResult(); + } +} diff --git a/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/modelo/Categoria.java b/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/modelo/Categoria.java new file mode 100644 index 0000000..ca3d679 --- /dev/null +++ b/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/modelo/Categoria.java @@ -0,0 +1,46 @@ +package com.latam.alura.tienda.modelo; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +//public enum Categoria { +// SOFTWARES, +// LIBROS, +// CELULARES +//} + +@Entity +@Table(name="categorias") +public class Categoria { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String nombre; + + public Categoria() {} + + public Categoria(String nombre) { + this.nombre = nombre; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getNombre() { + return nombre; + } + + public void setNombre(String nombre) { + this.nombre = nombre; + } + +} \ No newline at end of file diff --git a/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/modelo/Producto.java b/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/modelo/Producto.java new file mode 100644 index 0000000..0db6112 --- /dev/null +++ b/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/modelo/Producto.java @@ -0,0 +1,75 @@ +package com.latam.alura.tienda.modelo; + +import java.math.BigDecimal; +import java.time.LocalDate; + +import javax.persistence.Entity; +//import javax.persistence.EnumType; +//import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +@Entity +@Table(name="productos") +public class Producto { + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + private Long id; + // @Column(name="nombres") + private String nombre; + private String descripcion; + private BigDecimal precio; + private LocalDate fechaDeRegistro = LocalDate.now(); + //@Enumerated(EnumType.STRING) + @ManyToOne + private Categoria categoria; + + public Producto() {} + + public Producto(String nombre, String descripcion, BigDecimal precio, Categoria categoria) { + this.nombre = nombre; + this.descripcion = descripcion; + this.precio = precio; + this.categoria = categoria; + } + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + + public String getNombre() { + return nombre; + } + + public void setNombre(String nombre) { + this.nombre = nombre; + } + + public String getDescripcion() { + return descripcion; + } + + public void setDescripcion(String descripcion) { + this.descripcion = descripcion; + } + + public BigDecimal getPrecio() { + return precio; + } + + public void setPrecio(BigDecimal precio) { + this.precio = precio; + } + + public LocalDate getFechaDeRegistro() { + return fechaDeRegistro; + } + +} diff --git a/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/prueba/RegistroDeProducto.java b/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/prueba/RegistroDeProducto.java new file mode 100644 index 0000000..0805acd --- /dev/null +++ b/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/prueba/RegistroDeProducto.java @@ -0,0 +1,121 @@ +package com.latam.alura.tienda.prueba; + +import java.math.BigDecimal; +import java.util.List; + +import javax.persistence.EntityManager; +//import javax.persistence.EntityManagerFactory; +//import javax.persistence.Persistence; + +import com.latam.alura.tienda.dao.CategoriaDao; +import com.latam.alura.tienda.dao.ProductoDao; +import com.latam.alura.tienda.modelo.Categoria; +import com.latam.alura.tienda.modelo.Producto; +import com.latam.alura.tienda.utils.JPAUtils; + +public class RegistroDeProducto { + + public static void main(String[] args) { + RegistrarProducto(); + EntityManager em = JPAUtils.getEntityManager(); + ProductoDao productoDao = new ProductoDao(em); + Producto producto = productoDao.consultaPorId(1L); + System.out.println(producto.getNombre()); + + List productos = productoDao.consultarTodos(); + productos.forEach(producto_ -> System.out.println(producto_.getDescripcion())); + + CategoriaDao categoriaDao = new CategoriaDao(em); + List categorias = categoriaDao.consultarTodos(); + categorias.forEach(categoria_ -> System.out.println(categoria_.getNombre())); + + List productos_por_nombre = productoDao.consultaPorNombre("Samsung"); + productos_por_nombre.forEach(producto_ -> System.out.println(producto_.getDescripcion())); + + List productos_por_nombre_categoria = productoDao.consultaPorNombreDeCategoria("Celulares"); + productos_por_nombre_categoria.forEach(producto_ -> System.out.println(producto_.getDescripcion())); + + BigDecimal precio_producto = productoDao.consultaPrecioPorNombreDeProducto("Samsung"); + System.out.println(precio_producto); + /* + Categoria celulares = new Categoria("Celulares"); + //Producto celular = new Producto("Samsung", "Teléfono usado", new BigDecimal("1000"), Categoria.CELULARES); + Producto celular = new Producto("Samsung", "Teléfono usado", new BigDecimal("1000"), celulares); + //celular.setNombre("Samsung"); + //celular.setDescripcion("Teléfono usado"); + //celular.setPrecio(new BigDecimal("1000")); + + //EntityManagerFactory factory = Persistence.createEntityManagerFactory("tienda"); + //EntityManager em = factory.createEntityManager(); + EntityManager em = JPAUtils.getEntityManager(); + + ProductoDao productoDao = new ProductoDao(em); + CategoriaDao categoriaDao = new CategoriaDao(em); + + em.getTransaction().begin(); + categoriaDao.guardar(celulares); + productoDao.guardar(celular); + //em.persist(celular); + //em.getTransaction().commit(); + em.flush(); + em.clear(); + //em.close(); + */ + + // Acciones por aula + //em.getTransaction().begin(); + + //V1 + /* + em.getTransaction().begin(); + em.persist(celulares); + celulares.setNombre("LAPTOPS"); + em.getTransaction().commit(); + em.close(); + celulares.setNombre("PANTALLAS"); + */ + + //V2 + /* + em.persist(celulares); + celulares.setNombre("LAPTOPS"); + em.flush(); + em.clear(); + + celulares = em.merge(celulares); + celulares.setNombre("PANTALLAS"); + em.flush(); + em.remove(celulares); + */ + + //V3 + /* + em.persist(celulares); + celulares.setNombre("LAPTOPS"); + em.flush(); + em.clear(); + + celulares = em.merge(celulares); + celulares.setNombre("PANTALLAS"); + em.flush(); + //em.clear(); + em.remove(celulares); + em.flush(); + */ + } + + public static void RegistrarProducto() { + Categoria celulares = new Categoria("Celulares"); + Producto celular = new Producto("Samsung", "Teléfono usado", new BigDecimal("1000"), celulares); + EntityManager em = JPAUtils.getEntityManager(); + ProductoDao productoDao = new ProductoDao(em); + CategoriaDao categoriaDao = new CategoriaDao(em); + + em.getTransaction().begin(); + categoriaDao.guardar(celulares); + productoDao.guardar(celular); + em.getTransaction().commit(); + em.close(); + } + +} diff --git a/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/utils/JPAUtils.java b/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/utils/JPAUtils.java new file mode 100644 index 0000000..e9a394b --- /dev/null +++ b/010_spring_boot/jpa/tienda/src/main/java/com/latam/alura/tienda/utils/JPAUtils.java @@ -0,0 +1,14 @@ +package com.latam.alura.tienda.utils; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +public class JPAUtils { + + private static EntityManagerFactory FACTORY = Persistence.createEntityManagerFactory("tienda"); + + public static EntityManager getEntityManager() { + return FACTORY.createEntityManager(); + } +} diff --git a/010_spring_boot/jpa/tienda/src/main/resources/META-INF/persistence.xml b/010_spring_boot/jpa/tienda/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000..de1a6ad --- /dev/null +++ b/010_spring_boot/jpa/tienda/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/010_spring_boot/jpa_persistencia_hibernate.md b/010_spring_boot/jpa_persistencia_hibernate.md new file mode 100644 index 0000000..d9d0fba --- /dev/null +++ b/010_spring_boot/jpa_persistencia_hibernate.md @@ -0,0 +1,264 @@ +# JPA + + + +## Java Persistence API + +[H2 Database Engine](https://mvnrepository.com/artifact/com.h2database/h2/2.2.222) + +### JDBC + +- Especificación para acceso al banco de datos relacional JAVA +- Abstracción del protocolo de comunicación con BD +- Drivers de la BD son implementaciones de JDBC +- Impacto mínimo en la aplicación al cambiar de BD +- Pattern DAO ayuda a aislar el código entre la API y el JDBC + +```mermaid +%%{init: {'theme': 'dark','themeVariables': {'clusterBkg': '#2b2f38'}, 'flowchart': {'curve': 'monotoneY'}}}%% +flowchart +subgraph JDBC +DB[(Base de Datos)] +CS("Controller/Service +(Lógica de Negocios)") +style CS fill:#3f3f3f,stroke:#000,stroke-width:2px +DAO("DAO +(JDBC)") +style DAO fill:#3f3f3f,stroke:#000,stroke-width:2px +CS-->DAO-->DB +end +``` + +Ejemplo + +```java +public class RegistroDeProductoService { + private ProductoDao dao; + + public RegistroDeProductoService(ProductoDao dao) { + this.dao = dao; + } + public void registrarProducto(Producto producto) { + // lógica de negocio + this.dao.registrar(producto); + } +} +``` + +### Desventajas de JDBC + +- Demasiado detalle, muchas lineas de código +- Alto acoplamiento con la BD, cualquier cambio en una parte tiene alto impacto +en otra parte + +### Hibernate + +- Creado en el año 2001 por ***Gavin King*** +- Alternativa a JDBC/EJB 2 +- Posteriormente Gavin King fue contratado por Red Hat + +### JPA + +- Especificación para ORM (Object Relational Mapping) en JAVA +- Lanzada el 2006 +- Versión 2.0 lanzada el 2009 +- Hibernate 3.5.0 (2010) paso a soportar JPA 2 + +```mermaid +%%{init: {'theme': 'dark','themeVariables': {'clusterBkg': '#2b2f38'}, 'flowchart': {'curve': 'monotoneY'}}}%% +flowchart +subgraph " " +direction BT +JP(JPA) +HB(Hibernate) +style HB fill:#3f3f3f,stroke:#000,stroke-width:2px +EL(EclipseLink) +style EL fill:#3f3f3f,stroke:#000,stroke-width:2px +OJP(OpenJPA) +style OJP fill:#3f3f3f,stroke:#000,stroke-width:2px +HB-->JP +EL-->JP +OJP-->JP +end +``` + +JPA es una capa (una abstarcción) se debe usar una biblioteca que la implemente +Existen detalles específicos de Hibernate que dificultan cambiar de implementacion +de JPA. Es recomendable mantenerse dentro del patrón de JPA. + +EclipseLink es la implementación de referencia de JPA. + +pom.xml + +```xml +... + + + + org.apache.plugins + maven-compiler-plugin + 3.11.0 + + ${java.version} + ${java.version} + true + + + + + + + org.hibernate + hibernate-entitymanager + 5.6.15.Final + + + com.h2database + h2 + 2.2.222 + test + + +... +``` + +[/tienda/src/main/resources/META-INF/persistence.xml](./jpa/tienda/src/main/resources/META-INF/persistence.xml) + +```xml + + + + + + + + + + + + +``` + +### Mapeo de entidades + +```mermaid +%%{init: {'theme': 'dark','themeVariables': {'clusterBkg': '#2b2f38'}, 'flowchart': {'curve': 'monotoneY'}}}%% +flowchart +subgraph " " +DB[(Base de Datos)] +EN(Entidades) +style EN fill:#3f3f3f,stroke:#000,stroke-width:2px +subgraph ORM +OR("Tablas == Clases +Columnas == Atributos +Filas == Objetos") +style ORM fill:#3f3f3f,stroke:#000,stroke-width:2px +end +ORM-->EN-->DB +end +``` + +Entidades + +```mermaid +erDiagram + Productos }|--|| Categorias : tiene + Productos { + id bigint PK + Nombre varchar + Descripcion varchar + Precio decimal + categoria_id int FK + } + Categorias { + id biging PK + nombre string + } +``` + +### Ciclo de vida de una entidad en JPA + +```mermaid +%%{init: {'theme': 'dark','themeVariables': {'clusterBkg': '#2b2f38'}, 'flowchart': {'curve': 'linear'}}}%% +flowchart +subgraph " " +NO["operador +new"] +TR(tranciente) +NO-->TR +MG(Managed) +TR-->MG +subgraph " " +RM(removed) +DT(detached) +MG<-->RM +MG<--"close, clear +detach"-->DT +end +direction TB +DB[(Base de Datos)] +MG--"flush, +commit"-->DB +DB--"find, +query"-->MG +end +style DT fill:#3f3f3f,stroke:#000,stroke-width:2px +style RM fill:#3f3f3f,stroke:#000,stroke-width:2px +``` + +#### Estados de una Transacción + +- Transiente +- Managed +**flush()**: permite realizar un rollback. +**commit()**: los cambios son definitivos. +**close()**: cierra el ***EntityManager***. +**clear()**: envia todas las entidades a un estado ***detach*** (ahorro de memoria). +**merge()**: actualiza un registro (primero realiza un select, luego se debe +asignar para su posterior merge, trae un registro al estado *Managed*). +**remove()**: delete registro si tiene estado *managed*. +- Detached +- Removed + +### Consultas JPA + +[ProductoDao.java](./jpa/tienda/src/main/java/com/latam/alura/tienda/dao/ProductoDao.java) + +```java +... + public Producto consultaPorId(Long id) { + return em.find(Producto.class, id); + } + + public List consultarTodos() { + String jpql = "SELECT P FROM Producto AS P"; + return em.createQuery(jpql, Producto.class).getResultList(); + } + + public List consultaPorNombre(String nombre) { + String jpql = "SELECT P FROM Producto AS P WHERE P.nombre=:nombre"; + return em.createQuery(jpql, Producto.class).setParameter("nombre", nombre).getResultList(); + } + + public List consultaPorNombreDeCategoria(String nombre) { + String jpql = "SELECT P FROM Producto AS P WHERE P.categoria.nombre=:nombre"; + return em.createQuery(jpql, Producto.class).setParameter("nombre", nombre).getResultList(); + } + + public BigDecimal consultaPrecioPorNombreDeProducto(String nombre) { + String jpql = "SELECT P.precio FROM Producto AS P WHERE P.nombre=:nombre"; + return em.createQuery(jpql, BigDecimal.class).setParameter("nombre", nombre).getSingleResult(); + } +} +``` + +---- + +Archivos de configuración: + +- [pom.xml](./jpa/tienda/pom.xml) +- [presistence.xml](./jpa/tienda/src/main/resources/META-INF/persistence.xml) diff --git a/README.md b/README.md index 3b7f19c..2784fe1 100644 --- a/README.md +++ b/README.md @@ -47,3 +47,5 @@ primoridiales en programación con Javascript - [Emprendimiento](./009_emprendimiento/) - [Spring Boot](./010_spring_boot/README.md) - [Base de datos](./010_spring_boot/base_de_datos.md) + - [JDBC](./010_spring_boot/jdbc.md) + - [Persistencia con JPA - Hibernate](./010_spring_boot/jpa_persistencia_hibernate.md)