CodeGym /Blog Java /Random-ES /Tu primera aplicación de Hibernate
John Squirrels
Nivel 41
San Francisco

Tu primera aplicación de Hibernate

Publicado en el grupo Random-ES
En este artículo, se familiarizará con uno de los marcos empresariales más populares para Java y creará su primera aplicación de Hibernate. ¿Nunca has oído hablar de Hibernate? ¿O tal vez has oído hablar de él, pero no lo has usado? ¿O tal vez intentaste usarlo, pero fallaste? En los tres casos, bienvenidos a debajo del corte :) Tu primera aplicación de Hibernate - 1 ¡Hola a todos! En este artículo, hablaré sobre las características principales del marco de Hibernate y lo ayudaré a escribir su primera miniaplicación. Para esto, necesitamos:
  1. IntelliJ IDEA Ultimate Edition
    Descárguelo del sitio web oficial y active la versión de prueba de 30 días.
  2. PostgreSQL: uno de los sistemas de administración de bases de datos (DBMS) modernos más populares
  3. Maven (ya conectado a IDEA)
  4. Un poco de paciencia.
Por si acaso, publiqué el código de la aplicación en GitHub (sucursal codegym). El artículo está dirigido principalmente a aquellos que nunca antes han trabajado con esta tecnología, por lo que he minimizado la cantidad de código. ¡Empecemos!

¿Qué es Hibernate?

Es una de las implementaciones de mapeo relacional de objetos (ORM) más populares. Un mapeo relacional de objetos define la relación entre los objetos de software y los registros de la base de datos. Por supuesto, Hibernate tiene una funcionalidad muy amplia, pero nos centraremos en las funciones más sencillas. Nuestro objetivo es crear una aplicación CRUD (Crear, Leer, Actualizar, Eliminar) que sea capaz de:
  1. Cree usuarios (Usuario), búsquelos en la base de datos por ID, actualice sus datos en la base de datos y elimínelos de la base de datos.
  2. Asigne objetos de coche (Auto) a los usuarios. Cree, actualice, busque y elimine automóviles de la base de datos.
  3. Además, la aplicación debería eliminar automáticamente los automóviles "sin propietario" de la base de datos. En otras palabras, cuando se elimina un usuario, todos los automóviles que pertenecen a ese usuario también deben eliminarse de la base de datos.
