JPA — создание собственного запроса на чистом SQL
Создание собственного запроса на чистом SQL в JPA.
Используемые технологии
- Spring 4.1.5.RELEASE
- Hibernate 5.0.1.Final
- JPA 2.1
- MySQL 5.6.25
- IntelliJ IDEA 14
- Maven 3.2.5
1. Структура проекта
Настройки взяты из JPA – пример приложения Hello World, используемые здесь сущности взяты в измененной версии JPA – операции INSERT, UPDATE, DELETE.
2. Создание собственного запроса в JPA
Если вам требуется полный контроль над запросом, который будет отправлен базе данных, то вам необходимо создать так называемый NativeQuery — запрос на чистом sql. Для демонстрации такого запроса был создан метод findAllByNativeQuery:
1 2 3 4 5 |
/* names from columns! not ContactEntity properties */ final static String ALL_CONTACT_NATIVE_QUERY = "select id, first_name, last_name, birth_date, version from contact"; public List<ContactEntity> findAllByNativeQuery() { return em.createNativeQuery(ALL_CONTACT_NATIVE_QUERY, ContactEntity.class).getResultList(); } |
Обратите внимание, что в запросе указываются не имена свойств из сущностного класса, а реальные имена столбцов из базы данных:
1 2 3 4 5 6 |
public class ContactEntity { private Integer id; private String firstName; private String lastName; private Date birthDate; private int version; |
3. JPA — собственный запрос с отображением результирующего набора SQL
Еще одним способом создания собственного запроса является указание аннотации @SqlResultSetMapping над классом:
1 2 3 4 5 |
@SqlResultSetMapping( name = "nativeSqlResult", entities = @EntityResult(entityClass = ContactEntity.class) ) public class ContactEntity { |
Здесь для сущностного класса было определено отображение результирующего набора SQL по имени nativeSqlResult с указанием в атрибуте entityClass самого класса Contact. В JPA поддерживается более сложное отображение для множества сущностей,а также отображение вплоть до уровня отдельных столбцов.
Запрос похож на предыдущий, только возвращаемый результат изменен с указания класса на имя, указанное в аннотации:
1 2 3 |
public List<ContactEntity> findAllByNativeQuery2() { return em.createNativeQuery(ALL_CONTACT_NATIVE_QUERY, "nativeSqlResult").getResultList(); } |
4. Тестирование запроса
1 2 3 4 5 6 7 8 9 10 11 |
private static void simpleNativeQuery(GenericXmlApplicationContext ctx) { ContactService service = ctx.getBean("jpaContactService", ContactService.class); List<ContactEntity> contacts = service.findAllByNativeQuery(); List<ContactEntity> contacts2 = service.findAllByNativeQuery2(); for (ContactEntity c : contacts) { System.out.println(c); } System.out.println("Contacts = Contacts2: " + contacts.equals(contacts2)); } |
Исходные коды
JPA SQL — база данных.
5