Antes de empezar

1

Pasos para aprender Java Spring

2

¿Java sigue siendo gratuito?

3

Instalación de ambiente de desarrollo: Linux Ubuntu

4

Instalación de ambiente de desarrollo: macOS

5

Instalación de ambiente de desarrollo: Windows

Introducción a Spring boot

6

¿Qué es y qué usaremos de Spring?

7

Conocer qué es una aplicación autocontenida

8

Crear nuestra aplicación con Spring Initializr

9

Hola mundo con Spring Boot

10

Configurar Spring Boot

11

Crear la estructura del proyecto

Spring Data

12

¿Qué es JPA?

13

Conocer qué es Spring Data

14

Conectar la base de datos a nuestra aplicación

15

Mapear las tablas como clases

16

Crear Entity cuando su clave primaria es compuesta

17

Mapear relaciones entre clases

18

Usar la interface CrudRepository

19

Query Methods

Construyendo nuestra API

20

Implementar la anotación @Repository

21

¿Qué es el patrón Data Mapper y qué resuelve?

22

Orientar nuestra API al dominio con MapStruct

23

Orientar nuestro repositorio a términos del dominio

24

Inyección de dependencias

25

Implementar la anotación @Service

26

Implementar la anotación @RestController

27

Exponer nuestra API

Mejorando nuestra API

28

Controlar las respuestas HTTP

29

Crear el dominio de compras

30

Mapear el dominio de compras

31

Crear el repositorio de compras

32

Probando nuestros servicios de compras

33

Documentar nuestra API con Swagger

Spring Security

34

Configurar la seguridad de nuestra API con Spring Security

35

Generar un JWT

36

Autenticación con JWT

37

Autorización con JWT

Despliegue de nuestra aplicación

38

Desplegar nuestra API desde la ventana de comandos

39

Desplegar nuestra base de datos con Heroku

40

Desplegar nuestra API con Heroku

41

Conclusiones y despedida del curso

Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Curso de Java Spring

Curso de Java Spring

Alejandro Ramírez

Alejandro Ramírez

Query Methods

19/41
Recursos

Aportes 48

Preguntas 11

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Creo que de la ruta de Java es sin dudas el mejor curso, se entiende a la perfeccion lo que expica Alejandro y Java Spring es realmente sorprendente…

<h3>Los query method son muy potentes. Además de los explicado, permiten realizar múltiples operaciones de comparación con:</h3>
  • Números: mayores, menores, iguales…
  • Textos: contiene cierta porción de texto, empieza o termina con una porción de texto, ignora case sensitive…
  • Fechas: Antes de cierta fecha, después de cierta fecha, entre cierta fecha…
  • Joins entre entidades: Si tenemos una entidad que se relaciona con otra, es posible realizar “joins” con esa relación para tener queries más específicas según nuestra necesidad. Por ejemplo, si tengo una relación de Producto y Categoría y quiero tener todos los productos de cierta categoría podría hacer: findAllByCategoriasId(Integer categoriaId) y así poder llegar a esta relación. Esto puede mezclarse con múltiples relaciones en simultáneo
  • Comparación entre un conjunto de datos: Si por ejemplo quiero traerme los productos con varias categorías, podría escribir findAllByCategoriasIdIn(List<Integer> categoriaIds); y así trabajar bajo un conjunto de Id de categorías

Existen más funcionalidades ✌🏼. Pueden ver más detalle acá: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation

Con la anotación @Query es posible, entre otras cosas, escribir sentencias con JPQL. Es otro nivel de abstracción de la base de datos en donde se hacen queries sobre las clases Java y no sobre el nombre de las tablas. Bajo mi preferencia, si poseo una query muy compleja que podría hacer que mí QueryMethod sea muy verbosa, prefiero utilizar JPQL y así tener código más legible. Esto me ayuda a tener un código más limpio y seguir manteniendo la abstracción de base de datos que se pierde al hacer una query nativa.

Acá les dejo un link referencial sobre @Query en Spring JPA
https://www.baeldung.com/spring-data-jpa-query

Si quieren aprender más sobre los Optionals les recomiendo esta clase:

https://platzi.com/clases/1826-java-funcional/26239-la-clase-optional/ 🚀

ProductoCrudRepository

Optional<List<Producto>> findByPrecioVentaLessThanAndIdCategoriaOrderByNombreAsc(int precioVenta, int idCategoria);

ProductoRepository

public Optional<List<Producto>> getProductoByPrecioVentaLessThanPriceAndByCategory (int precioVenta, int idCategoria) {
        return productoCrudRepository.findByPrecioVentaLessThanAndIdCategoriaOrderByNombreAsc(precioVenta, idCategoria);
    }

Sin duda el mejor curso que he visto en platzi…