Nuestro proyecto se estructurará así: Su primera aplicación de Hibernate - 2Como puedes ver, nada complicado. 6 clases + 1 archivo con configuraciones. Primero, cree un nuevo proyecto Maven en IntelliJ IDEA. Archivo -> Nuevo Proyecto. Seleccione Maven entre los tipos de proyectos propuestos y avance al siguiente paso. Su primera aplicación de Hibernate - 3Apache Maven es un marco para crear proyectos automáticamente en función de una descripción de su estructura en archivos POM. Toda la estructura de su proyecto se describirá en pom.xml, un archivo que IDEA mismo creará en la raíz de su proyecto. En la configuración del proyecto, debe especificar la siguiente configuración de Maven: ID de grupo y ID de artefacto. En los proyectos, groupId suele ser una descripción de la empresa o unidad de negocio. El nombre de dominio de la empresa o sitio web puede ir aquí. A su vez, artefactoId es el nombre del proyecto. Para groupdId, puede ingresar com.yourNickname.codegym. Esto no tendrá ningún efecto en la aplicación. Para artefactoId, elija cualquier nombre de proyecto que desee. La versión se puede dejar sin cambios. Su primera aplicación de Hibernate - 4En la última pantalla, simplemente confirme los datos introducidos anteriormente.Tu primera aplicación de Hibernate - 5Entonces, creamos el proyecto. Ahora todo lo que queda por hacer es escribir algo de código y hacer que funcione :) Lo primero es lo primero: si queremos crear una aplicación que funcione con una base de datos, ¡definitivamente no podemos prescindir de una base de datos! Descarga PostgreSQL desde aquí (estoy usando la versión 9). PostgreSQL tiene un usuario predeterminado 'postgres': deberá pensar en una contraseña para él cuando lo instale. No olvides la contraseña. ¡Lo necesitaremos más tarde! (En general, usar la base de datos predeterminada en las aplicaciones es una mala práctica, pero lo haremos para reducir la cantidad de causas de úlceras creando su propia base de datos). Si no eres amigo de la línea de comandos y las consultas SQL, hay buenas noticias. IntelliJ IDEA proporciona una interfaz de usuario totalmente adecuada para trabajar con la base de datos. Su primera aplicación de Hibernate - 6(ubicado en el panel derecho de IDEA, la pestaña Base de datos). Para crear una conexión, haga clic en "+" y seleccione nuestra fuente de datos (PostgeSQL). Complete los campos para el usuario y la base de datos ("postgres" para ambos) e ingrese la contraseña que se configuró durante la instalación de PostgreSQL. Si es necesario, descargue el controlador de Postgres. Puedes hacerlo en la misma página. Haga clic en "Probar conexión" para verificar que se haya establecido la conexión con la base de datos. Si ve "Exitoso", continúe. Ahora vamos a crear las tablas que necesitamos. Habrá un total de dos: usuarios y autos. Parámetros para la tabla de usuarios: Tu primera aplicación de Hibernate - 7tenga en cuenta que id es la clave principal. Si no sabe cuál es la clave principal en SQL, búsquela en Google. Esto es importante. Configuraciones para la tabla de autos: Su primera aplicación de Hibernate - 8Para la tabla de autos, debe configurar una clave externa. Servirá para enlazar nuestras tablas. Te recomiendo que leas más al respecto. En pocas palabras, hace referencia a una tabla externa, en nuestro caso, usuarios. Si un auto pertenece al usuario con id = 1, entonces el campo user_id de los autos será igual a 1. Así es como asociamos a los usuarios con sus autos en nuestra aplicación. En nuestra tabla de autos, el campo user_id actuará como clave externa. Se referirá al campo id de la tabla de usuarios. Su primera aplicación de Hibernate - 9Entonces, hemos creado una base de datos con dos tablas. Lo que queda es entender cómo gestionarlo desde código Java. Comenzaremos con el archivo pom.xml, en el que debemos incluir las bibliotecas necesarias (en Maven se llaman dependencias). Todas las bibliotecas se almacenan en el repositorio central de Maven. Las bibliotecas que especifique en pom.xml están disponibles para que las use en el proyecto. Su pom.xml debería verse así: Tu primera aplicación de Hibernate - 10Nada complicado, como puede ver. Agregamos solo 2 dependencias: para usar PostgreSQL e Hibernate. Ahora pasemos al código Java. Cree todos los paquetes y clases necesarios en el proyecto. Para empezar, necesitamos un modelo de datos: las clases Usery Auto.

 package models;
 
 import javax.persistence.*;
 import java.util.ArrayList;
 import java.util.List;
 
 @Entity
 @Table (name = "users")
 public class User {
 
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private int id;
     @Column(name = "name")
     private String name;
     // You can omit the Column attribute if the name property matches the column name in the table
     private int age;
 
     @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
     private List<Auto> autos;
 
     public User() {
     }
 
     public User(String name, int age) {
         this.name = name;
         this.age = age;
         autos = new ArrayList<>();
     }
 
     public void addAuto(Auto auto) {
         auto.setUser(this);
         autos.add(auto);
     }
 
     public void removeAuto(Auto auto) {
         autos.remove(auto);
     }
 
     public int getId() {
         return id;
     }
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         this.name = name;
     }
 
     public int getAge() {
         return age;
     }
 
     public void setAge(int age) {
         this.age = age;
     }
 
     public List<Auto> getAutos() {
         return autos;
     }
 
     public void setAutos(List<Auto> autos) {
         this.autos = autos;
     }
 
     @Override
     public String toString() {
         return "models.User{" +
                 "id=" + id +
                 ", name='" + name + '\'' +
                 ", age=" + age +
                 '}';
     }
 }
 
 

 package models;
 
 import javax.persistence.*;
 
 @Entity
 @Table(name = "autos")
 public class Auto {
 
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private int id;
 
     @Column (name = "model")
     private String model;
 
     // You can omit the Column attribute if the name property matches the column name in the table
     private String color;
 
 
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "user_id")
     private User user;
 
     public Auto() {
     }
 
     public Auto(String model, String color) {
         this.model = model;
         this.color = color;
     }
 
     public int getId() {
         return id;
     }
 
     public String getModel() {
         return model;
     }
 
     public void setModel(String model) {
         this.model = model;
     }
 
     public String getColor() {
         return color;
     }
 
     public void setColor(String color) {
         this.color = color;
     }
 
     public User getUser() {
         return user;
     }
 
     public void setUser(User user) {
         this.user = user;
     }
 
     @Override
     public String toString() {
         return color + " " + model;
     }
 }
 
 
