Persistencia de los datos con Hibernate y Spring Okta.

Los desarrolladores de Java generalmente tienen la necesidad de almacenar datos de forma regular. Si lleva más de 15 años desarrollando, probablemente recuerde los días de JDBC en Java. Usar JDBC puede ser tedioso si no te gusta escribir SQL. No solo eso, sino que no hay nada en JDBC que te ayude a crear tu base de datos. Hibernate llegó y cambió todo permitiéndole mapear los pojos (objetos sin formato de Java) a las tablas de la base de datos. No fue un ataque de ansiedad severo en perros, solo eso, pero tenía una API muy java que facilitaba la creación de pojos CRUD. Poco después, llegó la primavera y agregó abstracciones para hibernación que llevaron a la simplificación de la API aún más. Avance al día de hoy, y la mayoría de las aplicaciones java utilizan tanto Spring como Hibernate.


Desde hace algún tiempo, los desarrolladores han operado bajo uno de dos modelos separados pero distintos para representar entidades comerciales. El modelo relacional, que prevalece en las bases de datos, y el modelo orientado a objetos. Estos dos modelos son similares en que ambos trabajan con estructuras similares para representar la lógica empresarial, y son distintos en el sentido de que fueron diseñados para diferentes propósitos: uno para almacenar datos y otro para describir el comportamiento. Utiliza hibernate a la antigua usanza, sin primavera.

Con el advenimiento de la hibernación (y muchas herramientas similares), el equipo java EE decidió proponer un nuevo patrón para guiar los marcos ORM utilizando encéphalopathie post anoxique définition en un solo idioma. La JPA (API de persistencia de Java) se creó y se define completamente como anotaciones de Java (además de XML) que aumentan la legibilidad y la capacidad de mantenimiento del código. A continuación se muestra un ejemplo de un mapeo basado en XML de la escuela principal y un mapeo basado en anotaciones más actual para la misma entidad.

