2.1 Въведение в класовете Query

Между другото, друг важен момент е помощният клас Query. Можете да го видите в този пример:

public List<Employee> getAllEmployes() {
    try (Session session = sessionFactory.openSession()) {
            Query<Employee> query = session.createQuery("from Employee", Employee.class);
            return query.list();
    }
}

Всъщност Query е интерфейс и има няколко реализации за различни случаи. Но за простота ще продължа да го наричам клас. Това е, да кажем, клас в широк смисъл - от гледна точка на ООП.

Забележка. Имаше два класа:

  • Заявка за описание на заявката.
  • TypedQuery за описание на заявка с известен тип.

Първият се появи, когато Hibernate вече съществуваше и все още нямаше генерични продукти. След това, след излизането на JDK 5, към Hibernate беше добавен друг клас - TypedQuery, който вече поддържаше въвеждането на резултата от заявката.

Но доколкото си спомням, като се започне с 5-та version на Hibernate, беше оставен само един въведен клас и той сега се нарича Query.

Стандартният начин за създаване на заявка е:


Query<Employee> query = session.createQuery("from Employee", Employee.class);

Научихте How да създавате обекти на заявка, но How да изпълнявате тези заявки?

Тук е още по-просто - просто извикваме метода list() на обекта Query:


Query<Employee> query = session.createQuery("from Employee", Employee.class);
List<Employee> resultLіst = query.list();

Методът list() има синоним на JPA, метод, който прави същото, но се нарича getResultList() . Понякога можете да го видите в code, написан от други програмисти.

Между другото, ако заявката предполага, че резултатът ще бъде в един резултат, тогава е по-лесно да използвате метода uniqueResult() за извикване на заявката .


Query<Employee> query = session.createQuery("from Employee where id = 1", Employee.class);
Employee result = query.uniqueResult();

Методът uniqueResult() има синоним на JPA, методът singleResult() . Той беше въведен за съвместимост на Hibernate със стандарта JPA. Той прави абсолютно същото.

2.2 Методи на клас заявки

Всъщност класът Query има много различни методи. По-долу ще говоря за още три от тях.

Първият е методът stream() . И неговият JPA синоним getResultStream() .

И двата метода връщат поток от данни instead of списък. Този подход може да бъде много ефективен, когато не се нуждаете от всички обекти, получени в резултат на заявка наведнъж. Или има възможност да се използва само първият от тях.

Пример:


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
Stream<Employee> stream = query.stream();

Вторият метод е методът executeUpdate() . Можете да напишете заявка, която ще промени нещо в базата данни. В този случай е необходимо Hibernate да не използва транзакция само за четене при достъп до базата данни.

Пример за заявка: решихме да повишим нивото на всички потребители с 1.


Query<User> query = session.createQuery("update User set level=level+1", User.class);
int count = query.executeUpdate();

Методът executeUpdate() ще върне броя редове, които действително са бor променени.

И накрая третият метод е scroll() . Ще ви разкажем малко повече за него.

2.3 Методи на клас превъртане

Този метод е донякъде подобен на метода stream() . Само той ви позволява да се движите през списъка с резултати, без изобщо да ги изваждате. Тоест можете да изпълните заявка, след това да я превъртите до мorонния ред на резултата и да започнете да четете данни от там.

Такъв напреднал итератор.


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
ScrollableResults<Employee> scroll = query.scroll();

Обектът ScrollableResults има следните методи:

Метод Описание
R get() Връща текущия елемент
следващия() Премества показалеца към следващия елемент
предишен () Премества показалеца към предишния елемент
превъртане (int size) Превъртете напред по редове за размер
позиция (int pos) Прави елемента pos номер текущия елемент
последно() Сега текущият елемент е последен
първи() Сега текущият елемент е първият
getRowNumber() Връща номера на текущия ред
setRowNumber() Задава номера на текущия ред

Да приемем, че сте изпълнor заявка и искате да получите последния елемент. Ето How да го направите:


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
ScrollableResults<Employee> scroll = query.scroll();
scroll.last();
Employee lastEmployee = scroll.get();