Пример использования Entity Beans - hello-world

advertisement
Пример использования Entity Beans
Оглавление
Пример использования Entity Beans ................................................................................................. 1
Интеграция с СУБД ....................................................................................................................... 2
Самый первый Entity Bean ........................................................................................................... 2
Промежуточная проверка ............................................................................................................. 4
Использование JPA из Session Bean ............................................................................................ 4
Тестирование ................................................................................................................................ 5
Интеграция с СУБД
Вернёмся к нашему Hello-приложению и продолжим его эволюцию. Чего в нем не
хватает – это интеграции AuthBean с СУБД, в которой хранится список пользователей.
Создадим таблицу USERS в MySQL как раз для этих целей:
CREATE
TABLE IF NOT EXISTS `c4f`.`USERS` (
`id` INT NOT NULL AUTO_INCREMENT,
`login` VARCHAR(45) NOT NULL,
`password` VARCHAR(45) NOT NULL,
`email` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`) ,
UNIQUE INDEX `login_UNIQUE` (`login` ASC) )
ENGINE = InnoDB;
Добавим нескольких пользователей:
INSERT INTO `c4f`.`USERS` (id, login, password, email)
VALUES (NULL, 'user1', 'password1', 'user1@gmail.com');
INSERT INTO `c4f`.`USERS` (id, login, password, email)
VALUES (NULL, 'user2', 'password2', 'user2@gmail.com');
Самый первый Entity Bean
Как мы выяснили на шаге 12, Entity Bean представляет собой класс, экземпляры
которого соответствуют записям БД. БД у нас уже появилась, осталось объявить
класс.
package com.company.ejb.entities;
import
import
import
import
javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.Id;
javax.persistence.Table;
@Entity
@Table(name="USERS")
public class User {
@Id
@Column(name="id", unique=true, updatable=false )
private Integer id;
@Column(name="login", unique=true, updatable=false )
private String login;
@Column(name="password")
private String password;
@Column(name="email")
private String email;
public User() {
}
public User(String
this.email
this.password
this.login
this.id
}
login, String email, String pass) {
= email;
= pass;
= login;
= null;
public String getLogin() {
return login;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public Integer getId() {
return this.id;
}
public void setPassword(String pass) {
this.password = pass;
}
public void setEmail(String email) {
this.email = email;
}
}
Итак, мы определили класс User, который соответствует таблице USERS.
Желтым помечены JPA аннотации, зеленым – необязательные параметры, которые
могут использоваться контейнером для оптимизаций или кэширования.
Далее необходимо указать, какую СУБД мы собираемся использовать в нашем
приложении.
Для этого нам необходимо определить т. н. persistence-unit, которому будет
соответствовать класс User. Фактически, persistence-unit – ни что иное, как JNDI имя
пула соединений с БД и подсказка для JPA какой диалект SQL необходимо
использовать для общения с этой СУБД:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="c4f-unit">
<jta-data-source>java:C4F_DB</jta-data-source>
<properties>
<property name="dialect"
value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
</properties>
</persistence-unit>
</persistence>
В этом конфигурационном файле нет никаких специфических параметров, как имя
пользователя и пароль к СУБД, имя сервера и порт СУБД и т. п., что соответствует
духу Java EE. Все конфигурационные параметры, относящиеся к развертыванию
задаются снаружи приложения.
XML файл, определенный выше, должен называться persistence.xml и его
необходимо размещать в директории META-INF того ejb-jar'а, внутри которого
определены Entity Bean'ы.
Чтобы сделать это в нашем проекте, persistence.xml необходимо поместить в
директорию ejb-res/META-INF.
Промежуточная проверка
Собираем приложение и разворачиваем его на сервере. Внешних изменений попрежнему быть не должно, но успешное развертывание означает, что мы делаем все
правильно.
Использование JPA из Session Bean
Теперь перейдем к непосредственному взаимодействию с СУБД из AuthBean. Для
начала нам необходимо получить доступ к экземпляру EntityManager'а (напомним,
что это главный класс JPA):
package com.company.ejb;
import
import
import
import
import
import
javax.ejb.Stateless;
java.util.List;
javax.persistence.EntityManager;
javax.persistence.PersistenceContext;
javax.persistence.Query;
com.company.ejb.entities.User;
@Stateless
public class AuthBean implements AuthLocal {
@PersistenceContext
protected EntityManager em; // Dependency Injection
@Override
@SuppressWarnings("unchecked")
public boolean checkPassword(String login, String password) {
Query q = em.createQuery("SELECT o FROM User o WHERE " +
"o.login=:login and o.password=:password");
q.setParameter("login", login);
q.setParameter("password", password);
List<User> userList = q.getResultList();
return !userList.isEmpty();
}
}
Необходимые замечания. Код метода не самый лаконичный, но зато наглядный. Что
здесь происходит:
1. В некоторый момент времени перед вызовом checkPassword, контейнер
инициализирует поле em готовым к использованию EntityManager'ом.
2. В ходе исполнения checkPassword, с помощью JPA исполняется EJB-QL запрос.
Языки запросов EJB-QL (определённый в спецификации EJB) и HQL
(поддерживаемый Hibernate) являются практически синонимами, разве что
HQL поддерживает некоторые специфические для Hibernate конструкции.
3. Параметры EJB-QL запроса в отличие от JDBC являются именованными.
Используйте ':' перед именами параметров.
4.
JPA возвращает список объектов как результат выполнения запроса. Если
ожидается только один результат, то для этого случая используйте
getSingleResult вместо getResultList
Тестирование
Убедитесь, что теперь доступ получают только пользователи user1 и user2 с
соответствующими паролями.
Проект с необходимыми настройками находится в директории entity-bean
Download