Est-il possible d'utiliser du SQL brut dans un référentiel Spring


112

J'ai besoin d'utiliser du SQL brut dans un référentiel de données Spring, est-ce possible? Tout ce que je vois autour @Queryest toujours basé sur une entité.



Comment puis-je utiliser cela dans un référentiel? Ou est-ce que je n'utiliserais pas un dépôt et utiliserais-je simplement cet objet dans mon service?
Webnet

Utilisez-vous spring-data-jpa?
zagyi

@Webnet Je suis un peu nouveau sur Spring moi-même, mais il me semble que vous pourriez l'utiliser comme objet
Chetter Hummin

avez-vous essayé Spring JDBCTemplate?
BlackJoker

Réponses:


133

L'annotation @Query permet d'exécuter des requêtes natives en définissant l'indicateur nativeQuery sur true.

Citation de la documentation de référence Spring Data JPA .

Consultez également cette section pour savoir comment procéder avec une requête native nommée.


13
@ user454322, les paramètres commencent par 1, donc c'est:@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
Jacob van Lingen

nativeQuery = true m'a sauvé de IllegalArgumentException
Reza

45

OUI, vous pouvez le faire de la manière suivante:

1. Par CrudRepository (Projection)

Les référentiels de données Spring renvoient généralement le modèle de domaine lors de l'utilisation de méthodes de requête. Cependant, vous devrez parfois modifier la vue de ce modèle pour diverses raisons.

Supposons que votre entité ressemble à ceci:

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

Maintenant, votre classe de projection est comme ci-dessous. Il peut les champs dont vous aviez besoin.

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

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

Maintenant ArrayList<IUserProjection> findUserUsingRollNo(String rollNo), vous donnera la liste des utilisateurs.

2. Utilisation d'EntityManager

Supposons que votre requête soit " select id, name from users where roll_no = 1001 ".

Ici, la requête renverra un objet avec la colonne id et name. Votre classe Response est comme ci-dessous:

Votre classe de réponse est comme:

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

ici, le constructeur UserObject obtiendra un tableau d'objets et définira les données avec l'objet.

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

Votre fonction d'exécution de requête est comme ci-dessous:

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

Ici, vous devez importer les packages ci-dessous:

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

Maintenant votre classe principale, vous devez appeler cette fonction. Obtenez d'abord EntityManager et appelez cette getUserByRoll(EntityManager entityManager,String rollNo)fonction. La procédure d'appel est donnée ci-dessous:

Voici les importations

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

obtenez EntityManagerde cette façon:

@PersistenceContext
private EntityManager entityManager;

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

Vous avez maintenant des données dans cet userObject.

Remarque:

query.getSingleResult () renvoie un tableau d'objets. Vous devez gérer la position de la colonne et le type de données avec la position de la colonne de requête.

select id,name from users where roll_no = 1001 

query renvoie un tableau et c'est [0] --> id and [1] -> name.

Plus d'informations visitez ce fil et ce fil

Merci :)


3

Il est également possible d'utiliser le référentiel Spring Data JDBC , qui est un projet communautaire construit sur Spring Data Commons pour accéder aux bases de données avec SQL brut, sans utiliser JPA.

Il est moins puissant que Spring Data JPA, mais si vous voulez une solution légère pour des projets simples sans utiliser un ORM comme Hibernate, cette solution vaut la peine d'essayer.


3

nous pouvons utiliser createNativeQuery ("Here Nagitive SQL Query");

par exemple :

Query q = em.createNativeQuery("SELECT a.firstname, a.lastname FROM Author a");
List<Object[]> authors = q.getResultList();

9
Ce serait utile / complet si vous montriez également comment créer la emvariable.
ETL

1

Il est possible d'utiliser une requête brute dans un référentiel 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);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.