Como puede ver, las clases tienen un montón de anotaciones oscuras. Comencemos a profundizar en ellos. Para nosotros, la anotación principal es @Entity. Léalo en Wikipedia y apréndalo todo de memoria. Este es el fundamento de la fundación. Esta anotación permite que los objetos de su clase Java se asignen a una base de datos. Para que una clase sea una entidad, debe cumplir con los siguientes requisitos:
  • Debe tener un constructor vacío ( publico protected)
  • No se puede anidar, una interfaz o unenum
  • No puede ser finaly no puede tener finalcampos/propiedades
  • Debe tener al menos un campo @Id.
Revisa las clases de tu entidad: son lugares muy populares para pegarte un tiro en el pie. Es muy fácil olvidar algo. Además, una entidad puede hacer lo siguiente:
  • Puede tener constructores no vacíos.
  • Se puede heredar y ser heredado.
  • Puede tener otros métodos e implementar interfaces.
Como puede ver, la Userclase es muy similar a la tabla de usuarios. tiene id, nameyagecampos. Las anotaciones ubicadas encima de ellos no necesitan ninguna explicación en particular: está claro que @Id indica que el campo es un identificador de objetos de esta clase. La anotación @Table sobre la clase indica el nombre de la tabla donde se escriben los objetos. Tenga en cuenta el comentario sobre el campo de edad: si el nombre del campo en la clase es el mismo que el nombre de la tabla, puede omitir la anotación @Column y funcionará. En cuanto a la parte indicada entre llaves ("strategy = GenerationType.IDENTITY"): existen varias estrategias para generar IDs. Puede buscarlos en Google, pero para nuestra aplicación, no hay necesidad de molestarse. Lo principal es que para nuestros objetos el valor de id se generará automáticamente. En consecuencia, no hay setter para id, y tampoco lo establecemos en el constructor. Sin embargo,Userla clase se destaca. ¡Tiene una lista de autos! Su primera aplicación de Hibernate - 11La anotación @OneToMany cuelga sobre la lista. Significa que varios coches pueden corresponder a un mismo objeto de la clase Usuario. El elemento "mappedBy" se refiere al campo de usuario de la Autoclase. Así, coches y usuarios están relacionados. El elemento orphanRemoval indica si aplicar la operación de eliminación a entidades que ya no tienen una relación. Si eliminamos un usuario de la base de datos, también se eliminarán todos los automóviles asociados con él. A su vez, en elAutoclase, verá el campo de usuario con la anotación @ManyToOne (un Usuario puede corresponder a muchos Autos) y la anotación @JoinColumn. Indica qué columna en la tabla de autos se usa para hacer referencia a la tabla de usuarios (es decir, la clave externa de la que hablamos anteriormente). Después de crear el modelo de datos, es hora de enseñar a nuestro programa a realizar operaciones con los datos de la base de datos. Comencemos con la clase de utilidad HibernateSessionFactoryUtil. Solo tiene un trabajo: crear una fábrica de sesiones para que nuestra aplicación funcione con la base de datos (¡salude al patrón de diseño Factory!). No sabe hacer otra cosa.

 package utils;
 
 import models.Auto;
 import models.User;
 import org.hibernate.SessionFactory;
 import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
 import org.hibernate.cfg.Configuration;
 
 public class HibernateSessionFactoryUtil {
     private static SessionFactory sessionFactory;
 
     private HibernateSessionFactoryUtil() {}
 
     public static SessionFactory getSessionFactory() {
         if (sessionFactory == null) {
             try {
                 Configuration configuration = new Configuration().configure();
                 configuration.addAnnotatedClass(User.class);
                 configuration.addAnnotatedClass(Auto.class);
                 StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
                 sessionFactory = configuration.buildSessionFactory(builder.build());
 
             } catch (Exception e) {
                 System.out.println("Исключение!" + e);
             }
         }
         return sessionFactory;
     }
 }
 
