Vamos a realizar un pequeño CRUD utilizando Hibernate partiendo de la BD que hicimos en el tema de configuración. Como hemos podido observar el Framework nos ha realizado las clases principales del modelo.

Ahora siguiendo los patrones aprendidos (MVC-DAO-SINGLETON) vamos a crear las clases conectoras y generar los métodos básicos para la gestión de un CRUD de nuestros refrescos. Veamos nuestro diagrama de clases y planteamos nuestros DAO, en un principio pondremos un insertar, update, delete y un obtener por id ademas de la lista completa de objetos.

Para entender mejor la codificación vamos a realizarla inicialmente de una sola clase, la de Refrescos y generar su Clase Dao con los métodos de Hibernate.
La base de datos ya la tenemos creada y conectada del paso anterior así como la clase del modelo, repasemos la estructura de nuestro proyecto.

Podemos ver claramente como tenemos dos paquetes que pertenecen al Modelo (MVC), las propias clases que definen los datos (modelo) y hemos creado otro llamado (dao) para las clases conectoras.
Aplicando el patron Singleton que vimos en unidades anteriores hemos creado una clase Conexion.java estática para poder conectarnos desde cualquier parte del programa.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package dao; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class Conexion { private static SessionFactory sesion; static { sesion = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory(); } public static SessionFactory getSession() { return sesion; } } |
Vemos que el código es bastante simple aunque mas abstracto que el caso de usar directamente JDBC como en la unidad anterior. creando un objeto Configuration de Hibernate y haciendo referencia al archivo de xml de configuración es suficiente.
|
1 |
sesion = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory() |
El siguiente paso es insertar los métodos CRUD de nuestra clase Dao, empecemos por el insertar.
Clase Dao (insertar)
|
1 2 3 4 5 6 7 8 9 10 11 |
public static void insertar(Refresco r) { Session sesion = Conexion.getSession().openSession(); Transaction tx = sesion.beginTransaction(); sesion.save(r); tx.commit(); sesion.close(); } |
En en método vemos cómo creamos el objeto de la sesión y llamamos al metodo save(r) que es el encargado de hacer la inserción en la base datos. Es importante señalar que el metodo que realiza la ejecución es el comit de la transaction (tx.commit()).
Los métodos de update y delete son muy similares, dado que no recibimos nada (se esta omitiendo cualquier tipo de control de errores).
Clase Dao (update)
|
1 2 3 4 5 6 7 8 9 10 11 12 |
public static void update(Refresco r) { Session sesion = Conexion.getSession().openSession(); Transaction tx = sesion.beginTransaction(); sesion.update(r); tx.commit(); sesion.close(); } |
Clase Dao (delete)
|
1 2 3 4 5 6 7 8 9 10 11 12 |
public static void delete(Refresco r) { Session sesion = Conexion.getSession().openSession(); Transaction tx = sesion.beginTransaction(); sesion.delete(r); tx.commit(); sesion.close(); } |
Para la obtención de resultados es igualmente simple. Para obtener un solo resultado utilizaremos el metodo get, indicando la clase y el identificador del elemento que queremos recuperar.
Clase Dao (obtener por id)
|
1 2 3 4 5 6 7 8 9 |
public static Refresco obtener(int id) { Session sesion = Conexion.getSession().openSession(); Transaction tx = sesion.beginTransaction(); Refresco res = sesion.get(Refresco.class, id); tx.commit(); sesion.close(); return res; } |
Este método ya nos retorno un objeto tipo Refresco con el que podemos trabajar.
Clase Dao (obtener todos)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public static List<Refresco> obtenerListado() throws IOException, SQLException{ Session sesion = Conexion.getSession().openSession(); Transaction tx = sesion.beginTransaction(); //Forma deprecate //List<Refresco> res = (List<Refresco>) sesion.createCriteria(Refresco.class).list(); //Forma posterior CriteriaQuery<Refresco> cq = sesion.getCriteriaBuilder().createQuery(Refresco.class); cq.from(Refresco.class); List<Refresco> res = sesion.createQuery(cq).getResultList(); tx.commit(); sesion.close(); return res; } |
Clase Dao (Búsqueda)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public static List<Refresco> obtenerListadoPorNombreOpcion(String nombre) throws IOException, SQLException{ Session sesion = Conexion.getSession().openSession(); Transaction tx = sesion.beginTransaction(); Query consulta = sesion.createQuery("from Refresco where nombre = :nombre"); consulta.setParameter("nombre", nombre); List<Refresco> res = consulta.getResultList(); tx.commit(); sesion.close(); return res; } |
Podemos observar que es similar al método que usamos para listar todo, pero en este caso utilizamos la creación de una query donde le indicamos lo que debe buscar mediante un parametro, con setParameter().
|
1 2 |
Query consulta = sesion.createQuery("from Refresco where nombre = :nombre"); consulta.setParameter("nombre", nombre); |
Y en en el modelo ya solo tenemos que llamar al método correspondiente del Dao.
Clase Refresco
|
1 2 3 |
public void insertar() throws IOException, SQLException { daoRefrescos.insertar(this); } |
Mapeo
En Hibernate tenemos dos formas de realizar el mapeo para que relacione los campos de las tablas con los atributos de los objetos.
Ya hemos visto en la lección anterior como la utilidad de Code Generation de hibernate nos crea las clase y los archivos xml de cada una de las clases.
Con anotaciones
Otra forma de indicar a Hibernata que es cada cosa, es por medio de anotaciones, tanto a los atributos como a la clase.
Las anotaciones básicas que debemos de añadir son:
@Entity: Indica que la clase es una Entidad (que tiene una tabla asociada)
@Table(name=»tabla»): Indica el nombre de la tabla asociada.
@Id: Identifica el atributo como PK.
@Column(name=»campo»): Asocia cada atributo con el nombre del campo, si como en este caso es el mismo, bastaría con poner @Column sin ningun parametro.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@Entity @Table(name="refrescos") public class Refrescos implements java.io.Serializable { @Id @Column(name="id") private Integer id; @Column(name="nombre") private String nombre; @Column(name="tamano") private Integer tamano; @Column(name="sabor") private Integer sabor; @Column(name="marca") private Integer marca; @Column(name="propiedades") private String propiedades; |
Probamos que todo funciona, en este caso en el controlador haremos un objeto y probamos la inserción.
NOTA:
Con el XML
Es posible que necesitemos modificar el archivo de configuración (hibernate.cfg.xml) mapeando las clases, este método aunque sigue siendo funcional esta desaprobado en favor de las anotaciones del ejemplo anterior. De esta forma:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory name="ConexionHibernate"> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.password">1234</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/nevera</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.search.autoregister_listeners">true</property> <property name="hibernate.validator.apply_to_ddl">false</property> <mapping resource="modelo/Refrescos.hbm.xml"/> <mapping resource="modelo/Sabores.hbm.xml"/> <mapping resource="modelo/Marca.hbm.xml"/> </session-factory> </hibernate-configuration> |
Podemos ver como le hemos añadido las etiquetas mapping indicando donde se encuentran los archivos xml de cada clase.
Las clases de mi aplicación
Clase Main
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public static void main(String[] args) throws IOException, SQLException { // TODO Auto-generated method stub Refresco r1 = new Refresco(); r1.setMarca(1); r1.setNombre("Naranjon"); r1.setPropiedades("Energía, Refrescante"); r1.setSabor(1); r1.setTamano(3); System.out.println(r1.toString()); r1.insertar(); } |
Podemos comprobar como realiza la inserción en la tabla.

A continuación tienes el código de las clases de el CRUD completo.
Clase Refresco
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
package modelo; import java.io.IOException; import java.sql.SQLException; import org.hibernate.Session; import org.hibernate.Transaction; import dao.Conexion; import dao.DaoRefrescos; // Generated 19 ene. 2021 10:25:12 by Hibernate Tools 5.4.21.Final /** * Refrescos generated by hbm2java */ public class Refresco implements java.io.Serializable { private Integer id; private String nombre; private Integer tamano; private Integer sabor; private Integer marca; private String propiedades; public Refresco() { } public Refresco(String nombre, Integer tamano, Integer sabor, Integer marca, String propiedades) { this.nombre = nombre; this.tamano = tamano; this.sabor = sabor; this.marca = marca; this.propiedades = propiedades; } public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } public String getNombre() { return this.nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public Integer getTamano() { return this.tamano; } public void setTamano(Integer tamano) { this.tamano = tamano; } public Integer getSabor() { return this.sabor; } public void setSabor(Integer sabor) { this.sabor = sabor; } public Integer getMarca() { return this.marca; } public void setMarca(Integer marca) { this.marca = marca; } public String getPropiedades() { return this.propiedades; } public void setPropiedades(String propiedades) { this.propiedades = propiedades; } public void insertar() throws IOException, SQLException { DaoRefrescos.insertar(this); } public void update() throws IOException, SQLException { DaoRefrescos.update(this); } public void delete() throws IOException, SQLException { DaoRefrescos.delete(this); } public void obtenerPorId(int id) throws IOException, SQLException{ Refresco aux = DaoRefrescos.obtener(id); this.id = aux.getId(); this.marca = aux.getMarca(); this.nombre = aux.getNombre(); this.propiedades = aux.getPropiedades(); this.tamano = aux.getTamano(); System.out.println(this); } @Override public String toString() { return "Refrescos [id=" + id + ", nombre=" + nombre + ", tamano=" + tamano + ", sabor=" + sabor + ", marca=" + marca + ", propiedades=" + propiedades + "]"; } } |
Clase conexión
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package dao; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class Conexion { private static SessionFactory sesion; static { sesion = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory(); } public static SessionFactory getSession() { return sesion; } } |
Clase DaoRefresco
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
package dao; import java.io.IOException; import java.sql.SQLException; import java.util.Iterator; import java.util.List; import javax.persistence.Query; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.criterion.Expression; import modelo.Refresco; public class DaoRefrescos { public static void insertar(Refresco r)throws IOException, SQLException{ Session sesion = Conexion.getSession().openSession(); Transaction tx = sesion.beginTransaction(); sesion.save(r); tx.commit(); sesion.close(); } public static void update(Refresco r) throws IOException, SQLException { Session sesion = Conexion.getSession().openSession(); Transaction tx = sesion.beginTransaction(); sesion.update(r); tx.commit(); sesion.close(); } public static void delete(Refresco r) throws IOException, SQLException { Session sesion = Conexion.getSession().openSession(); Transaction tx = sesion.beginTransaction(); sesion.delete(r); tx.commit(); sesion.close(); } public static Refresco obtener(int id) throws IOException, SQLException { Session sesion = Conexion.getSession().openSession(); Transaction tx = sesion.beginTransaction(); Refresco res = sesion.get(Refresco.class, id); tx.commit(); sesion.close(); return res; } public static List<Refresco> obtenerListado() throws IOException, SQLException{ Session sesion = Conexion.getSession().openSession(); Transaction tx = sesion.beginTransaction(); //Forma deprecate //List<Refresco> res = (List<Refresco>) sesion.createCriteria(Refresco.class).list(); //Forma posterior CriteriaQuery<Refresco> cq = sesion.getCriteriaBuilder().createQuery(Refresco.class); cq.from(Refresco.class); List<Refresco> res = sesion.createQuery(cq).getResultList(); tx.commit(); sesion.close(); return res; } public static List<Refresco> obtenerListadoPorNombreOpcion(String nombre) throws IOException, SQLException{ Session sesion = Conexion.getSession().openSession(); Transaction tx = sesion.beginTransaction(); Query consulta = sesion.createQuery("from Refresco where nombre = :nombre"); consulta.setParameter("nombre", nombre); List<Refresco> res = consulta.getResultList(); tx.commit(); sesion.close(); return res; } } |
Y ahora la clase main donde probamos los diferentes métodos comentando lo que no queremos que se ejecute en cada momento.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
package controlador; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import dao.DaoRefrescos; import modelo.Refresco; public class Principal { public static void main(String[] args) throws IOException, SQLException { // TODO Auto-generated method stub //Ejecución insertar /* Refrescos r1 = new Refrescos(); r1.setMarca(1); r1.setNombre("coquequelo2"); r1.setPropiedades("Persistentes, saludable"); r1.setSabor(1); r1.setTamano(3); System.out.println(r1.toString()); r1.insertar(); */ //Ejecución Update /* Refrescos r2 = new Refrescos(); r2.setId(9); r2.setMarca(1); r2.setNombre("DawFresas 2"); r2.setPropiedades("Salado, saludable"); r2.setSabor(1); r2.setTamano(3); System.out.println(r2.toString()); r2.update(); */ //obtener por ID /* Refrescos r3 = new Refrescos(); r3.obtenerPorId(11); */ //Delete (recibir primero) /* r3.delete(); */ //Ver todos /* List<Refresco> lista = DaoRefrescos.obtenerListado(); for (Refresco r : lista) { System.out.println(r.toString()); } */ //Buscar por nombre List<Refresco> lista = DaoRefrescos.obtenerListadoPorNombreOpcion("Cerecero"); for (Refresco r : lista) { System.out.println(r.toString()); } } } |
¡Y Listo!