Paquete neto. Dovale. Entidades; import javax.Persistence. *; @entity public class course {@id @generatedvalue (strategy = generationtype. AUTO) private id largo; nombre de cadena privada; carga de trabajo privada int; tasa de int privado; @manytoone @joincolumn (foreignkey = @foreignkey (name = "fk_course_teacher" )) profesor privado profesor; curso público () {} curso público (nombre de cadena, carga de trabajo int, tasa int, profesor maestro) {esto. Nombre = nombre; esta . Carga de trabajo = carga de trabajo; esta . Tasa = tasa; esta . Maestro = maestro; } // (…) getter y setters (…)}

Como puede ver, hay una anotación @manytooneand y @joincolumn. Esas anotaciones representan, como su nombre lo indica, una relación de muchos a uno (cuando una sola entidad tiene muchas relaciones con otra entidad). La anotación @joincolumn especifica que la relación debe ser realizada por una columna en una entidad (curso, en este caso) y @foreignkey especifica el nombre de la restricción. Siempre recomiendo especificar el nombre de la clave externa para ayudar a la depuración.

Paquete neto. Dovale. Dao importar org.Hibernate.Session; importar org.Hibernate.SessionFactory; import javax.Persistence.Criteria.CriteriaQuery; import java.Util.List; clase abstracta pública abstractcruddao {sesión final privadafactorial sesionaria; clase final privada clase clase anoxia cerebral causa; cadena privada final nombre de entidad; protegido abstractcruddao (sessionfactory sessionfactory, class entityclass, string entityname) {esto. SessionFactory = sessionfactory; esta . EntityClass = entityclass; esta . EntityName = nombre de entidad; } guardar T público (entidad T) {sessionfactory. GetCurrentSession (). Guardar (entidad); entidad de retorno } eliminar el vacío público (entidad T) {sessionfactory. GetCurrentSession (). Eliminar (entidad); } public T find (ID larga) {return sessionfactory. GetCurrentSession (). Encuentra (entityclass, id); } lista de la lista pública () {session session = sessionfactory. GetCurrentSession (); Consulta de criterios = sesión. GetCriteriaBuilder (). CreateQuery (entityclass); consulta . Seleccione (consulta. De (entityclass)); sesión de retorno CreateQuery (consulta). GetResultList (); }}

Hibernate utiliza una abstracción de sesión para comunicarse con la base de datos y convertir objetos en relaciones y viceversa. El marco también introduce su propio lenguaje de consulta llamado HQL (lenguaje de consulta de hibernación). En el código anterior, HQL está representado en el método de lista. Lo bueno de HQL es que está consultando objetos y no tablas y relaciones. El motor de consulta de hibernación se convertirá a SQL internamente.

ACID (atomic consistente durable) es una característica clave de la base de datos relacional. Garantiza la coherencia entre los datos insertados a través de transacciones. En otras palabras: si está ejecutando neuropatología y mecanismos de una transacción de lesión cerebral isquémica hipóxica, todas sus operaciones son atómicas y no están influenciadas por otras operaciones que pueden ejecutarse en la misma base de datos, al mismo tiempo. Para lograr esto completamente, hibernate también tiene una abstracción de transacción. El código en net.Dovale.Application muestra cómo funciona:

Paquete neto. Dovale; importar net.Dovale.Dao. *; import net.Dovale.Entities. *; importar org.Hibernate. *; importar org.Hibernate.Boot.MetadataSources; importar org.Hibernate.Boot.Registry.StandardServiceRegistry; importar org.Hibernate.Boot.Registry.StandardServiceRegistryBuilder; aplicación de clase pública {public static void main (string [] args) {standardserviceregistry registry = new standardserviceregistrybuilder (). Configurar (). Construir (); try (sessionfactory sessionfactory = new metadatasources (registry). BuildMetadata (). BuildSessionFactory ()) {coursedao coursedao = new coursedao (sessionfactory); teacherdao teacherdao = new teacherdao (sessionfactory); try (session session = sessionfactory. GetCurrentSession ()) {transaction tx = session. BeginTransaction (); // crea docentes profesora pj = teacherdao. Guardar (nuevo maestro ( "profesor jirafales" , "https://upload.Wikimedia.Org/wikipedia/commons/thumb/d/d1/ruben2017.Jpg/245px-ruben2017.Jpg" , "jirafales@example.Com" )); maestro px = teacherdao. Guardar (nuevo maestro ( "profesor plexo ansiedad testimonios x" , "https://encrypted-tbn0.Gstatic.Com/images?Q=tbn:and9gcs9ui1cb-nq2ujoph4_t96krvlsmjczaknhljyi1nqwxagvqwc4" , "director@xproject_.Com" )); coursedao. Guardar (nuevo curso ( "matemáticas" , 20, 10, pj)); coursedao. Guardar (nuevo curso ( "Español" , 20, 10, pj)); coursedao. Guardar (nuevo curso ( "tratar con desconocido" , 10, 100, px)); coursedao. Guardar (nuevo curso ( "manejando tu poder mental" , 50, 100, px)); coursedao. Guardar (nuevo curso ( "Introducción a la Psicología" , 90, 100, px)); tx Commit (); } try (sesión sesion anoxica convulsion sintoma = sesion de sesion. GetCurrentSession ()) {sesion. BeginTransaction (); sistema Fuera . Println ( "cursos" ); coursedao. Lista (). ForEach (curso -> sistema Fuera . Println (curso. GetName ())); sistema Fuera . Println ( "maestros" ); profesora Lista (). Para cada profesor> sistema Fuera . Println (teacher. GetName ())); }}}}

Esta clase crea algunos datos para nuestra base de datos de ejemplo, y todos los datos se insertan utilizando la misma transacción: si se produce un error, todos los datos se borran antes de que cualquier usuario pueda consultarlos. Para implementar esto correctamente en hibernación sin formato, llamamos session.BeginTransaction () y session.CommitTransaction (). También es importante llamar a sessionfactory.GetCurrentSession () y no sessionfactory.OpenSession () para usar la misma sesión en toda la operación.

Paquete neto. Dovale. Okta. Springhibernate. Primavera . Servicios; importar net.Dovale.Okta.Springhibernate.Spring.Dao. *; import net.Dovale.Okta.Springhibernate.Spring.Entities. *; importar org.Springframework.Beans.Factory.Annotation.Autowired; importar org.Springframework.Stereotype.Service; importar org.Springframework.Transaction.Annotation.Transactional; importar javax.Annotation.PostConstruct; @service public class datafillerservice {private final coursedao coursedao; profesorado final privado profesoradoo; @autowired public datafillerservice (coursedao coursedao, teacherdao teacherdao) {esto. CursoDao = coursedao; esta . TeacherDao = teacherdao; } @postconstruct @transactional public void filldata () {teacher pj = new teacher ( "profesor jirafales" , "https://upload.Wikimedia.Org/wikipedia/commons/thumb/d/d1/ruben2017.Jpg/245px-ruben2017.Jpg" , "jirafales@example.Com" ); maestro px = nuevo maestro ( "profesor x" , "https://encrypted-tbn0.Gstatic.Com/images?Q=tbn:and9gcs9ui1cb-nq2ujoph4_t96krvlsmjczaknhljyi1nqwxagvqwc4" , "director@xproject_.Com" ); profesora Guardar (pj); profesora Guardar (px); coursedao. Guardar (nuevo curso ( "matemáticas" , 20, (corto) 10, pj)); coursedao. Guardar (nuevo curso ( "Español" , 20, (corto) 10, pj)); coursedao. Guardar (nuevo curso ( "tratar con desconocido" , 10, (corto) 100, pj)); coursedao. Guardar (nuevo curso ( "manejando tu poder mental" , 50, (corto) 100, pj)); coursedao. Ahorro (nuevo curso de pronóstico de lesión cerebral axonal difusa ( "Introducción a la Psicología" , 90, (corto) 100, pj)); }}

¿Ves lo limpio que es tu código en comparación con el proyecto en bruto? Esto sucede porque solo tiene una preocupación: mantener el código de su negocio sanamente. Mientras estuvo en su proyecto en bruto tuvo que manejar sesiones y transacciones, aquí solo necesitamos agregar una anotación transaccional para mantener la ejecución completa del método dentro de una transacción de base de datos. Además, @postconstruct le dice a la primavera que este método debe pronosticarse después de invocar una lesión cerebral anóxica después de que el contexto esté completamente cargado.

Paquete neto. Dovale. Okta. Springhibernate. Primavera ; importar org.Springframework.Boot.SpringApplication; importar org.Springframework.Boot.Autoconfigure.SpringBootApplication; importar org.Springframework.Context.Annotation.Configuration; importar org.Springframework.Security.Config.Annotation.Method.Configuration.EnableGlobalMethodSecurity; importar org.Springframework.Security.Config.Annotation.Web.Builders.HttpSecurity; importar org.Springframework.Security.Config.Annotation.Web.Configuration.WebSecurityConfigurerAdapter; importar org.Springframework.Transaction.Annotation.EnableTransactionManagement; @springbootapplication @enabletransactionmanagement @enableresourceserver @enableglobalmethodsecurity (prepostenabled = true) aplicación de clase pública {public static void main (string [] args) {springapplication. Ejecutar (aplicación. Clase, argumentos); } @configuration clase estática oktaoauth2websecurityconfigureradapter extiende websecurityconfigureradapter {@override protected void configure (httpsecurity http) lanza la excepción {http. AuthorizeRequests (). Cualquier solicitud (). Autenticado (). Y (). Oauth2ResourceServer (). Jwt (); }}}