410013796724260
• Webmoney
R335386147728
Z369087728698
Чтение объектов в HibernateИзвлечение информации из базы данных в виде коллекции объектов Hibernate может выполнять с использованием :
В данной статье будут рассмотрены различные способы чтения данных без фильтрации и с фильтрацией на основе примера, представленного на странице связанных сущностей, где описаны структуры таблиц базы данных и связанные сущности. Т.е. на этой странице будет продолжено повествование о связанных сущностях с точки зрения их извлечения из БД. Чтение данных с использованием HQLHibernate может использовать свой мощный язык запросов Hibernate Query Language, который очень похож на родной SQL. В сравнении с SQL, HQL полностью объектно-ориентирован и использует понятия наследования, полиформизма и связывания. Подробное описание языка HQL будет представлено в ближайшие дни. Следующий метод демонстрирует чтение набора данных пользователей User. HQL запрос формируется с использованием наименования класса. После этого создается запрос Query методом createQuery(sql) объекта сессии и извлекаются данные методом list (). private void readUsers_HQL() { System.out.println("\n\nЧтение записей : HQL"); // HQL (Hibernate Query Language) String sql = "From " + User.class.getSimpleName(); System.out.println("sql = " + sql); List<User> users = session.createQuery(sql).list(); System.out.println("users.size = " + users.size()); for (Iterator<User> it = users.iterator(); it.hasNext();) { User user = (User) it.next(); System.out.println(user.toString()); } } Запросы Hibernate и данные выводятся в консоль (см. ниже). Обратите внимание, что при создании запроса Query методом createQuery(sql) Hibernate формирует соответствующий запрос чтения списка пользователей. Второй запрос по чтению связанных записей Auto формируется и выполняется уже при распечатке пользователя, т.е. при обращении к связанной сущности (lazy загрузка). Чтение записей : HQL sql = From User Hibernate: select user0_.id as id1_0_, user0_.login as login2_0_, user0_.name as name3_0_ from USERS user0_ users.size = 2 Hibernate: select autos0_.user_id as user_id3_0_0_, autos0_.aid as aid1_1_0_, autos0_.aid as aid1_1_1_, autos0_.name as name2_1_1_, autos0_.user_id as user_id3_1_1_ from autos autos0_ where autos0_.user_id=? User {id = 50, login = 'ivan, name = 'Иван', autos =[ Auto {id = 55, name = 'Volvo, user_id = 50}, Auto {id = 56, name = 'Skoda, user_id = 50}]} User {id = 51, login = 'serg, name = 'Сергей', autos =[]} Чтение данных с использованием native SQL-запросаHibernate позволяет выполнять native SQL-запросы с использованием org.hibernate.SQLQuery, который создается методом createSQLQuery(String) объекта сессии. Но необходимо учитывать, что в этом случае можно потерять все преимущества HQL (ассоциации, кэширование). Следующий код демонстрирует использование нативного запроса для получения коллекции пользователей. private void readUsers_SQL() { System.out.println("\n\nЧтение записей : SQL"); // Использование native SQL query String sql = "select ID, LOGIN, NAME from USERS"; Query query = session.createSQLQuery(sql).addEntity(User.class); List<User> users = query.list(); System.out.println("users.size = " + users.size()); for (Iterator<User> it = users.iterator(); it.hasNext();) { User user = (User) it.next(); System.out.println(user.toString()); } } При формировании объекта Query был добавлен класс User.class методом addEntity, в результате чего метод list объекта Query вернул коллекцию пользователей List<User>. Объект org.hibernate.SQLQuery расширяет возможности двух классов org.hibernate.Query, org.hibernate.SynchronizeableQuery и является потокобезопасным. Набор прочитанных данных выводится в консоль, представленную ниже. Обратите внимание, что также, как и для HQL, при использовании native SQL второй запрос чтения связанных сущностей формируется по мере необходимости, т.е. при обращении. Чтение записей : SQL Hibernate: select ID, LOGIN, NAME from USERS users.size = 2 Hibernate: select autos0_.user_id as user_id3_0_0_, \ autos0_.aid as aid1_1_0_, \ autos0_.aid as aid1_1_1_, \ autos0_.name as name2_1_1_, \ autos0_.user_id as user_id3_1_1_ \ from autos autos0_ where autos0_.user_id=? User {id = 50, login = 'ivan, name = 'Иван', autos =[ Auto {id = 55, name = 'Volvo, user_id = 50}, Auto {id = 56, name = 'Skoda, user_id = 50}]} User {id = 51, login = 'serg, name = 'Сергей', autos =[]} Чтение набора объектов, List<Object[]>При выполнении сложных нативных SQL-запросов для извлечения определенной информации можно сущности к объекту org.hibernate.Query не подключать. В этом случае метод list() объекта Query вернет коллекцию объектов List<Object[]>, как это показано в следующем коде. После этого список объектов можно парсить и использовать по назначению. private void readObjects() { System.out.println("\n\nЧтение объектов"); String sql = "select ID, LOGIN, NAME from USERS"; Query query = session.createSQLQuery(sql); List<Object[]> rows = query.list(); for(Object[] row : rows) { User user = new User(); user.setId (Integer.valueOf(row[0].toString())); user.setLogin (row[1].toString()); user.setName (row[2].toString()); System.out.println(user.toString()); } } В результате выполнения метода readObjects() в консоль будет выведена информация без подгрузки связанных сущностей Auto : Чтение объектов Hibernate: select ID, LOGIN, NAME from USERS User {id = 50, login = 'ivan, name = 'Иван', autos =[]} User {id = 51, login = 'serg, name = 'Сергей', autos =[]} Использование org.hibernate.CriteriaИнтерфейс org.hibernate.Criteria представляет собой объектно-ориентированный запрос на выборку в отношении конкретной сущности и позволяет выполнять запросы без написания SQL кода. Для создания экземпляров Criteria используется класс Session, который выступает в качестве фабрики. Следующий метод выполняет чтение списка пользователей с именем "Иван". При создании Criteria используется метод createCriteria объекта сессии Session, которому в качестве параметра передается класс объекта. Объект criteria имеет метод add, позволяющий выполнить фильтрацию данных. Для этого методу add необходимо передать параметр ограничения Restrictions с определенными условиями. private void readUsers_criteria() { System.out.println("\n\nCriteria API"); Criteria criteria; criteria = session.createCriteria(User.class) .add(Restrictions.eq("name", "Иван")); List<User> users = criteria.list(); for (Iterator<User> it = users.iterator(); it.hasNext();) { User user = (User) it.next(); System.out.println(user.toString()); } } Результат выполнения метода readUsers_criteria выведен в консоль : Criteria API Hibernate: select this_.id as id1_0_0_, \ this_.login as login2_0_0_, \ this_.name as name3_0_0_ \ from USERS this_ \ where this_.name=? Hibernate: select autos0_.user_id as user_id3_0_0_, \ autos0_.aid as aid1_1_0_, \ autos0_.aid as aid1_1_1_, \ autos0_.name as name2_1_1_, \ autos0_.user_id as user_id3_1_1_ from autos autos0_ where autos0_.user_id=? User {id = 50, login = 'ivan, name = 'Иван', autos =[ Auto {id = 55, name = 'Volvo, user_id = 50}, Auto {id = 56, name = 'Skoda, user_id = 50}]} Подробное описание org.hibernate.Criteria с примерами представлено здесь. Фильтрация данных в HibernateДля чтения данных с фильтрацией можно использовать как org.hibernate.Criteria, представленный выше, так и native SQL. Метод readUsers демонстрирует извлечение отдельной записи пользователя, у которой логин соответствует значению параметра метода "filter" : private void readUsers(final String filter) { String sql; // Использование native SQL query с условием sql = "select ID, LOGIN, NAME from USERS where login like :log"; Query query = session.createSQLQuery (sql) // SQL .addEntity (User.class) // Class .setParameter ("log", filter); // Condition List<User> users = query.list(); System.out.println("users.size = " + users.size()); for (Iterator<User> it = users.iterator(); it.hasNext();){ User user = (User) it.next(); System.out.println(user.toString()); } } При создании объекта SQLQuery (native SQL) была добавлена сущность (addEntity) и определен параметр "log" (setParameter). В консоли увидим следующую информацию : Hibernate: select ID, LOGIN, NAME from USERS where login like ? users.size = 1 User {id = 50, login = 'ivan, name = 'Иван', autos =[ Auto {id = 55, name = 'Volvo, user_id = 50}, Auto {id = 56, name = 'Skoda, user_id = 50}]} Чтение отдельной записиЕсли известен идентификатор сущности Id, то объект сессии Session позволяет прочитать запись. Для этого можно использовать метод get или load. Отличия методов get и load представлено на странице Hibernate в вопросах и ответах. Следующий код демонстрирует чтение записи пользователя с идентификатором Id=51 : User user = (User) session.load(User.class, 51); if (user != null) System.out.println("\n\n" + user.toString()); Скачать примерИсходный код рассмотренного на странице примера использования различных способов Hibernate для чтения данных в виде проекта Eclipse, включающий все необходимые библиотеки hibernate, можно скачать здесь (8.02 Mб). |