NativeQuery

Disponível

3.1 Introdução

Outra coisa útil sobre a qual gostaria de falar é NativeQuery . Como você já sabe, usando NativeQuery, você pode escrever consultas em SQL nativo. No entanto, o que é ainda mais interessante é que você não precisa usar o mapeamento de classe ao obter o resultado da consulta.

Prefiro mostrar um exemplo:

List<Object[]> persons = session.createNativeQuery("SELECT * FROM Person").list();

Neste exemplo, não passamos uma classe que corresponda às linhas do resultado da consulta, apenas usamos uma matriz de objetos Object.

Isso pode ser útil se você quiser selecionar apenas algumas colunas em uma tabela. Exemplo:

List<Object[]> persons = session.createNativeQuery("SELECT id, name FROM Person").list();

for(Object[] person : persons) {
    Number id = (Number) person[0];
    String name = (String) person[1];
}

Isso é um pouco semelhante à abordagem JDBC quando você obtém um objeto ResultSet e lê os dados de suas linhas.

No entanto, o Hibernate oferece diferentes maneiras de tornar isso mais confiável. Por exemplo, você pode especificar o tipo de colunas que deseja subtrair. Exemplo:

Query<Object[]> query = session.createNativeQuery("SELECT id, name FROM Person");
query.addScalar("id", StandardBasicTypes.LONG);
query.addScalar("name", StandardBasicTypes.STRING);
List<Object[]> persons = query.list();

for(Object[] person : persons) {
    Long id = (Long) person[0];
    String name = (String) person[1];
}

3.2 Mapeamento de entidades

Você também pode especificar explicitamente a classe que o Hibernate deve usar ao analisar o resultado de NativeQuery . Isso pode ser feito de diferentes maneiras.

Query<Person> query = session.createNativeQuery("SELECT * FROM Person")
    .addEntity(Person.class);
    .list();

E claro, o bom e velho formato que você conhece:

Query<Person> query = session.createNativeQuery("SELECT * FROM Person", Person.class).list();

A primeira abordagem é a abordagem nativa do Hibernate e a segunda é a abordagem JPA. A abordagem JPA é mais conveniente e concisa, pois esse padrão foi inventado depois que o Hibernate existiu por muitos anos. E o Hibernate evoluiu e foi forçado a suportar abordagens antigas para manter a compatibilidade com suas versões antigas.

A propósito, graças à sua abordagem, o Hibernate permite conectar não uma classe ao mapeamento do resultado da consulta, mas várias classes. Exemplo:

List<Phone> results = session.createNativeQuery(
    "SELECT {ph.*}, {pr.*}" +
    "FROM Phone ph" +
    "JOIN Person pr ON ph.person_id = pr.id")
.addEntity("ph", Phone.class)
.addJoin("pr", "ph.person")
.list();

for (Phone. phone : results) {
           	assertNotNull( phone.getPerson().getName() );
}

Essa abordagem usando NativeQuery pode ser usada para acelerar a seleção de dados do banco de dados. Se você sabe que não precisa de algumas colunas, pode omiti-las na solicitação.

Você também pode carregar todas as entidades filhas de uma vez, mesmo que o Hibernate queira usar Cache ou o mecanismo LazyLoading . Além disso, suas entidades filhas podem ter muitas colunas no banco de dados e você pode selecionar apenas algumas delas.

3.3 Mapeamento DTO

O Hibernate também permite que você use classes não Entity para mapear o resultado. Classes que não possuem anotações e não são mapeadas para nenhuma tabela.

Exemplo:

public class PersonSummaryDTO {
    private Number id;
    private String name;

    public Number getId() {
    	return id;
    }

    public void setId(Number id) {
    	this.id = id;
    }

    public String getName() {
    	return name;
    }

    public void setName(String name) {
    	this.name = name;
	}
}

List<PersonSummaryDTO> dtos = session.createNativeQuery(
    "SELECT p.id as \"id\", p.name as \"name\" FROM Person p")
.setResultTransformer(Transformers.aliasToBean(PersonSummaryDTO.class) )
.list();

Como não há anotações na classe PersonSummaryDTO, os nomes das colunas na consulta SQL devem corresponder exatamente aos nomes dos campos da classe PersonSummaryDTO.

Isso pode ser muito útil se você estiver lendo dados de um banco de dados externo ao qual seu aplicativo está conectado apenas no modo somente leitura. Ou seja, você teve acesso a tabelas com mais de 50 colunas, elas armazenam dados de forma desordenada para agilizar a seleção.

Ou digamos que alguém decidiu armazenar a hierarquia de classes em uma tabela, e em cinco anos essa tabela cresceu tanto que o diabo vai quebrar a perna. Você precisa selecionar algumas colunas desta tabela (Id e nome de usuário) e fornecê-las ao cliente.

Acho que você entendeu, mas se quiser se aprofundar mais nesse assunto, pode ler mais no link:

Consultas SQL nativas

Comentários
  • Populares
  • Novas
  • Antigas
Você precisa acessar para deixar um comentário
Esta página ainda não tem nenhum comentário