Czy można używać surowego SQL w repozytorium Spring?


112

Muszę używać surowego kodu SQL w repozytorium danych Spring, czy to możliwe? Wszystko, co widzę, @Queryjest zawsze oparte na bytach.



Jak mogę tego użyć w repozytorium? A może nie użyłbym repozytorium i po prostu użyłbym tego obiektu w ramach mojej usługi?
Webnet

Czy używasz spring-data-jpa?
zagyi

@Webnet Jestem trochę nowych do wiosny siebie, ale wygląda mi się, że można używać, jako obiekt
Chetter Hummin

czy wypróbowałeś Spring JDBCTemplate?
BlackJoker,

Odpowiedzi:


133

Adnotacja @Query umożliwia wykonywanie zapytań natywnych przez ustawienie flagi nativeQuery na true.

Cytat z dokumentacji referencyjnej JPA Spring Data .

Zobacz również tę sekcję, aby dowiedzieć się, jak to zrobić za pomocą nazwanego zapytania natywnego.


13
@ user454322, parametry zaczynają się od 1, więc jest to:@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
Jacob van Lingen

nativeQuery = true uratował mnie przed IllegalArgumentException
Reza

45

TAK, możesz to zrobić na następujące sposoby:

1. Przez CrudRepository (projekcja)

Spring Data Repositories zwykle zwraca model domeny podczas korzystania z metod zapytań. Czasami jednak z różnych powodów może zajść potrzeba zmiany widoku tego modelu.

Załóżmy, że twoja jednostka wygląda tak:

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

Teraz twoja klasa Projection wygląda jak poniżej. Może te pola, których potrzebujesz.

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

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

Teraz ArrayList<IUserProjection> findUserUsingRollNo(String rollNo)poda Ci listę użytkowników.

2. Korzystanie z EntityManager

Załóżmy, że Twoje zapytanie to „ select id, name from users, gdzie roll_no = 1001 ”.

Tutaj zapytanie zwróci obiekt z kolumną id i nazwa. Twoja klasa odpowiedzi wygląda następująco:

Twoja klasa odpowiedzi jest następująca:

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

tutaj Konstruktor UserObject pobierze Object Array i ustawi dane za pomocą obiektu.

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

Twoja funkcja wykonująca zapytanie wygląda jak poniżej:

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

Tutaj musisz zaimportować poniższe pakiety:

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

Teraz twoja główna klasa, musisz wywołać tę funkcję. Najpierw pobierz EntityManager i wywołaj tę getUserByRoll(EntityManager entityManager,String rollNo)funkcję. Poniżej przedstawiono procedurę wywołania:

Oto import

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

dostać się w EntityManagerten sposób:

@PersistenceContext
private EntityManager entityManager;

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

Teraz masz dane w tym userObject.

Uwaga:

query.getSingleResult () zwracają tablicę obiektów. Musisz zachować pozycję kolumny i typ danych z pozycją kolumny zapytania.

select id,name from users where roll_no = 1001 

zapytanie zwraca tablicę i to jest [0] --> id and [1] -> name.

Więcej informacji znajdziesz w tym wątku i w tym wątku

Dzięki :)


3

Możliwe jest również wykorzystanie repozytorium Spring Data JDBC , które jest projektem społecznościowym zbudowanym na bazie Spring Data Commons w celu uzyskania dostępu do baz danych z surowym kodem SQL, bez użycia JPA.

Jest mniej wydajny niż Spring Data JPA, ale jeśli potrzebujesz lekkiego rozwiązania do prostych projektów bez użycia ORM, takiego jak Hibernate, to rozwiązanie warte wypróbowania.


3

możemy użyć createNativeQuery ("Tutaj Nagitive SQL Query");

na przykład :

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

9
Byłoby użyteczne / kompletne, gdybyś pokazał również, jak utworzyć emzmienną.
ETL

1

Możliwe jest użycie surowego zapytania w repozytorium 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);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.