En esta clase, creamos un nuevo objeto de configuración y le pasamos las clases que debe tratar como entidades: Usery Auto. Presta atención al configuration.getProperties()método. ¿Qué otras propiedades hay? ¿De dónde vienen? Las propiedades son las configuraciones de hibernación indicadas en el archivo hibernate.cfg.xml especial. Su primera aplicación de Hibernate - 12Hibernate.cfg.xml se lee aquí: new Configuration().configure(); Como puede ver, no tiene nada de especial: contiene los parámetros para conectarse a la base de datos, así como el parámetro show_sql. Esto es necesario para que todas las consultas sql ejecutadas por Hibernate se muestren en la consola. De esta manera, verá exactamente lo que Hibernate está haciendo en un momento dado, eliminando cualquier sentido de "magia". A continuación necesitamos elUserDAOclase. La mejor práctica es programar a través de las interfaces: cree una UserDAOinterfaz e UserDAOImplimplementación separadas, pero omitiré esto para reducir la cantidad de código. ¡No hagas esto en proyectos reales! El patrón de diseño DAO (objeto de acceso a datos) es uno de los más comunes. La idea es simple: crear una capa de aplicación responsable solo de acceder a los datos, nada más. Obtener datos de la base de datos, actualizar datos, eliminar datos, eso es todo. Estudia más sobre DAO. Utilizará objetos de acceso a datos constantemente en su trabajo. ¿ Qué puede hacer nuestra UserDaoclase? Bueno, como todos los DAO, solo puede funcionar con datos. Encuentre un usuario por ID, actualice sus datos, elimínelo, obtenga una lista de todos los usuarios de la base de datos o guarde un nuevo usuario en la base de datos: esa es la totalidad de su funcionalidad.

 package dao;
 
 import models.Auto;
 import models.User;
 import org.hibernate.Session;
 import org.hibernate.Transaction;
 import utils.HibernateSessionFactoryUtil;
 import java.util.List;
 
 public class UserDao {
 
     public User findById(int id) {
         return HibernateSessionFactoryUtil.getSessionFactory().openSession().get(User.class, id);
     }
 
     public void save(User user) {
         Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
         Transaction tx1 = session.beginTransaction();
         session.save(user);
         tx1.commit();
         session.close();
     }
 
     public void update(User user) {
         Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
         Transaction tx1 = session.beginTransaction();
         session.update(user);
         tx1.commit();
         session.close();
     }
 
     public void delete(User user) {
         Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
         Transaction tx1 = session.beginTransaction();
         session.delete(user);
         tx1.commit();
         session.close();
     }
 
     public Auto findAutoById(int id) {
         return HibernateSessionFactoryUtil.getSessionFactory().openSession().get(Auto.class, id);
     }
 
     public List<User> findAll() {
         List<User> users = (List<User>) HibernateSessionFactoryUtil.getSessionFactory().openSession().createQuery("From User").list();
         return users;
     }
 }
 
UserDaoLos métodos de son similares entre sí. En la mayoría de ellos, obtenemos un objeto Session (sesión de conexión a la base de datos) usando nuestra Session Factory, creamos una sola transacción dentro de esta sesión, realizamos las manipulaciones de datos necesarias, guardamos el resultado de la transacción en la base de datos y luego cerramos la sesión. Los métodos en sí, como puede ver, son bastante simples. DAO es el "corazón" de nuestra aplicación. Sin embargo, no crearemos un DAO directamente ni llamaremos a sus métodos en nuestro main()método. Toda la lógica se moverá a la UserServiceclase.

 package services;
 
 import dao.UserDao;
 import models.Auto;
 import models.User;
 
 import java.util.List;
 
 public class UserService {
 
     private UserDao usersDao = new UserDao();
 
     public UserService() {
     }
 
     public User findUser(int id) {
         return usersDao.findById(id);
     }
 
     public void saveUser(User user) {
         usersDao.save(user);
     }
 
     public void deleteUser(User user) {
         usersDao.delete(user);
     }
 
     public void updateUser(User user) {
         usersDao.update(user);
     }
 
     public List<User> findAllUsers() {
         return usersDao.findAll();
     }
 
     public Auto findAutoById(int id) {
         return usersDao.findAutoById(id);
     }
 
 
 }
 
 
