Изучаем Java EE 7 - [57]
• @Entity проинформирует поставщика постоянства о том, что этот класс является сущностью и ему следует управлять им.
• Аннотации @NamedQueries и @NamedQuery будут определять два именованных запроса, которые станут использовать JPQL для извлечения информации о книгах из базы данных.
• @Id будет определять атрибут id как первичный ключ.
• Аннотация @GeneratedValue проинформирует поставщика постоянства о необходимости автоматического генерирования первичного ключа с использованием инструмента id основной базы данных.
>package org.agoncal.book.javaee7.chapter04;
>@Entity
>@NamedQueries({
>··@NamedQuery(name = "findAllBooks", query = "SELECT b FROM Book b"),
>··@NamedQuery(name = "findBookH2G2", query = "SELECT b FROM Book b
>WHERE b.title ='H2G2'")
>})
>public class Book {
>··@Id @GeneratedValue
>··private Long id;
>··@NotNull
>··private String title;
>··private Float price;
>··@Size(min = 10, max = 2000)
>··private String description;
>··private String isbn;
>··private Integer nbOfPage;
>··private Boolean illustrations;
>··// Конструкторы, геттеры, сеттеры
>}
Обратите внимание, что для лучшей удобочитаемости я убрал конструктор, геттеры и сеттеры этого класса. Как видно из кода, если не считать нескольких аннотаций, Book представляет собой простой POJO. А теперь напишем класс Main, который будет обеспечивать постоянство Book в базе данных.
Написание класса Main
Класс Main, показанный в листинге 4.8, будет располагаться в том же пакете, что и сущность Book. Он начнет с того, что создаст новый экземпляр Book (с использованием ключевого слова Java new) и задаст значения для его атрибутов. Здесь не будет ничего особенного, лишь чистый Java-код. Затем он воспользуется классом Persistence для получения экземпляра EntityManagerFactory, ссылающегося на единицу сохраняемости с именем chapter04PU, которую я охарактеризую позднее, в разделе «Написание единицы сохраняемости». EntityManagerFactory создаст экземпляр EntityManager (переменная em). Как уже отмечалось ранее, EntityManager является центральным элементом JPA в том смысле, что способен начать транзакцию, обеспечить постоянство объекта Book с помощью метода EntityManager.persist(), а затем произвести фиксацию транзакции. В конце метода main() как EntityManager, так и EntityManagerFactory будут закрыты, чтобы высвободить ресурсы поставщика.
>package org.agoncal.book.javaee7.chapter04;
>public class Main {
>··public static void main(String[] args) {
>····// Создает экземпляр Book
>····Book book = new Book("H2G2", "Автостопом по Галактике",
>····12.5F, "1-84023-742-2", 354, false);
>····// Получает EntityManager и транзакцию
>····EntityManagerFactory emf =
>Persistence.createEntityManagerFactory("chapter04PU");
>····EntityManager em = emf.createEntityManager();
>····// Обеспечивает постоянство Book в базе данных
>····EntityTransaction tx = em.getTransaction();
>····tx.begin();
>····em.persist(book);
>····tx.commit();
>····// Закрывает EntityManager и EntityManagerFactory
>····em.close();
>····emf.close();
>··}
>}
Опять-таки ради удобочитаемости я убрал обработку исключений. Если будет иметь место исключение постоянства, то вам придется откатить транзакцию, зарегистрировать сообщение и закрыть EntityManager в финальном блоке.
Написание интеграционного теста BookIT
Одна из жалоб на предыдущие версии Entity CMP 2.x заключалась в сложности интеграционного тестирования постоянных компонентов. Один из основных выигрышных моментов JPA состоит в том, что вы можете с легкостью тестировать сущности без необходимости в работающем сервере приложений или реальной базе данных. Но какие именно функции вы можете протестировать? Сущности как таковые обычно не нуждаются в тестировании в изоляции. Большинство методов сущностей представляют собой простые геттеры или сеттеры. Проверка того, что сеттер присваивает значение атрибуту, а также того, что соответствующий геттер извлекает то же значение, не имеет особой ценности (если только побочный эффект не проявится в геттерах или сеттерах). Поэтому модульное тестирование сущностей представляет ограниченный интерес.
А как насчет тестирования запросов к базе данных? Нужно ли убедиться в том, что запрос findBookH2G2 корректен? Или вводить информацию в базу данных и тестировать комплексные запросы, возвращающие множественные значения? Такие интеграционные тесты потребовали бы реальной базы данных с реальной информацией, либо вы стали бы проводить модульное тестирование в изоляции, пытаясь симулировать запрос. Хорошее компромиссное решение — использовать базу данных в оперативной памяти и JPA-транзакции. CRUD-операции и JPQL-запросы могут быть протестированы с применением очень легковесной базы данных, которая не потребует запуска отдельного процесса (понадобится лишь добавить файл с расширением. jar, используя путь к соответствующему классу). Рассмотрим, как придется задействовать наш класс BookIT во встроенном режиме Derby.
Maven использует два разных каталога, один из которых применяется для размещения кода главного приложения, а другой — для тестовых классов. Класс BookIT, показанный в листинге 4.9, располагается в каталоге src/test/java и осуществляет тестирование на предмет того, может ли менеджер сущностей обеспечить постоянство сущности Book и извлекать ее из базы данных, а также удостоверяется в том, что применяются ограничения Bean Validation.
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.