Ist es möglich, Raw SQL in einem Spring Repository zu verwenden?


110

Ich muss Raw-SQL in einem Spring Data Repository verwenden. Ist dies möglich? Alles, was ich sehe, @Querybasiert immer auf Entitäten.



Wie könnte ich das in einem Repository verwenden? Oder würde ich kein Repo verwenden und nur dieses Objekt in meinem Dienst verwenden?
Webnet

Verwenden Sie spring-data-jpa?
Zagyi

@ Webnet Ich bin ein bisschen neu in Spring selbst, aber es
scheint

Haben Sie Spring JDBCTemplate ausprobiert?
BlackJoker

Antworten:


133

Mit der Annotation @Query können native Abfragen ausgeführt werden, indem das Flag nativeQuery auf true gesetzt wird.

Zitat aus Spring Data JPA- Referenzdokumenten .

In diesem Abschnitt erfahren Sie auch, wie Sie dies mit einer benannten nativen Abfrage tun.


13
@ user454322, Parameter beginnen mit 1, also ist es:@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
Jacob van Lingen

nativeQuery = true hat mich vor IllegalArgumentException
Reza

45

JA, Sie können dies auf folgende Weise tun:

1. Durch CrudRepository (Projektion)

Spring Data Repositories geben normalerweise das Domänenmodell zurück, wenn Abfragemethoden verwendet werden. Manchmal müssen Sie jedoch aus verschiedenen Gründen die Ansicht dieses Modells ändern.

Angenommen, Ihre Entität sieht folgendermaßen aus:

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

Jetzt ist Ihre Projektionsklasse wie unten. Es können die Felder, die Sie benötigt.

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

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

Jetzt erhalten ArrayList<IUserProjection> findUserUsingRollNo(String rollNo)Sie die Liste der Benutzer.

2. Verwenden von EntityManager

Angenommen, Ihre Abfrage lautet " ID auswählen, Name von Benutzern mit roll_no = 1001 ".

Hier gibt die Abfrage ein Objekt mit der ID- und Namensspalte zurück. Ihre Antwortklasse ist wie folgt:

Ihre Antwortklasse lautet wie folgt:

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

Hier erhält der UserObject-Konstruktor ein Objektarray und legt Daten mit dem Objekt fest.

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

Ihre Funktion zum Ausführen von Abfragen ist wie folgt:

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

Hier müssen Sie folgende Pakete importieren:

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

Jetzt, in Ihrer Hauptklasse, müssen Sie diese Funktion aufrufen. Holen Sie sich zuerst EntityManager und rufen Sie diese getUserByRoll(EntityManager entityManager,String rollNo)Funktion auf. Das Anrufverfahren ist unten angegeben:

Hier sind die Importe

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

erhalten EntityManagervon dieser Art und Weise:

@PersistenceContext
private EntityManager entityManager;

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

Jetzt haben Sie Daten in diesem userObject.

Hinweis:

query.getSingleResult () gibt ein Objektarray zurück. Sie müssen die Spaltenposition und den Datentyp mit der Abfragespaltenposition pflegen.

select id,name from users where roll_no = 1001 

Abfrage ein Array zurückgeben und es ist [0] --> id and [1] -> name.

Weitere Infos finden Sie in diesem Thread und in diesem Thread

Vielen Dank :)


3

Es ist auch möglich, das Spring Data JDBC-Repository zu verwenden , ein Community-Projekt, das auf Spring Data Commons aufbaut, um ohne Verwendung von JPA auf Datenbanken mit unformatiertem SQL zuzugreifen.

Es ist weniger leistungsfähig als Spring Data JPA, aber wenn Sie eine einfache Lösung für einfache Projekte ohne Verwendung eines ORM wie Hibernate wünschen, ist diese Lösung einen Versuch wert.


3

wir können createNativeQuery ("Here Nagitive SQL Query") verwenden;

zum Beispiel :

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

9
Wäre nützlich / vollständig, wenn Sie auch zeigen würden, wie die emVariable erstellt wird.
ETL

1

Es ist möglich, eine Rohabfrage in einem Spring Repository zu verwenden.

      @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);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.