É possível usar SQL bruto dentro de um Repositório Spring

112

Preciso usar SQL bruto em um Repositório Spring Data, isso é possível? Tudo o que vejo ao redor @Queryé sempre baseado em entidades.

Webnet
fonte
SqlQuery serviria? static.springsource.org/spring/docs/2.5.x/api
Chetter Hummin
Como posso usar isso em um repositório? Ou eu não usaria um repo e apenas usaria esse objeto em meu serviço?
Webnet
Você usa spring-data-jpa?
zagyi
@Webnet Eu sou um pouco novo no Spring, mas me parece que você poderia usar isso como um objeto
Chetter Hummin
você experimentou Spring JDBCTemplate?
BlackJoker

Respostas:

133

A anotação @Query permite executar consultas nativas definindo o sinalizador nativeQuery como true.

Cite os documentos de referência do Spring Data JPA .

Além disso, consulte esta seção sobre como fazer isso com uma consulta nativa nomeada.

Zagyi
fonte
13
@ user454322, os parâmetros começam com 1, então é:@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
Jacob van Lingen
nativeQuery = true me salvou de IllegalArgumentException
Reza
45

SIM, você pode fazer isso das maneiras abaixo:

1. Por CrudRepository (Projeção)

Os Spring Data Repositories geralmente retornam o modelo de domínio ao usar métodos de consulta. No entanto, às vezes, você pode precisar alterar a exibição desse modelo por vários motivos.

Suponha que sua entidade seja assim:

    import javax.persistence.*;
    import java.math.BigDecimal;

    @Entity
    @Table(name = "USER_INFO_TEST")
    public class UserInfoTest {
        private int id;
        private String name;
        private String rollNo;

        public UserInfoTest() {
        }

        public UserInfoTest(int id, String name) {
        this.id = id;
        this.name = name;
        }

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "ID", nullable = false, precision = 0)
        public int getId() {
            return id;
        }

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

        @Basic
        @Column(name = "name", nullable = true)
        public String getName() {
            return name;
        }

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

        @Basic
        @Column(name = "roll_no", nullable = true)
        public String getRollNo() {
            return rollNo;
        }

        public void setRollNo(String rollNo) {
            this.rollNo = rollNo;
        }
    }

Agora sua classe Projection é como a abaixo. Ele pode aqueles campos que você precisava.

public interface IUserProjection {
     int getId();
     String getName();
     String getRollNo();
}

E Your Data Access Object(Dao) is like bellow:

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

import java.util.ArrayList;

public interface UserInfoTestDao extends CrudRepository<UserInfoTest,Integer> {
    @Query(value = "select id,name,roll_no from USER_INFO_TEST where rollNo = ?1", nativeQuery = true)
    ArrayList<IUserProjection> findUserUsingRollNo(String rollNo);
}

Agora ArrayList<IUserProjection> findUserUsingRollNo(String rollNo)lhe dará a lista de usuários.

2. Usando EntityManager

Suponha que sua consulta seja " select id, name from users where roll_no = 1001 ".

Aqui a consulta retornará um objeto com a coluna id e name. Sua classe de resposta é como abaixo:

Sua classe de resposta é como:

public class UserObject{
        int id;
        String name;
        String rollNo;

        public UserObject(Object[] columns) {
            this.id = (columns[0] != null)?((BigDecimal)columns[0]).intValue():0;
            this.name = (String) columns[1];
        }

        public int getId() {
            return id;
        }

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

        public String getName() {
            return name;
        }

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

        public String getRollNo() {
            return rollNo;
        }

        public void setRollNo(String rollNo) {
            this.rollNo = rollNo;
        }
    }

aqui o construtor UserObject obterá um Object Array e definirá os dados com o objeto.

public UserObject(Object[] columns) {
            this.id = (columns[0] != null)?((BigDecimal)columns[0]).intValue():0;
            this.name = (String) columns[1];
        }

A função de execução de sua consulta é a seguinte:

public UserObject getUserByRoll(EntityManager entityManager,String rollNo) {

        String queryStr = "select id,name from users where roll_no = ?1";
        try {
            Query query = entityManager.createNativeQuery(queryStr);
            query.setParameter(1, rollNo);

            return new UserObject((Object[]) query.getSingleResult());
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

Aqui você deve importar os pacotes abaixo:

import javax.persistence.Query;
import javax.persistence.EntityManager;

Agora sua classe principal, você tem que chamar esta função. Primeiro, obtenha o EntityManager e chame esta getUserByRoll(EntityManager entityManager,String rollNo)função. O procedimento de chamada é fornecido abaixo:

Aqui estão as importações

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

obtenha EntityManagerdesta forma:

@PersistenceContext
private EntityManager entityManager;

UserObject userObject = getUserByRoll(entityManager,"1001");

Agora você tem dados neste userObject.

Nota:

query.getSingleResult () retorna uma matriz de objeto. Você deve manter a posição da coluna e o tipo de dados com a posição da coluna de consulta.

select id,name from users where roll_no = 1001 

consulta retorna uma matriz e é [0] --> id and [1] -> name.

Mais informações visite este tópico e este tópico

Obrigado :)

Md. Sajedul Karim
fonte
3

Também é possível usar o repositório Spring Data JDBC , que é um projeto de comunidade construído em cima do Spring Data Commons para acessar bancos de dados com SQL bruto, sem usar JPA.

É menos poderoso que o Spring Data JPA, mas se você deseja uma solução leve para projetos simples sem usar um ORM como o Hibernate, vale a pena tentar essa solução.

Sébastien Deleuze
fonte
3

podemos usar createNativeQuery ("Here Nagitive SQL Query");

por exemplo :

Query q = em.createNativeQuery("SELECT a.firstname, a.lastname FROM Author a");
List<Object[]> authors = q.getResultList();
Lova Chittumuri
fonte
9
Seria útil / completo se você também mostrasse como criar a emvariável.
ETL de
1

É possível usar consulta bruta em um repositório Spring.

      @Query(value = "SELECT A.IS_MUTUAL_AID FROM planex AS A 
             INNER JOIN planex_rel AS B ON A.PLANEX_ID=B.PLANEX_ID  
             WHERE B.GOOD_ID = :goodId",nativeQuery = true)

      Boolean mutualAidFlag(@Param("goodId")Integer goodId);
Abdur Rahman
fonte