Hibernate 3 удаление, изменение и загрузка pojo-объектов

В прошлой статье мы научились настраивать hibernate,  в этой научимся сохранять, редактировать и удалять. Немножко теории есть стандарт Как нужно пользоваться  hibernat'om. Открываем сессию(Session), получаем все необходимые нам данные, удаляем, вычисляем, редактируем, выводим данные пользователю, сохраняем все данные, сессию закрываем. После закрытия сессии не желательно использовать данные сохраненные в pojo-объекте. До тех пор пока вы используете объекты, полученные из Hibernate, вы должны иметь открытой сессию, в которой были получены эти объекты, и иметь активную транзакцию!
Использовать эти объекты можно только в однопоточной среде! Иначе со стороны Hibernate возможны ошибки (Рекомендация разрабочиков Hibernate). Если что-то пойдет не так Hibernate выкидывает ошибку HibernateException  и её надо вылавливать в catch, Для Hibernate ошибка HibernateException то же самое что Exception в Java т.е. она стоит во главе иерархии ошибок Hibernate.
Приведу стандартный набор кода:

        ....
        // получаем сессию
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        try {
            // начинаем транзакцию
            session.beginTransaction();
            // создаем, загружаем, редактирум , удаляем данные
            ....
            //в данном случае создаем pojo-объек и сохраняем данные в БД
            Person person = new Person();
            //заполняем его данными
            person.setFirstName("Vit");
            person.setLastName("Lo");
            Calendar c =Calendar.getInstance();
            c.set(2009, 11, 4);
            person.setBirthDate(c.getTime());
            //сохраняем в сессии и в БД применяем транзакцию
            session.save(person);
            session.getTransaction().commit();
        }catch( HibernateException e ) {
            // ошибка откатываем транзакцию
        session.getTransaction().rollback();
        ....
        }
        finally {
            //если открыта сессия закрываем её
            if (session.isOpen()) session.close();
        }
        ....

Давайте попробуем получить данные  pojo-объекта(Person) из сессии(session) это можно сделать несколькими способами, расмотрим их подробно:

1. В hibernate есть язык запросов HQL который оперирует не полями  как в SQL'e а вашими pojo-объектами(наш случай Person) и он очень похож на sql. Допустим нам нужно получить запись из БД с id=1, sql-запрос будет таким:

select * from persons where id=1

соответствующий HQL-запрос будет выглядеть так

from Person where id=1.

В место имени таблицы persons - имя pojo-объекта Person, select * - не нужен вообще так как нам в любом случаем возвращается 1 запись данных(pojo-объект Person).  За запросы отвечает Hibernate interfase Query давайте расмотрим пример:

//создаем запрос
Query q = session.createQuery("from Person where id = :id");
//устанавливаем значение
q.setInteger("id",1);
//получаем pojo-объект Person
Person p1 = (Person) q.uniqueResult();
//проверяем получи ли мы объект Person
if (p1!=null)
  //выводим данные
  System.out.println("Имя:"+p1.getFirstName()+"фамилия:"+p1.getLastName());

метод uniqueResult() гарантировано вернет 1 значение(pojo-объект Person) или
null - если нет записи с таким номером и вызовет ошибку(HibernateException)
если их будет больше 1.

2. В объекте Session присутствует два метода Load() и Get(), которые возвращают pojo-объект из БД по его идентификатору(id), возникает вопрос чем они отличаются? Опуская все нюансы скажу  что Load() вызовет исключение если не сможет вернуть объект, а Get() - null, если есть запись с таким id то pojo-объект:

....
 session.beginTransaction();
 // исключение нет в БД такой записи
 Person p2 = (Person) session.load(Person.class,250);
 System.out.println(p2.getFirstName()+" "+p2.getLastName());
 ....

 ....
 session.beginTransaction();
 // есть pojo-объект Person
 Person p2 = (Person) session.load(Person.class,2);
 if (p2!=null)
   System.out.println(p2.getFirstName()+" "+p2.getLastName());
 ....

