410013796724260
• Webmoney
R335386147728
Z369087728698
Обзор Hibernate Criteria APIОдним из способов манипулирования объектом и транслирования его в таблицу базы данных (БД) является Criteria API, который позволяет создавать запросы с критериями программным методом. Наиболее значимые области применения Criteria API :
Для создания объекта org.hibernate.Criteria используется метод createCriteria интерфейса сессии Session, которому в качестве параметра необходимо передать сущность. Следующий код формирует объект Criteria для выполнения транзакций с сущностью разработчика Developer. Criteria criteria = session.createCriteria (Developer.class); Чтение данныхСледующий код позволяет прочитать данные и сформировать коллекцию. Чтобы прочитать определенное количество записей необходимо использовать метод setMaxResults (int) объекта Criteria. Метод setFirstResult (int) определяет первую запись. Т.е. данные методы позволяют определить параметры OFFSET, LIMIT, используемые в SQL-запросах некоторых типов БД. Criteria criteria = session.createCriteria (Developer.class); criteria.setFirstResult(5); criteria.setMaxResults (10); List<Developer> developers = criteria.list(); Сортировка данных в запросе CriteriaДля сортировки данных в запросе используется метод addOrder, которому в качестве параметра необходимо передать порядок сортировки (Order) : // Сортировка набора по возрастанию значения поля firstName Criteria criteria = session.createCriteria (Developer.class) .addOrder(Order.asc("firstName")); // Сортировка набора по убыванию значения поля firstName criteria.addOrder(Order.desc("firstName"); Ограничения данных в запросе CriteriaДля ограничения/фильтрации объектов набора используется параметр Restrictions.[eq | lt | le | gt | ge | like | between | isNotNull | isNull]. Следующий код демонстрирует использование в критерии параметра Restrictions. // список разработчиков с опытом разработки больше или равен 3 Criteria criteria = session.createCriteria(Developer.class) .add(Restrictions.ge("experience", 3); // список разработчиков, у которых login начинается с 'serg' Criteria criteria = session.createCriteria(Developer.class) .add(Restrictions.like("login", "serg%"); // список разработчиков, у которых birth_date is null Criteria criteria = session.createCriteria(Developer.class) .add(Restrictions.isNull("birth_date"); // список разработчиков, у которых birth_date is not null: Criteria criteria = session.createCriteria(Developer.class) .add(Restrictions.isNotNull("birth_date"); Пример использования org.hibernate.CriteriaРассмотрим пример использования org.hibernate.Criteria и сущности Developer. В примере создадим и запишем новые сущности в базу данных, после чего извлечем определенные записи. При описании сущности будем использовать аннотации. По сути, это модифицированный пример использования Sequence для генерирования идентификаторов записей в Hibernate, описанный здесь. Поэтому ниже будут представлены только используемые методы, связанные с org.hibernate.Criteria. Сначала определим объекты базы данных. Таблица и генератор запросовВ примере потребуется таблица DEVELOPERS и генератор последовательностей SEQ_DEVELOPER в схеме SCOTT. CREATE TABLE SCOTT.DEVELOPERS ( ID INT NOT NULL, FIRST_NAME VARCHAR2(64) default NULL, LAST_NAME VARCHAR2(64) default NULL, SPECIALTY VARCHAR2(64) default NULL, EXPERIENCE INT default NULL, SALARY INT default NULL, CONSTRAINT pk_DEVELOPER_ID PRIMARY KEY (id), ); create sequence SCOTT.SEQ_DEVELOPER minvalue 1 start with 5 increment by 1 cache 2; Листинг сущности DeveloperПри описании сущности (методы set/get не отображены) используем аннотации. Подробнее об аннотациях, используемых при описании сущности, представлено здесь. @Entity @Table(name = "developers") public class Developer { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="dev_seq") @SequenceGenerator(name="dev_seq", sequenceName="SEQ_DEVELOPER", allocationSize=5) @Column(name="id") private int id; @Column(name="FIRST_NAME") private String firstName; @Column(name="LAST_NAME") private String lastName; @Column private String specialty; @Column private int experience; @Column private int salary; public Developer(int id, String firstName, String lastName, String specialty, int experience, int salary) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.specialty = specialty; this.experience = experience; this.salary = salary; } public Developer() {} // get/set @Override public String toString() { return "Developer [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", specialty=" + specialty + ", experience=" + experience + ", salary=" + salary + "]"; } } Сохранение новых записей в БДДля сохранения записей в таблице БД определяем массив DEVELOPERS и два метода. Первый метод addDevelopers в цикле перебирает массив данных и вызывает второй метод addDeveloper, который формирует объект Developer и сохраняет его в БД. private Session session = null; private final String[][] DEVELOPERS = { {"Сергей", "Ветров" , "Java Developer", "6", "2400"}, {"Олег" , "Мантров" , "C++ Developer" , "10", "2300"}, {"Остап" , "Бендер" , "C# Developer" , "5", "2200"}, {"Киса" , "Воробьянинов", "PHP Developer" , "4", "2500"} }; . . . private void addDevelopers() { Transaction transaction = null; transaction = session.beginTransaction(); for (int i = 0; i < DEVELOPERS.length; i++) { addDeveloper(DEVELOPERS[i][0], DEVELOPERS[i][1], DEVELOPERS[i][2], Integer.valueOf(DEVELOPERS[i][3]), Integer.valueOf(DEVELOPERS[i][4])); } transaction.commit(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private Integer addDeveloper(String firstName, String lastName, String specialty, int experience, int salary) { Integer developerId = null; Developer developer = new Developer(); developer.setFirstName (firstName ); developer.setLastName (lastName ); developer.setExperience(experience); developer.setSpecialty (specialty ); developer.setSalary (salary ); developerId = (Integer) session.save(developer); return developerId; } При выполнении метода addDevelopers в консоль приложения будет выведена информация, представленная ниже. Hibernate подготавливает один запрос получения идентификатора записи и для каждой записи отдельный SQL-запрос вставки. Hibernate: select SEQ_DEVELOPER.nextval from dual Hibernate: insert into developers (experience, FIRST_NAME, LAST_NAME, salary, specialty, id) values (?, ?, ?, ?, ?, ?) Hibernate: insert into developers (experience, FIRST_NAME, LAST_NAME, salary, specialty, id) values (?, ?, ?, ?, ?, ?) Hibernate: insert into developers (experience, FIRST_NAME, LAST_NAME, salary, specialty, id) values (?, ?, ?, ?, ?, ?) Hibernate: insert into developers (experience, FIRST_NAME, LAST_NAME, salary, specialty, id) values (?, ?, ?, ?, ?, ?) Фильтрация записейМетод listDevelopers позволяет прочитать записи разработчиков, у которых опыт работы превышает значение min_experience. В методе формируется объект criteria, которому добавляется условие (ограничение Restrictions) с параметром "experience" и значением min_experience. public void listDevelopers(final int min_experience) { Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Developer.class); criteria.add(Restrictions.gt("experience", min_experience)); List<Developer> developers = criteria.list(); for (Developer developer : developers) System.out.println(developer); transaction.commit(); } В результате выполнения метода listDevelopers в консоль будет выведена информация, представляющая сформированный hibernate запрос и прочитанные данные для значение min_experience равное 5 : Hibernate: select this_.id as id1_0_0_, this_.experience as experience2_0_0_, this_.FIRST_NAME as FIRST_NAME3_0_0_, this_.LAST_NAME as LAST_NAME4_0_0_, this_.salary as salary5_0_0_, this_.specialty as specialty6_0_0_ from developers this_ where this_.experience > ? Developer [id=45, firstName=Сергей, lastName=Ветров, specialty=Java Developer, experience=6, salary=2400] Developer [id=46, firstName=Олег, lastName=Мантров, specialty=C++ Developer, experience=10, salary=2300] Выполнение функции суммированияКак было описано выше Criteria можно использовать для выполнения агрегированных функций. Следующий метод totalSalary позволяет просуммировать заработок всех разработчиков. Для этого используется метод setProjection критерия, параметр которого определяет агрегированную функцию. Метод list вернет набор из одной записи, значение которой определяет результат выполненной функции. public void totalSalary() { Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Developer.class); criteria.setProjection(Projections.sum("salary")); List<Integer> totalSalary = criteria.list(); System.out.println("Заработок разработчиков : " + totalSalary.get(0)); transaction.commit(); } Выполнение метода выведет следующую информацию в консоль : SQL-запрос суммирования значения поля salary и значение : Hibernate: select sum(this_.salary) as y0_ from developers this_ Заработок разработчиков : 9400 Скачать примерИсходный код примера в виде проекта Eclipse hibernate-criteria.zip, включающий все необходимые библиотеки hibernate, можно скачать здесь (8.216 Mб). |