Рубрики
Без рубрики

Руководство по хранимым процедурам с помощью JPA

Краткое практическое руководство по использованию хранимых процедур с помощью Java Persistence API (JPA).

Автор оригинала: baeldung.

1. введение

В этом кратком руководстве мы рассмотрим использование хранимых процедур в Java Persistence API (JPA).

2. Настройка проекта

2.1. Настройка Maven

Сначала нам нужно определить следующие зависимости в вашем pom.xml :

  • javax.javaee-api – поскольку он включает в себя API JPA
  • реализация API JPA – в этом примере мы будем использовать Hibernate , но EclipseLink также будет приемлемой альтернативой
  • a MySQL База данных

    7.0
    11.2.0.4
    5.1.38


    
        javax
        javaee-api
        ${jee.version}
        provided
    
    
        org.hibernate
        hibernate-core
        ${hibernate.version}
    
    
        mysql
        mysql-connector-java
        ${mysql.version}
    

2.2. Определение единицы Стойкости

Вторым шагом является создание src/main/resources/META-INF/persistence.xml файл – который содержит определения единиц сохранения:




    
        org.hibernate.jpa.HibernatePersistenceProvider
        com.baeldung.jpa.model.Car
        
            
            
            
            
            
            
        
    

Все определенные свойства гибернации не нужны, если вы ссылаетесь на источник данных JNDI (среды JEE):

java:jboss/datasources/JpaStoredProcedure

2.3. Сценарий создания таблицы

Давайте теперь создадим Стол ( АВТОМОБИЛЬ ) – с тремя атрибутами: ID, МОДЕЛЬ и ГОД :

CREATE TABLE `car` (
  `ID` int(10) NOT NULL AUTO_INCREMENT,
  `MODEL` varchar(50) NOT NULL,
  `YEAR` int(4) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

Конечно, предполагалось, что схема БД и разрешения уже существуют.

2.4. Создание хранимых процедур в БД

Самым последним шагом перед переходом к коду java является создание хранимой процедуры в нашей базе данных MySQL:

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `FIND_CAR_BY_YEAR`(in p_year int)
begin
SELECT ID, MODEL, YEAR
    FROM CAR
    WHERE YEAR = p_year;
end
$$
DELIMITER ;

3. Хранимая процедура JPA

Теперь мы готовы использовать JPA для связи с базой данных и выполнения определенной нами хранимой процедуры.

Как только мы это сделаем, мы также сможем перебирать результаты в виде Списка автомобиля.

3.1. Юридическое Лицо Автомобиля

Под сущностью Car , которая будет сопоставлена с таблицей базы данных CAR менеджером сущностей.

Обратите внимание, что мы также определяем нашу хранимую процедуру непосредственно на объекте с помощью аннотации @NamedStoredProcedureQueries :

@Entity
@Table(name = "CAR")
@NamedStoredProcedureQueries({
  @NamedStoredProcedureQuery(
    name = "findByYearProcedure", 
    procedureName = "FIND_CAR_BY_YEAR", 
    resultClasses = { Car.class }, 
    parameters = { 
        @StoredProcedureParameter(
          name = "p_year", 
          type = Integer.class, 
          mode = ParameterMode.IN) }) 
})
public class Car {

    private long id;
    private String model;
    private Integer year;

    public Car(String model, Integer year) {
        this.model = model;
        this.year = year;
    }

    public Car() {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", unique = true, nullable = false, scale = 0)
    public long getId() {
        return id;
    }

    @Column(name = "MODEL")
    public String getModel() {
        return model;
    }

    @Column(name = "YEAR")
    public Integer getYear() {
        return year;
    }
    
    // standard setter methods
}

3.2. Доступ к базе данных

Теперь, когда все определено и на месте, давайте напишем пару тестов, фактически использующих JPA для выполнения процедуры.

Мы собираемся вернуть все Автомобили в данный год :

public class StoredProcedureTest {

    private static EntityManagerFactory factory = null;
    private static EntityManager entityManager = null;

    @BeforeClass
    public static void init() {
        factory = Persistence.createEntityManagerFactory("jpa-db");
        entityManager = factory.createEntityManager();
    }

    @Test
    public void findCarsByYearWithNamedStored() {
        StoredProcedureQuery findByYearProcedure = 
          entityManager.createNamedStoredProcedureQuery("findByYearProcedure");
        
        StoredProcedureQuery storedProcedure = 
          findByYearProcedure.setParameter("p_year", 2015);
        
        storedProcedure.getResultList()
          .forEach(c -> Assert.assertEquals(new Integer(2015), ((Car) c).getYear())); 
    }

    @Test
    public void findCarsByYearNoNamedStored() {
        StoredProcedureQuery storedProcedure = 
          entityManager
            .createStoredProcedureQuery("FIND_CAR_BY_YEAR",Car.class)
            .registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN)
            .setParameter(1, 2015);
       
        storedProcedure.getResultList()
          .forEach(c -> Assert.assertEquals(new Integer(2015), ((Car) c).getYear()));
    }

}

Обратите внимание, что во втором тесте мы больше не используем хранимую процедуру, которую мы определили для сущности . Вместо этого мы определяем процедуру с нуля.

Это может быть очень полезно, когда вам нужно использовать хранимые процедуры, но у вас нет возможности изменить свои сущности и перекомпилировать их.

4. Заключение

В этом уроке мы обсуждали использование хранимой процедуры с API сохранения Java.

Пример, используемый в этой статье, доступен в качестве примера проекта в GitHub .