¿Es posible usar SQL sin formato dentro de un repositorio de Spring?

112

Necesito usar SQL sin procesar dentro de un repositorio de datos de Spring, ¿es esto posible? Todo lo que veo a mi alrededor @Querysiempre se basa en entidades.

Webnet
fuente
¿SqlQuery lo haría? static.springsource.org/spring/docs/2.5.x/api
Hummin
¿Cómo podría usar eso dentro de un repositorio? ¿O no usaría un repositorio y simplemente usaría ese objeto dentro de mi servicio?
Webnet
¿Utiliza spring-data-jpa?
zagyi
@Webnet Soy un poco nuevo en Spring, pero me parece que podrías usarlo como objeto
Chetter Hummin
¿Has probado Spring JDBCTemplate?
BlackJoker

Respuestas:

133

La anotación @Query permite ejecutar consultas nativas estableciendo el indicador nativeQuery en verdadero.

Cita de los documentos de referencia de Spring Data JPA .

Además, consulte esta sección sobre cómo hacerlo con una consulta nativa con nombre.

zagyi
fuente
13
@ user454322, los parámetros comienzan con 1, por lo que es:@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
Jacob van Lingen
nativeQuery = true me salvó de IllegalArgumentException
Reza
45

SÍ, puede hacer esto de las siguientes formas:

1. Por CrudRepository (proyección)

Los repositorios de datos de Spring generalmente devuelven el modelo de dominio cuando se utilizan métodos de consulta. Sin embargo, a veces, es posible que deba modificar la vista de ese modelo por varias razones.

Suponga que su entidad es así:

    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;
        }
    }

Ahora tu clase de proyección es como abajo. Puede esos campos que necesitabas.

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

Y 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);
}

Ahora ArrayList<IUserProjection> findUserUsingRollNo(String rollNo)te dará la lista de usuarios.

2. Usando EntityManager

Suponga que su consulta es " seleccionar id, nombre de los usuarios donde roll_no = 1001 ".

Aquí la consulta devolverá un objeto con la columna de identificación y nombre. Su clase de respuesta es como abajo:

Tu clase de respuesta es 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;
        }
    }

aquí el constructor UserObject obtendrá una matriz de objetos y establecerá datos con el objeto.

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

La función de ejecución de su consulta es la siguiente:

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;
        }
    }

Aquí tienes que importar los siguientes paquetes:

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

Ahora tu clase principal, tienes que llamar a esta función. Primero obtenga EntityManager y llame a esta getUserByRoll(EntityManager entityManager,String rollNo)función. El procedimiento de llamada se da a continuación:

Aquí están las importaciones

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

obtener EntityManagerde esta manera:

@PersistenceContext
private EntityManager entityManager;

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

Ahora tiene datos en este userObject.

Nota:

query.getSingleResult () devuelve una matriz de objetos. Debe mantener la posición de la columna y el tipo de datos con la posición de la columna de consulta.

select id,name from users where roll_no = 1001 

consulta devuelve una matriz y es [0] --> id and [1] -> name.

Más información visite este hilo y este hilo

Gracias :)

Md. Sajedul Karim
fuente
3

También es posible usar el repositorio Spring Data JDBC , que es un proyecto comunitario construido sobre Spring Data Commons para acceder a bases de datos con SQL sin procesar, sin usar JPA.

Es menos poderoso que Spring Data JPA, pero si desea una solución liviana para proyectos simples sin usar un ORM como Hibernate, esa es una solución que vale la pena probar.

Sébastien Deleuze
fuente
3

podemos usar createNativeQuery ("Aquí consulta SQL Nagitive");

por ejemplo :

Query q = em.createNativeQuery("SELECT a.firstname, a.lastname FROM Author a");
List<Object[]> authors = q.getResultList();
Lova Chittumuri
fuente
9
Sería útil / completo si también mostrara cómo crear la emvariable.
ETL
1

Es posible utilizar consultas sin formato dentro de un repositorio 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
fuente