Книга 1 - Начальные сведения
Книга 2 - Более профессиональный подход |
Студенческий отдел кадров Hibernate - пакет для DAO
Самая главная задача Hibernate - сделать так, чтобы разработчик думал в терминах объектов.
Причем не просто на уровне таблиц - на уровне отношений между таблицами. Т.е. если тот же
студент учится в группе, то связь должна быть на уровне объектов, а не на уровне поля
groupID у студента. Иными словами - загруженный
объект "Студент" должен иметь ссылку на объект "Группа". Мало того - для получения данных
о группе объект "Студент" не надо делать явный запрос к базе данных. Эту функцию
должен взять на себя Hibernate - в коде на Java мы просто должны вызывать метод
student.getGroup() Для решения своих задач Hibernate должен получить от разработчика следующую информацию:
С другой стороны обольщаться не стоит - Hibernate не так уж и здорово решает абсолютно все задачи. Например, сложные запросы, которые часто требуются для создания головоломных отчетов, часто проще и эффективнее сделать на SQL. Hibernate позволяет это сделать - в нем можно создать обычный SQL-запрос. Также массовые изменения в нем делаются не очень эффективно. И еще я бы выделил не всегда удачную реализацию отношений - особенно это касается отношения многие-ко-многим - при редактировани такого списка Hibernate просто удаляет все старые отношения и заменяет их на новые. В общем смотрите, сравнивайте, оптимизируйте. Но все-таки Hobernate существенно облегчает работу с базой данных и значительно упрощает код Вашего приложения. Ну что же - приступим. Для начала вам необходимо скачать сам пакет. Зайдите на страницу Hibernate. Слева будет в меню, в котором мы выбираем пункт Download. В списке реализаций выбираем "Hibernate Core". Я буду использовать версию 3.3.1.GA. Само собой, что со временем она устареет, но будем надеятся, что совместимость поможет разобраться и с более новой версией. Чтобы сразу снять все вопросы по поводу остальных средств разработки:
Предварительная настройка окружения
Данный раздел предназначен для тех, кто никогда не работал с NetBeans. Т.к. часто можно видеть
вопросы "Как подключить библиотеку ?", "Как запустить программы ?" - постараюсь снять некоторые
из них.
Теперь приступим к установке и настройке NetBeans. В общем-то ничего сложного в установке нет -
единственное, что может вызвать какие-то раздумья - это настройка JDK. Но обычно NetBeans находит
его сам (очень подозреваю, что он используется переменную JAVA-HOME).
Нажмите кнопку "New library..." и введите в форме название нашей библиотеки - StudentLibrary. После этого нажмите OK.
Теперь у нас есть библиотека, в которую мы можем добавлять наши JAR-файлы. Что очень удобно. Теперь
в проекте нам будет достаточно установит ссылку на нашу библиотеку и проект получит доступ ко всем
JAR-файлам, которые в ней есть. Думаю, что вы догадались, как пользоваться кнопками редактирования
содержимого библиотеки. они находятся с правой стороны формы.
Заключительное действие - подключение библиотеки к проекту. В общем-то ничего сложного тут тоже нет. Щелкните правой кнопкой мыши на разделе Libraries с окне со структурой проекта и выберите в нем пункт "Add Library...". Дальше выбираете нашу замечательную библиотеку. В общем-то и все. Что еще важно отметить - система автоматически отслеживает изменения в нашей библиотеке. Если мы добавим новый JAR-файл - тут же этот файл будет отображен на структуре используемых файлов.
Как видно на рисунке - теперь в библиотеке два файла. Я просто добавил новый JAR. Необходимые библиотекиВсе библиотеки, необходимяе для проекта "Студенческий отдел кадров" находятся ЗДЕСЬ
Для текущего проекта нам будет достаточно этих библиотек. Можно прямо тут и качать Так что содержимое библиотеки StudentsLibrary должно выглядеть приблизительно вот так:
В дальнейшем я не буду столь подробно останавливаться на библиотеках - буду просто приводить их список и вы должны будете сами все устанавливать. Думаю, что справитесь. Hibernate - первое приложение
Т.к. наша база данных включает в себя несколько таблиц и к тому же в ней есть сложные отношения, первые
шаги мы сделаем с одной таблицей - думаю, что так будет проще и понятнее. После того, как мы увидим и
попробуем простые вещи, нам будет проще построит полное приложение.
Как я уже говорил, Hibernate включает в себя как минимум две важные вещи - параметры соединения с базой
данных и описание (отображение) классов относительно таблиц.
Теперь я приведу структуру файлов, которые мы будем использовать в нашем маленьком проекте. Все они расположены в папке scr нашего проекта.
А теперь мы постепенно разберем все файлы, которые у нас здесь представлены. Начнем с файла hibernate.cfg.xml. hibernate.cfg.xml <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://127.0.0.1:3306/db_applicant</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size">1</property> <!-- Enable Hibernate's automatic session context management --> <property name="current_session_context_class">thread</property> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- Mapping files --> <mapping resource="students/entity/Profession.hbm.xml"/> </session-factory> </hibernate-configuration>
В приципе здесь представлены достаточно очевидные вещи. При небольшом усилии вы сами сможете
разобрать что и зачем. Но я все-таки пробегусь по именам.
Следующий интересный файл - это Profession.hbm.xml. Он описывает как наш класс Profession связан с таблицей PROFESSION. Давайте сначала приведем файл Profession.java Profession.java package students.entity; public class Profession { private Long professionId; private String professionName; public Long getProfessionId() { return professionId; } public void setProfessionId(Long professionId) { this.professionId = professionId; } public String getProfessionName() { return professionName; } public void setProfessionName(String professionName) { this.professionName = professionName; } }
Здесь в общем-то все очень просто - есть класс с полями, где можно хранить данные. Конечно же
вам надо использовать средства IDE, которые позволяют по набранным полям сразу сгенерировать
set/get методы. А теперь давайте рассмотрим файл Profession.hbm.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="students.entity"> <class name="Profession" table="profession"> <id name="professionId" column="profession_id"> <generator class="native"/> </id> <property name="professionName" column="profession_name"/> </class> </hibernate-mapping>
Здесь мы видим достаточно простое описание связи между таблицей и классом. Давайте остановимся на
некоторых атрибутах и тэгах
Нам осталось немного. Теперь на очереди файл HibernateUtil.java package students.utils; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory; static { try { // Create the SessionFactory from hibernate.cfg.xml sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } } Я не стал даже комментарии убирать - у меня этот файл существует уже несколько лет. И я его просто иногда копирую. В итоге здесь тоже ничего особо сложного нет. Я выделю два момента:
Ну и наконец наш главный файл для запуска и демонстрации Main.java package students; import students.entity.Profession; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import org.hibernate.Session; import students.utils.HibernateUtil; public class Main { // Данный метод просто показывает, как делается запрос при работе на уровне JDBC private void oldJDBC() { Connection connection = null; Statement statement = null; ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/db_applicant", "root", "root"); statement = connection.createStatement(); List<Profession> list = new ArrayList<Profession>(); rs = statement.executeQuery("select profession_id, profession_name from profession " + "order by profession_name"); while (rs.next()) { Profession r = new Profession(); r.setProfessionId(rs.getLong("profession_id")); r.setProfessionName(rs.getString("profession_name")); list.add(r); System.out.println(r.getProfessionId() + ":" + r.getProfessionName()); } } catch (SQLException ex) { ex.printStackTrace(); System.err.println("Error SQL execution: " + ex.getMessage()); } catch (ClassNotFoundException ex) { ex.printStackTrace(); System.err.println("Error SQL execution: " + ex.getMessage()); } finally { try { if (rs != null) { rs.close(); } if (statement != null) { statement.close(); } if (connection != null) { connection.close(); } } catch (SQLException ex) { ex.printStackTrace(); System.err.println("Error: " + ex.getMessage()); } } } // Метод добавляет новую запись в таблицу PROFESSION private void addProfession(String name) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Profession r= new Profession(); r.setProfessionName(name); session.save(r); session.getTransaction().commit(); } // Метод возвращает список профессий private List<Profession> listProfession() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); List<Profession> result = session.createQuery("from Profession order by professionName").list(); session.getTransaction().commit(); return result; } // Метод удаляет по очереди все записи, которые ему переданы в виде списка private void deleteProfessions(List<Profession> result) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); for(Profession p : result) { System.out.println("Delete:"+p.getProfessionId()+":"+p.getProfessionName()); session.delete(p); //session.flush(); } session.getTransaction().commit(); } // Методу удаляет одну запись private void deleteEntity(Object o) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); session.delete(o); session.flush(); session.getTransaction().commit(); } public static void main(String[] args) { Main main = new Main(); // Вызов "старого стиля" main.oldJDBC(); // Добавление новых профессий main.addProfession("Profession_1"); main.addProfession("Profession_2"); main.addProfession("Profession_3"); main.addProfession("Profession_4"); main.addProfession("Profession_5"); // Вариант вызова списка List<Profession> result = main.listProfession(); // Вариант вызова удаления одной записи result = main.listProfession(); main.deleteEntity(result.get(0)); // Вариант вызова списка и последующее удаление result = main.listProfession(); main.deleteProfessions(result); } }
Вся суть методов для редактирования сводится к одному - создание сессии (коннекта) к базе
(это объект класса Session) с помощью уже описанных классов
HibernateUtil и SessionFactory.
Объект session в общем-то не является непосредственным коннектом -
более правильно обозначит его функцию как "ответственный за работу с базой данных". В общем это все, что я хотел бы рассказать для начального шага в занимательный мир Hibernate. А теперь мы можем посмотреть более подробный рассказ - Часть 17 - Hibernate. Запись в виде XML-файлов.. Архив с исходными кодами: Исходный код |