Можно ли использовать необработанный SQL в репозитории Spring


112

Мне нужно использовать необработанный SQL в репозитории данных Spring, возможно ли это? Все, что я вижу вокруг @Query, всегда основано на сущностях.



Как я могу использовать это в репозитории? Или я бы не использовал репо и просто использовал этот объект в своей службе?
Webnet

Вы используете spring-data-jpa?
zagyi

@Webnet Я сам немного новичок в Spring, но мне кажется, что вы могли бы использовать это как объект
Четтер Хаммин

вы пробовали Spring JDBCTemplate?
BlackJoker

Ответы:


133

Аннотация @Query позволяет выполнять собственные запросы, устанавливая для флага nativeQuery значение true.

Цитата из справочных документов Spring Data JPA .

Также см. Этот раздел о том, как сделать это с помощью именованного собственного запроса.


13
@ user454322, параметры начинаются с 1, так что это:@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
Якоб ван Линген

nativeQuery = true спас меня от исключения IllegalArgumentException
Реза

45

ДА, вы можете сделать это следующими способами:

1. Автор CrudRepository (проекция)

Репозитории данных Spring обычно возвращают модель предметной области при использовании методов запроса. Однако иногда вам может потребоваться изменить вид этой модели по разным причинам.

Предположим, ваша сущность такая:

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

Теперь ваш класс Projection выглядит как показано ниже. Это могут те поля, которые вам нужны.

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

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

Теперь ArrayList<IUserProjection> findUserUsingRollNo(String rollNo)вам будет предоставлен список пользователей.

2. Использование EntityManager

Предположим, ваш запрос - « выберите идентификатор, имя от пользователей, где roll_no = 1001 ».

Здесь запрос вернет объект с идентификатором и столбцом имени. Ваш класс Response выглядит следующим образом:

Ваш класс ответа похож на:

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

здесь конструктор UserObject получит массив объектов и установит данные с помощью объекта.

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

Ваша функция выполнения запроса выглядит следующим образом:

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

Здесь вам нужно импортировать следующие пакеты:

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

Теперь ваш основной класс, вы должны вызвать эту функцию. Сначала получите EntityManager и вызовите эту getUserByRoll(EntityManager entityManager,String rollNo)функцию. Процедура вызова приведена ниже:

Вот импорт

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

получить EntityManagerотсюда:

@PersistenceContext
private EntityManager entityManager;

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

Теперь у вас есть данные в этом userObject.

Примечание:

query.getSingleResult () возвращает массив объектов. Вы должны поддерживать положение столбца и тип данных с положением столбца запроса.

select id,name from users where roll_no = 1001 

запрос возвращает массив, и это [0] --> id and [1] -> name.

Более подробная информация , посетите эту нить и эту тему

Спасибо :)


3

Также можно использовать репозиторий Spring Data JDBC , который представляет собой проект сообщества, построенный на основе Spring Data Commons, для доступа к базам данных с необработанным SQL без использования JPA.

Он менее мощный, чем Spring Data JPA, но если вам нужно легкое решение для простых проектов без использования ORM, такого как Hibernate, это решение стоит попробовать.


3

мы можем использовать createNativeQuery («Здесь Nagitive SQL Query»);

например :

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

9
Было бы полезно / полно, если бы вы также показали, как создать emпеременную.
ETL

1

В репозитории 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);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.