Framework Spring
Intro
- Se introducen los conceptos:
- Interfaz: un contrato de métodos abstractos sin implementación al que una o muchas clases pueden suscribirse, para lo cual deberán implementar dichos métodos listados
- Framework: conjunto de herramientas en forma de lirberías
y métodologíaspara solucionar problemas comúnes de cierta forma, en algún lenguaje de programación
- Se introduce el framework Spring
- Un framework puntual hecho para Java
- Usa inyección de dependencias (mediante interfaces en lugar de clases)
Patrón MVC
- Es un enfoque para construir apps, separando los intereses y responsabilidades de cada objeto
- Un Controlador recibe solicitudes, en base a las cuales...
- Consulta o modifica el modelo de datos, para luego...
- Cargar la vista adecuada que mostrar al usuario, llenándola con datos del modelo
- Y se devuelve la vista al usuario
El controlador
- No resuleve lógica de negocio ni hace cálulos
- Esto se delega a los objetos del modelo
- No realiza presentación de datos ni usabilidad
- Esto se delega a las vistas
- Sí decide cuál vista cargar, y controla cómo y hacia dónde continúa el flujo de la app
- Dentro de una app, hay muchos controladores
- Es común que haya uno por cada Caso de uso
- De un controlador pueden existir muchas instancias concurrentes
- Esto sería para atender muchos usuarios con el mismo CU al mismo tiempo
El modelo de datos
Es un conjunto de clases que representan al dominio del sistema, y tienen una capa de comportamiento que resuelven la lógica de negocio
"Incluye clases de dominio con métodos del negocio"
- Incluye clases de software (clases técnicas, que no pertenecen al dominio pero son necesarias para el funcionamiento de la app)
- Por ejemplo, repositorios y DAOs (para conexión a bases de datos), y clases de "Servicio"
Las vistas
Componentes responsables de generar el contenido que se va a mostrar al usuario final (ya sea HTML, JSON u otro formato)
- Recibe los datos u objetos del modelo que necesita consultar para mostrar al usuario
- No resuelven lógica de negocio
- Sí resuelven lógica para la presentación e interfaz de usuario
- Pueden realizar nuevamente solicitudes al controlador (en base a acciones del usuario)
- ! Esto no es común representarlo en el DSD
Patrón MVC en Spring Web
Hay muchas clases que no explicamos porque las trae resultas Spring y son más bien técnicas. Lo que implementamos nosotros es el Controlador (Front controller), Vistas y Modelo
- En el modelo del MVC incluímos objetos de dominio y clases de software
- De las clases de software, hacemos hincapié en los DAO
- Estos encapsulan el acceso a la base de datos
Dominio
- No conocen la existencia del controlador
- Sólo saben de la existencia de otros objetos del dominio si se los asocia (con una colección, por ejemplo), si se los instancia o se pasen entre sí como referencias en un método
- Son ricos en comportamiento y resuelven lógica del negocio
- "No son contenedores de datos"
- ????? (no se qué quiso decir con esto pero parece importante)
- "Su valor está en sus métodos, no en sus atributos"
- Son capaces de resolver todo lo que puedan en base a lo que conocen de sus atributos y todos los objetos que conocen a través de sus asociaciones
Persistencia
- Los objetos del dominio no son responsables de manejar su persistencia
- Para esto existen los DAOs
- Esto significa que los objetos tampoco saben que los DAO existen (están "fuera de su visión")
Mapeo Objeto-Relacional
Es una estrategia para traducir entre objetos de un modelo de POO y registros de una base de datos relacional.
Existen varias estrategias de mapeo
DAO
a.k.a. Repositorio
Es un patrón de arquitectura para resolver el problema de acceso a base de datos
- En general, existe un DAO por cada clase del dominio
- Si dos objetos del dominio tienen una relación todo-parte, puede ser que haya sólo un DAO para la clase que representa el TODO
- Ejemplo: Para las clases Venta y LineaVenta, sólo hay un VentaDAO
- El DAO sólo recive y devuelve objetos del dominio; nunca devolverá datos sueltos
Implementación de patrón DAO en Spring
- Para crear un DAO para alguna clase, se debe crear una interfaz que extienda (herede) la interfaz genérica JpaRepository
- Esta es probista por Spring como plantilla para cualquier DAO, ya que trae métodos que sie usan siempre en todos los DAO
- En el caso de que necesitemos consultas más específicas, podemos escribir métodos que usen consultas JPQL
- JPQL es una sintaxis muy similar a SQL, pero pensado para la orientación a objetos ya que referencia clases en lugar de tablas, y atributos en lugar de campos
- Que la interfaz JpaRepository sea genérica, significa que, cuando la extendamos, le podemos indicar sobre qué clases o tipos de datos va a trabajar:
- En
JpaRepository<T, ID>
:- El parámetro
T
indica la clase del dominio a la que se hace referencia (que se va a guardar y devolver) - Y el parémetro
ID
es el tipo de dato que la claseT
usa para su clave primaria (el tipo de su id)
- El parámetro
- En
- Ejemplo:
Anotaciones y configuración de persistencia
- Además de crear el DAO, necesitamos indicar ciertas configuraciones mediante anotaciones en las clases del dominio, para indicarle a Spring cómo hacer el mapeo
JPQL (Java Persistence Query Language)
Puede verse como una versión orientada a objetos del SQL.
Las consultas se hacen sobre clases y sus atributos (en lugar de sobre tablas y sus campos).
El motor de persistencia de JPA se encarga de traducir JPQL a SQL
- JPQL puede hacer consultas
SELECT
, y actualizacionesUPDATE
yDELETE
Consultas
Las cláusulas [entre corchetes] son opcionales
- La cláusula
SELECT
consiste de 6 cláusulas:
SELECT alias
FROM entidad alias
[JOIN entidad.otroCampo aliasCampo]
[WHERE ...]
[
[GROUP BY ...]
[HAVING ...]
]
[ORDER BY ...]
- & Ejemplo:
SELECT c FROM Cliente c
- & Ejemplo:
SELECT c FROM Cliente c WHERE c.id > 20
- & Ejemplo: Si al método
BuscarClientePorId(int id)
le pasamos un parámetro, la consulta será:SELECT c FROM Cliente c WHERE c.id = ?1
- Los parámetros se simbolizan con
?n
, donden
es la posición del parámetro en la firma del método
- & Ejemplo: De igual forma que pasamos parámetros de tipos primitivos, podemos pasar objetos como parámetros:
- Método:
BuscarVehiculosPorDueño(Cliente c)
- Consulta:
SELECT v FROM Vehiculo v WHERE v.propietario = ?1
- Método:
- & Ejemplo: Búsqueda por string parcial (con wildcards)
- Método:
BuscarClientesPorNombre(String nombreParcial)
- Consulta:
SELECT c FROM Cliente c WHERE c.nombre LIKE '%?1%'
- ¡ Nota: El símbolo
?n
se reemplaza en el JPQL aún estando dentro de una string. De hecho, si el parámetro es un string, pongámoslo por las dudas dentro de una string:'?1'
- & Por ejemplo, al usarlo dentro de una función:
UPPER('?1')
- & Por ejemplo, al usarlo dentro de una función:
- Método:
- & Ejemplo: Joins
SELECT l FROM Localidad l JOIN l.clientes c GROUP BY l HAVING count(c) >= 10
- ¡ Para hacer un join de dos entidades, simplemente se menciona el atributo de la clase y se le da un alias:
JOIN l.clientes c
Inner Join
- Como las entidades (clases) deifinidas ya tienen asociadas las clases a las que están relacionadas, JPA tiene la información para saber enganchar entidades entre sí, y no necesitamos indicar (con la cláusula
ON
) las claves foráneas - En su lugar, sólo se indica el atributo por el cual existe la relación con la otra entidad
SELECT c
FROM Cliente c
JOIN c.localidad loc
WHERE loc.codPostal > 1000
- Los joins entre entidades no relacionadas no tienen soporte en JPA, pero se puede lograr lo mismo usando
WHERE
para buscar igualdad entre atributos
SELECT c FROM Cliente c, OtraClase oc WHERE c.id = oc.id
Left join
- Para devolver una consulta en la que la entidad tiene 0 o más (en lugar de 1 o más) objetos en alguna de sus colecciones, usamos left join de la misma forma que join en el JPQL:
SELECT DISTINCT loc FROM Localidad loc LEFT JOIN loc.clientes c WHERE loc.codPostal LIKE '%0' OR c.id > 20
ON
- El
ON
, como ya se dijo, no es necesario, pero puede usarse para agregar condiciones adicionales en el join/left join
Joins implícitos
- Suceden cuando usamos la notación de punto para navegar entidades:
SELECT c FROM Cliente c WHERE c.localidad.codPostal > 1000
Actualizaciones
- Las estructuras DELETE y UPDATE son más simples:
DELETE FROM ...
[WHERE ...]
UPDATE ...
SET ...
[WHERE ...]
Proyección
- Por entidad: El select devuelve un objeto completo por cada registro encontrado
SELECT c FROM Cliente c
- Distinct: Remueve duplicados, como en SQL
Implementación en Java
- Para crear métodos del DAO que ejecuten nuestras queries específicas, usamos las anotaciones
@Query("...")
public interface ClienteDao extends JpaRepository<Cliente, Long> {
@Query("SELECT c FROM Cliente c WHERE c.localidad = ?1")
public Collection<Cliente> buscarClientesPorLocalidad(Localidad l);
@Query("SELECT c FROM Cliente c WHERE c.name LIKE '%?1%'")
public Collection<Cliente> buscarClientesPorNombre(String nombre);
}