3. Есть метод у интерфейса Query - list который возвращает коллекцию pojo-объектов расмотрим пример:

  ....
  //получаем сессию
  Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
  //начинаем новую транзакцию
  session2.beginTransaction();
  // готовим запрос
  Query q1 = session2.createQuery("from Person  p order by p.firstName");
  // получаем коллекцию pojo-объектов Person
  List<Person> p3 = q1.list();
  // выводим данные
  for ( Person p4 : p3  ) {
        System.out.println(p4.getFirstName()+" "+p4.getLastName());
  }
  // применяем транзакцию
  session2.getTransaction().commit();
  ....

Изменение данных выглядит так - получаем сессию, начинаем транзакцию, загружаем необходимые pojo-объекты и вызываем необходимые set-методы, применяем транзакцию. расмотрим на примере:

  ....
  //получаем сессию
  Session session3 = HibernateUtil.getSessionFactory().getCurrentSession();
  //начинаем новую транзакцию
  session3.beginTransaction();
  // готовим запрос
  Query q2 = session3.createQuery("from Person  p order by p.firstName");
  // получаем коллекцию pojo-объектов Person
  List<Person> p5 = q2.list();
  // изменяем данные
  for ( Person p6 : p5  ) {
        p6.setFirstName(p6.getFirstName()+p6.getId());
        p6.setLastName(p6.getLastName()+p6.getId());
  }
  // применяем транзакцию
  session3.getTransaction().commit();
  ....

Удаление данных выглядит так - получаем сессию, начинаем транзакцию, загружаем необходимый pojo-объект и вызываем delete() метод сессии, применяем транзакцию. расмотрим на примере:

....
 session.beginTransaction();
 // загружаем pojo-объект Person
 Person p2 = (Person) session.load(Person.class,2);
 if (p2!=null)
   // удаляем объект и данные из таблицы БД
   session2.delete(p2);
 // применяем транзакцию
 session.getTransaction().commit();
 ....

этот способ подходит для удаления 1 - 2 записей из таблицы БД, т.к. мы сначала  должны загрузить данные и только потом можем удалять, а если нам надо удалить допустим все данные из таблицы то подойдет следующий способ без загрузки данных:

  session.createQuery("delete from Person").executeUpdate();

есть еще одна вкусная фишка в hibernate это так называемый pagging т.е. если мне нужно допустим получить только 10 записей из таблицы БД(pojo-объектов Person) начиная с 6 записи то я пишу такой код:

....
Query q1 = session2.createQuery("from Person  p order by p.firstName");
List<Person> p3 = q1.setFirstResult(5).setMaxResults(10).list();
....

Ну вот, научились мы удалять, изменять и загружать pojo-объекты :) :) :)
 

ВложениеРазмер
hibernat3_2.zip10.62 кб

Отличная статья, спасибо!

Отличная статья, спасибо! Особенно радует, что прилагается архив с рассмотренным кодом.

Это еще цветочки, на

Это еще цветочки, на следуюшей неделе дас бог напишу еще 1 статью как за mapping  2 таблицы и расмотрю связи между ними :) :) вот сдесь будут ягодки :) :) :) 

Что-то меня начинают терзать

Что-то меня начинают терзать смутные сомнения, что легче освоить хорошенько SQL и JDBC, чем Hibernate. Надеюсь, ты докажешь обратное :)

Самая главная задача

Самая главная задача Hibernate - сделать так, чтобы разработчик думал в терминах объектов, что несказанно облегчает труд. Конечно, если нужно выдать какой-нибудь громоздкий отчет, то лучше SQL не найти, а так в обыденной жизни без Hibernate просто тьма.

Действительно хорошая

Действительно хорошая Информативная статья! Киндайте ссылку на вторую статью - с удовольствием прочитаю)

Ссылка на предыдущую

Ссылка на предыдущую статью http://linux16.net/node/513 

Отправить комментарий

КАПЧА
Этот вопрос задается для того, чтобы выяснить, являетесь ли Вы человеком или представляете из себя автоматическую спам-рассылку.
CAPTCHA на основе изображений
Enter the characters (without spaces) shown in the image.