Consulta dentro do Java

Buenas,

Preciso transformar uma query SQL em algo assim:

@Query ("SELECT o FROM Order....")

Estou usando o Spring Boot. Problema que nunca usei essa anotação e precisaria selecionar outros atributos de outros objetos, mas quando coloco lá, não funciona:

@Query(SELECT o, u.email, c.id…")

Acredito que não esteja usando da forma certa a sintaxe. Alguém consegue me ajudar ou me indicar um bom tutorial?

Edit: Minhas principais dúvidas são:

  • Quantos objetos eu consigo consultar no “SELECT”?
  • Posso consultar outros objetos e seus campos simplesmente colocandos “SELECT objeto.campo”?
    Grato.

Segue um ótimo material!

Antes de perguntar eu tinha acabado de ler esse material, realmente muito bom, mas infelizmente não respondeu minha pergunta :frowning:

Não achei nenhum exemplo que eu pudesse usar, infelizmente…

O que tu quer fazer é uma seleção simples ou com join em outras tabelas?

Fazer JOINS com outras tabelas… porém, a minha dúvida é como fazer para pegar os campos de outras tabelas. Segue os meus códigos:
Essa é minha consulta SQL, que retorna os dados que estou precisando:

SELECT 
	o.idorder, 
	o.date_reg, 
	o.total, 
	o.pay_type, 
	o.order_status, 
	o.for_collection,  
	o.fk_idbusiness as restaurant_id,
	u.email,
	u.first_name,
	b.idbusiness as id_business
from orders o
inner join customer as c on ( c.idcustomer = o.fk_idcustomer )
inner join user as u on ( u.iduser = c.fk_iduser )
inner join business_delivery_address as d on ( o.fk_idbusiness_delivery_address = d.idbusiness_adress )
inner join business as b on ( b.idbusiness = d.fk_idbusiness )
where o.idorder = 71424;

Tenho as entidades então no Java: Order, User, Business, Customer e BusinessDeliveryAdress. O número depois de “=” é um id qualquer de uma Order.

A minha consulta no Java, com a notação @Query é essa (que não está dando certo e não sei se estou fazendo certo ou errado) :

@Query("SELECT o.id, o.dateReg, o.total, o.payType, o.orderStatus, o.forCollection, o.business.id, " 
			+ "o.customer.user.email, o.customer.user.firstName, o.customer.user.lastName, o.deliveryAddress.business.id "
			+ "FROM Order o JOIN o.customer c JOIN c.user u JOIN o.deliveryAddress d JOIN d.business b " 
			+ "WHERE o.id = :idOrder")
	List<Order> findByGiuli(@Param("idOrder") Long idOrder);

O nome do método usei meu nome só para achar mais ligeiro no código.
Na verdade, queria fazer a tradução desse código SQL para esse do Java (HQL ou JPQL, não tenho certeza…)

Sem conhecer os atributos das classes, acho que a consulta JPQL ficaria algo próximo disso:

SELECT o
FROM Order o
WHERE o.id = 71424

No seu caso, não precisa especificar os joins na JPQL pois, ao retornar a lista de ordens, os valores dos atributos relacionados já serão retornados automaticamente por causa do mapeamento.

Minha dificuldade está em entender como consultar outros objetos/atributos diferentes. Por exemplo, assim dessa forma, eu estaria consultando somente o objeto “Order”, certo?

Isso mesmo, porém, essa consulta retornará os dados dos objetos relacionados com Order também.

he… não sei se estou sabendo explicar, mas assim: esta consulta está em uma interface do tipo “repository”, onde só é declarado a assinatura do método. Depois, uso esse método em uma classe “service” para criar um método e fazer a conversão para um objeto DTO e depois uso esse método em uma classe “controller”. Talvez até esteja trazendo os dados que eu preciso, porém, não estou sabendo como “chamar” esses dados e apresenta-los na api. Sei que deve ter algum esquema na classe “service”, mas não sei como…

Não sei se entendi bem, mas de acordo com o que eu entendi você quer fazer a consulta e montar um objeto DTO de acordo com o retorno da mesma, isso?

Se for o caso, tenho um projeto no meu git que desenvolvi uma situação assim executando queries nativas, mas não dentro da interface com o @Query, fiz de forma diferente e separada com hibernate, se for esse o caso, talvez te sirva de apoio.

Acredito que o método que vc precisa implementar seja mais ou menos assim:

Repository

@Query("SELECT o FROM Order o WHERE o.id = :idOrder")
List<Order> findById(@Param("idOrder") Long idOrder);

Service

List<Order> orders = orderRepository.findById(1234L);
List<OrderDTO> ordersDTO = new ArrayList<>();

orders.forEach(o -> {
	OrderDTO dto = new OrderDTO();
	// faça os gets e sets dos campos que precisa
	ordersDTO.add(DTO);
}

return ordersDTO;

Outra forma, seria montar já na consulta usando new OrderDTO

@Query("SELECT new seu.pacote.OrderDTO(o) FROM Order o WHERE o.id = :idOrder")
List<OrderDTO> findById(@Param("idOrder") Long idOrder);

E na classe OrderDTO:

public class OrderDTO {
	
	// campos
	
	public OrderDTO(Order order) {
		// seta os campos necessários aqui
	}
	
	// getters and setters
}

Como settar campos de outras classes (entitys) que não sejam do tipo “Order” ?

Vou fazer uma pergunta mais teórica. Bem, o meu método na interface repository é esse:

@Query("SELECT o FROM Order o JOIN o.customer c JOIN c.user u JOIN o.deliveryAddress d JOIN d.business b " 
			+ "WHERE o.id = :idOrder")
	Order findOrderById(@Param("idOrder") Long idOrder);

pois preciso ter os dados (campos) das entidades Order, User e Business. Como posso “setar” ou extrair esses dados? Onde essa consulta é retornada e como posso manipula-la?
E outra questão para entendimento: em uma @Query eu somente posso retornar um objeto, assim como um método só pode ter um retorno, certo? Mas como consultar valores que vem de outros objetos, mesmo que eles só tem uma associação pelo objeto “principal” (que está no início da “@Query”)??

Como posso “setar” ou extrair esses dados?

Setar e extrair são duas coisas distintas. Como você está realizando uma consulta, vc não irá setar nada no retorno, apenas extrair.

Onde essa consulta é retornada e como posso manipula-la?

Como vc disse, o resultado dessa consulta será obtida na sua classe de serviço (que acredito ser onde você está chamando esse método findOrderById

em uma @Query eu somente posso retornar um objeto, assim como um método só pode ter um retorno, certo? Mas como consultar valores que vem de outros objetos, mesmo que eles só tem uma associação pelo objeto “principal”

No seu caso, o objeto retornado é Order (uma lista de orders), para vc obter os valores de outros objetos, basta navegar através dos atributos de Order (customer, user, deliveryAddress, business). Nessa parte, é importante que o mapeamento esteja bem feito, pois vc só terá acesso aos atributos que se relacionam com Order (many-to-one, one-to-many, one-to-one, many-to-many)

Hola que tal Giuli_Ilustre
Ya pudiste hacer esa consulta ? yo también me encuentro en en una consulta similar con 3 tablas pero necesito unos campos de otras tablas, por favor como lo hiciste en JPQL ?