Se pueden usar Query Methods o de manera nativa, pero es preferible la primera.

Muy buen tema. gracias por explicarlo tan claro!

Muy interesante el tema sin duda 😄, pero recuerden que no es una buena práctica de seguridad utilizar en su código Querys, lo mejor para consumir bases de datos son Stored Procedures para evitar ataques SQL Injection entre muchos otros.

Optional<List<Producto>> findByPrecioVentaGreaterThanEqualAndCantidadStockLessThanOrderByNombre(double precioVenta, int cantidadStock);

Estos son los métodos que agregué a la clase Compra.

Por una experiencia personal les recomiendo a todos aplicar una una buena practica que es la de definir el tipo de dato para los id, ya sean variables o parámetros de métodos colocar como Long, ya que en sistemas de la vida real con muchísimos datos puede llegar a causarles problemas.

Una variante extra a @Query es: @NamedQuery

Se declara así:

@Entity
@NamedQuery(name = "User.findByEmailAddress",
  query = "select u from User u where u.emailAddress = ?1")
public class User {

}

y se usa así:

public interface UserRepository extends JpaRepository<User, Long> {

  List<User> findByLastname(String lastname);

  User findByEmailAddress(String emailAddress);
}

public class PagoRepo {
private PagoCrudRepo pagoCrudRepo;

public List<Pago> getPagos(int idPago){
    return (List<Pago>) pagoCrudRepo.findByIdPago(idPago);
}
public  List<Pago> fechaPago(Date fecha){
    return  pagoCrudRepo.findByFechaLess(fecha);
}
public Optional<List<Pago>> getCentroArrendatario(int idArrendatario, int idCentro){
    return  pagoCrudRepo.findByIdArrendatarioAndIdCentro(idArrendatario, idCentro);
}
public Optional<List<Pago>> getCentroArrendatarioFecha(int idArrendatario, int idCentro, Date fecha){
    return  pagoCrudRepo.findByIdArrendatarioAndIdCentroAndFecha(idArrendatario, idCentro, fecha);
}

}

Aquí está mi query method

Optional<List<Producto>> findByNombreAndPrecioVentaGreaterThanAndEstado(String nombre,double precioVenta,boolean estado);

Bastante interresante los query methods, en el ultimo proyecto que trabaje escribiamos las sentencias SQL segun las peticiones, que cantidad de tiempo puede ahorrar esto

profesor! muchas gracias por la manera de explicar! me ha quedado super claro y quede muy intrigado con saber mas acerca de los query methods

 public Optional<List<Producto>>getCantidadDisponible(String nombre){
        return productoCrudRepository.findByCantidadStockAndEstado(nombre,true);
    }```

me parece bien potente esto de los Query Methods, sin embargo pienso que hacer un refactor - que muchas veces implica mejorar los nombres de nuestros atributos - provocaria que se caiga el/los Query Method(s) cuyo nombre esta asociado a dicho atributo, y esto ocurriria sin siquiera saberlo ya que el compilador no detectaria dicho metodo como erroneo, este error seria solo detectado en runtime.

A mi en lo personal me gusta @Query porque siento mucho mas control sobre las consultas que se realizan en los métodos. Sin embargo, he notado que usar los Query Methods nos ahorra mucho trabajo en ciertas zonas y lo he empezado a utilizar con más frecuencia en mis proyectos. 🚀

Lo que no me gusta es que lleva buen rato escribiendo un montón de código y no ha probado nada para ver si funciona

El curso está chingon, wey

Query methods ofrece facilidades al definir consultas. Sin embargo, a nivel de performance no es el mejor. Ya que si tenemos mas entidades relacionadas por debajo spring data incluye mas y mas consultas. Eso perjudica considerablemente el performance. Lo que recomiendo es que si no tiene tantas relaciones puedes usar query methods. Pero si tienes artas consultas.. recomiendo haver el query en JPQL y realizar los respectivos joins para evitar tantas consultas x debajo.

Muy buen tema, gracias por explicarlo tan claro.!

Buenisima clase!

Este Query Method trae un listado de los productos en los que su cantidad de stock es menor al nivel ingresado y que pertenecen a una categoria en dada.

List<Producto> 	 findByIdCategoriaAndCantidadStockLessThan(int idCategoria, int cantidadStock);

Este Query Method hace una consulta a la BD y regresa un elemento de tipo producto que coincida con el id y el nombre ingresados por parámetros.

Producto findByIdProductoAndNombre(int idProducto, String nombre);

Excelente manera de explicar los Query Methods! que buendcurso…

<code>Optional<Producto> findByNombreAndPrecioVentaGreaterThan(String nombre, double precioVenta);

Estos son 2 Query methods ideados por mí; si están errados por favor NO DUDAR en corregirme 😄

// ProductoCrudRepository
    List<Producto> findByPrecioVentaLessThan(double precioLimite);

    List<Producto> findByIdCategoriaAndPrecioVentaLessThan(long idCategoria, double precioLimite);

    List<Producto> findByCategoriaGreaterThanOrPrecioVentaLessThan(long idCategoriaMenor, double precioMaximo);

// ===============================

// ProductoRepository
    public List<Producto> getByPrecioLimite(double precioLimite) {
        return productoCrudRepository.findByPrecioVentaLessThan(precioLimite);
    }

    public List<Producto> getByCategoriaLimiteOrPrecioMaximo(long idCategoriaLimite, double precioLimite) {
        return productoCrudRepository.findByCategoriaGreaterThanOrPrecioVentaLessThan(idCategoriaLimite, precioLimite);
    }

Cómo escribir los QueryMethods. Me parece que no debería evaluar mal si se usa findAllBy en lugar del findBy. Es lo mismo, y el findAllBy mejora la semántica del queryMethod.

  • Me tocó utilizar ambas opciones

@Query(value = “SELECT * FROM EVOLUCION WHERE cc = ?1 AND fech_evolucion = (SELECT MAX(fech_evolucion) from EVOLUCION)”, nativeQuery = true)

Optional<Evolucion> findByLastDate(int cc);

Lo explicas demasiado bien !!!

los query methods son parte del CrudRepository?

Muy buen tema, este es mi query methods

@Autowired
private Producto repository;


public Producto getProductoById(int id) {
		return repository.findById(id).get();
	}
	
	public List<Producto getAllProductos(){
		return (List<Producto>) repository.findAll();
	}

Si quieres mas informacion de los tipos de JPA Querys que existen te dejo el siguiente enlace.

Jpa-Queries

Como puedo probar que funcionen estos metodos? lo intente pero me daba un NullPointerException

ProductoCrudRepository.java :

//...

Optional<Producto> findByCodigoBarras(String codigoBarras);

    Optional<List<Producto>> findByNombreLike(String nombre);

//...

Una chulada de curso

My challenge

// ProductoCrudRepository.java

  List<Producto> findByPrecioVentaLessThanAndEstado(Double precioVenta, boolean estado);

  List<Producto> findByEstadoOrderByNombreAsc(boolean estado);

// ProductoRepository.java

public List<Producto> getProductsCheap(Double precioVenta, boolean estado){
    return productoCrudRepository.findByPrecioVentaLessThanAndEstado(precioVenta, estado);
  }

  public List<Producto> getProductsActive(){
    return productoCrudRepository.findByEstadoOrderByNombreAsc(true);
  }

ProductCrudRepository

public interface ProductoCrudRepository extends CrudRepository<Producto, Integer> {
    //All CrudRepository methods are inherit from CrudRepository

    /*
    NATIVE QUERY METHOD
    @Query(value = "SELECT * FROM productos WHERE id_categoria = ?", nativeQuery = true)
    List<Producto> getCategoriaByNombreAsc(int idCategoria);
    */

    //JPA Query Method
    List<Producto> findByIdCategoriaOrderByNombreAsc(int idCategoria);
    Optional<List<Producto>> findByCantidadStockLessThanAndEstado(int cantidadStock, boolean estado);
}

ProductRepository

public class ProductoRepository {
    private ProductoCrudRepository productoCrudRepository;

    //CrudRepository methods
    public List<Producto> getAll() {
        return (List<Producto>) productoCrudRepository.findAll();
    }

    /*
    NATIVE QUERY METHOD
    public List<Producto> getCategoria(int idCategoria) {
        return productoCrudRepository.getCategoriaByNombreAsc(int idCategoria)
    }
    */

    //JPA Query methods
    public List<Producto> getByCategoria(int idCategoria) {
        return productoCrudRepository.findByIdCategoriaOrderByNombreAsc(idCategoria);
    }
    public Optional<List<Producto>> getEscasos(int cantidad) {
        return productoCrudRepository.findByCantidadStockLessThanAndEstado(cantidad, true);
    }
}

Si queremos usar @query pero no indicamos que será un query nativo, significa que ¿tendremos que usar JPQL en lugar de SQL?

Gracias

public List<Product> getByDescriptionLike(String description, boolean state) {
        return (List<Product>) productCrudRepository.findByDescriptionLikeAndState(description, state);
    }

    public List<Product> getByBarcode(String barcode, boolean state) {
        return (List<Product>) productCrudRepository.findByBarcodeAndState(barcode, state);
    }

Excelente tema, tengo que aprender mas sobre estos métodos son mucho muy buenos

prosor y el Autowired? como se puede instanciar los metodos tan solo
creando un variable tipo