Un servicio es una capa de datos de aplicación responsable de ejecutar la lógica empresarial. Si su programa necesita ejecutar algún tipo de lógica comercial, lo hace a través de servicios. Un servicio contiene UserDaoy llama métodos DAO en sus métodos. Puede parecer que estamos duplicando funciones aquí (¿por qué no simplemente llamar a los métodos desde un objeto DAO?), pero con muchos objetos y una lógica compleja, la aplicación en capas proporciona enormes ventajas (es una buena práctica; recuerde esto en el futuro y lea sobre "capas de aplicación"). Nuestro servicio tiene una lógica simple, pero los métodos de servicio en proyectos del mundo real contienen mucho más que una línea de código :) ¡Ahora tenemos todo lo que necesita para ejecutar la aplicación! En el main()método, vamos a crear un usuario y su automóvil, asociar uno con el otro y guardarlos en la base de datos.

 import models.Auto;
 import models.User;
 import services.UserService;
 
 import java.sql.SQLException;
 
 public class Main {
     public static void main(String[] args) throws SQLException {
 
         UserService userService = new UserService();
         User user = new User ("Jenny", 26);
         userService.saveUser(user);
         Auto ferrari = new Auto("Ferrari", "red");
         ferrari.setUser(user);
         user.addAuto(ferrari);
         Auto ford = new Auto("Ford", "black");
         ford.setUser(user);
         user.addAuto(ford);
         userService.updateUser(user);
     }
 }
 
 
Como puede ver, la tabla de usuarios tiene su propio registro y la tabla de autos tiene su propio registro. Su primera aplicación de Hibernate - 13Su primera aplicación de Hibernate - 14Intentemos cambiar el nombre de nuestro usuario. Limpia la tabla de usuarios y ejecuta el código.

 import models.Auto;
 import models.User;
 import services.UserService;
 
 import java.sql.SQLException;
 
 public class Main {
     public static void main(String[] args) throws SQLException {
 
         UserService userService = new UserService();
         User user = new User ("Jenny", 26);
         userService.saveUser(user);
         Auto ferrari = new Auto("Ferrari", "red");
         user.addAuto(ferrari);
         Auto ford = new Auto("Ford", "black");
         ford.setUser(user);
         user.addAuto(ford);
         userService.updateUser(user);
         user.setName ("Benny");
         userService.updateUser(user);
     }
 }
 
 
¡Funciona! Tu primera aplicación de Hibernate - 15¿Qué pasa si eliminas al usuario? Borre la tabla de usuarios (los autos se borrarán solos) y ejecute el código

 import models.Auto;
 import models.User;
 import services.UserService;
 
 import java.sql.SQLException;
 
 public class Main {
     public static void main(String[] args) throws SQLException {
 
         UserService userService = new UserService();
         User user = new User ("Jenny", 26);
         userService.saveUser(user);
         Auto ferrari = new Auto("Ferrari", "red");
         user.addAuto(ferrari);
         Auto ford = new Auto("Ford", "black");
         ford.setUser(user);
         user.addAuto(ford);
         userService.updateUser(user);
         user.setName ("Benny");
         userService.updateUser(user);
         userService.deleteUser(user);
     }
 }
 
 
Y nuestras tablas están completamente vacías (preste atención a la consola: todas las solicitudes realizadas por Hibernate se mostrarán allí). Puedes jugar con la aplicación y probar todas sus funciones. Por ejemplo, cree un usuario con automóviles, guárdelo en la base de datos, mire la identificación asignada al usuario e intente usar esta identificación en elmain()método para obtener al usuario de la base de datos y mostrar una lista de sus autos en la consola. Por supuesto, solo hemos visto una pequeña parte de la funcionalidad de Hibernate. Sus capacidades son muy amplias y durante mucho tiempo ha sido una herramienta estándar de la industria para el desarrollo de Java. Si quieres estudiarlo en detalle, te puedo recomendar el libro "API de Persistencia de Java e Hibernate". Revisé en un artículo anterior. Espero que este artículo haya sido útil para los lectores. Si tienes preguntas, hazlas en los comentarios. Estaré encantado de responder :) Además, no olvides apoyar al autor en el concurso publicando un "Me gusta". O mejor aún: "Me encanta" :) ¡Buena suerte en tus estudios!
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION