Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2013_1 / КСТ / Разработка веб-приложений.pdf
Скачиваний:
160
Добавлен:
23.02.2015
Размер:
2.74 Mб
Скачать

Удаление сущностей

Бизнес-метод RequestBean.removeOrder удаляет данный заказ из базы данных.

Он использует метод EntityManager.remove, чтобы удалить сущности из базы данных.

Order order = em.find(Order.class, orderId); em.remove(order);

12.1.4. Построение и прогон приложения order

Формирование, упаковка, развертывание и выполнение в NetBeans IDE

Чтобы формировать, упаковывать, развертывать и запускать пример заказа на

вашем сервере предприятия в NetBeans IDE, следуйте этим инструкциям:

1.В NetBeans IDE выберите File>Open Project.

2.В открытом диалоге проекта перейдите в tut-install/examples/persistence/.

3.Выберите папку order.

4.Выберите переключатель Open as Main Project.

5.Откройте проект.

6.В закладке проектов правым щелчком выберите проект order и Run.

NetBeans откроет окно веб-браузера http://localhost:8080/order/.

Формирование, упаковка, развертывание и выполнение в Ant

Чтобы сформировать прикладные компоненты order, введите команду: ant

Она выполняет по умолчанию задачу, которая компилирует исходные файлы и упаковывает приложение в WAR-файл, расположенный в tut-install/examples/persis- tence/order/dist/order.war.

Для того чтобы развернуть WAR, убедитесь что сервер запущен, затем введите

следующую команду: ant deploy

Откройте окно просмотра веб в http://localhost:8080/order/, чтобы создавать и корректировать данные заказа.

Задача All

По соглашению, задача all сформирует, упакует, развернет и запустит приложение. Для того чтобы сделать это, введите команду:

ant all

Удаление приложения

Для удаления приложения order.war введите следующую команду: ant undeploy

12.2.Пример получения схемы отношений на основе таблиц БД

Средствами NetBeans IDE можно получить объявления сущностей для использования в Java EE 6 на основе имеющихся таблиц базы данных.

Для этого необходимо объявить ресурсный пул и ресурс, соответствующие имеющейся СУБД и базе данных, подключенным к проекту веб-приложения. Далее на закладке проектов выбрать папку проекта с расширением ejb, правой кнопкой щелкнуть по имени папки и выбрать пункт меню «Создать – Классы сущностей из базы данных».

138

Служба NetBeans IDE произведет анализ имеющихся таблиц базы данных и построит бины с необходимыми описаниями свойств и аннотаций.

Следующие таблицы созданы в СУБД Postgresql приведёнными ниже операто-

рами.

--Рудные тела

--1) Идентификатор (ПК)

--2) Горизонт (ВК)

--3) Высота слоя, м

--4) Сорт (ВК)

--Table: body

--DROP TABLE body;

CREATE TABLE body

(

id_body serial NOT NULL, id_hor integer NOT NULL,

h_body numeric(4,2) NOT NULL DEFAULT 10, id_sort integer NOT NULL,

CONSTRAINT "PK_body" PRIMARY KEY (id_body), CONSTRAINT "FK_body_hor" FOREIGN KEY (id_hor)

REFERENCES horizons (id_hor) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION, CONSTRAINT "FK_body_sort" FOREIGN KEY (id_sort) REFERENCES sorts (id_sort) MATCH SIMPLE

ON UPDATE NO ACTION ON DELETE NO ACTION

)

WITH ( OIDS=FALSE

);

ALTER TABLE body OWNER TO cyx;

COMMENT ON TABLE body IS 'Рудные тела (главная)';

------------------------------------------------

--Список фрагментов рудного тела

--1) Идентификатор (ПК)

--2) Рудное тело (ВК)

--3) Фрагмент (ВК)

--Table: body_frag

--DROP TABLE body_frag;

CREATE TABLE body_frag

(

id_body_frag serial NOT NULL, id_body integer NOT NULL, id_frag integer NOT NULL,

CONSTRAINT "PK_fr_body" PRIMARY KEY (id_body_frag), CONSTRAINT "FK_body_fr" FOREIGN KEY (id_frag)

139

REFERENCES fragments (id_fragment) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION,

CONSTRAINT "FK_id_body" FOREIGN KEY (id_body) REFERENCES body (id_body) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION

)

WITH ( OIDS=FALSE

);

ALTER TABLE body_frag OWNER TO cyx;

COMMENT ON TABLE body_frag IS 'Фрагменты рудных тел';

------------------------------------------------

--Характеристика тела

--1) Идентификатор (ПК)

--2) Тело (ВК)

--3) Параметр (ВК)

--4) Значение, веществ

--Table: body_char

--DROP TABLE body_char;

CREATE TABLE body_char

(

id_body_char serial NOT NULL, id_body integer NOT NULL, id_par integer NOT NULL, "value" real NOT NULL,

CONSTRAINT "PK_body_char" PRIMARY KEY (id_body_char), CONSTRAINT "FK_body_id" FOREIGN KEY (id_body)

REFERENCES body (id_body) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION, CONSTRAINT "FK_body_par" FOREIGN KEY (id_par)

REFERENCES params (id_param) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION

)

WITH ( OIDS=FALSE

);

ALTER TABLE body_char OWNER TO cyx;

COMMENT ON TABLE body_char IS 'Характеристики тела';

Логическая модель фрагмента базы данных приведена на рис. 12.1.

После получения схемы будем иметь следующие описания бинов (по тексту кур-

сивом добавлены комментарии к сгенерированным текстам программ на языке Java). package ggis_ejb;

// Раздел импорта стандартных пакетов и классов import java.io.Serializable;

140

Рис. 12.1. Логическая схема данных

import java.math.BigDecimal; import java.util.Collection; import javax.persistence.Basic;

import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id;

import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToMany; import javax.persistence.Table;

//Аннотации для объявления класса для сущности "Рудные тела"

@Entity

@Table(name = "body")

//Именованные запросы для трех вариантов

@NamedQueries({

@NamedQuery(name = "Body.findAll", query = "SELECT b FROM Body

b"),

@NamedQuery(name = "Body.findByIdBody", query = "SELECT b FROM Body b WHERE b.idBody = :idBody"),

@NamedQuery(name = "Body.findByHBody", query = "SELECT b FROM Body b WHERE b.hBody = :hBody")})

// Объявление класса для сущности "Рудные тела" public class Body implements Serializable {

141

// Ключ сериализации

private static final long serialVersionUID = 1L;

//Первичный ключ

@Id

@Basic(optional = false) @Column(name = "id_body") private Integer idBody;

//Свойство "Высота слоя"

@Basic(optional = false) @Column(name = "h_body") private BigDecimal hBody;

//Внешний ключ на таблицу "Горизонты" аннотируется @JoinColumn

и@ManyToOne

@JoinColumn(name = "id_hor", referencedColumnName = "id_hor") @ManyToOne(optional = false)

private Horizons idHor;

//Внешний ключ на таблицу "Сорта" аннотируется @JoinColumn

и@ManyToOne

@JoinColumn(name = "id_sort", referencedColumnName = "id_sort")

@ManyToOne(optional = false) private Sorts idSort;

//Из таблицы "Характеристика тела" есть ВК на таблицу "Рудные

тела"

@OneToMany(cascade = CascadeType.ALL, mappedBy = "idBody") private Collection<BodyChar> bodyCharCollection;

//Из таблицы "Список фрагментов" есть ВК на таблицу "Рудные

тела"

@OneToMany(cascade = CascadeType.ALL, mappedBy = "idBody") private Collection<BodyFrag> bodyFragCollection;

//Конструкторы сущностей "Рудные тела"

public Body() {

}

public Body(Integer idBody) { this.idBody = idBody;

}

public Body(Integer idBody, BigDecimal hBody) { this.idBody = idBody;

this.hBody = hBody;

}

142

//Методы доступа к свойствам сущностей "Рудные тела"

//Метод get

public Integer getIdBody() { return idBody;

}

// Метод set

public void setIdBody(Integer idBody) { this.idBody = idBody;

}

public BigDecimal getHBody() { return hBody;

}

public void setHBody(BigDecimal hBody) { this.hBody = hBody;

}

public Horizons getIdHor() { return idHor;

}

public void setIdHor(Horizons idHor) { this.idHor = idHor;

}

public Sorts getIdSort() { return idSort;

}

public void setIdSort(Sorts idSort) { this.idSort = idSort;

}

// Доступ к коллекции сущностей "Характеристика тела" в отно-

шении ManyToOne

public Collection<BodyChar> getBodyCharCollection() { return bodyCharCollection;

}

public void setBodyCharCollection(Collection<BodyChar> bodyCharCollection) {

this.bodyCharCollection = bodyCharCollection;

}

// Доступ к коллекции сущностей "Список фрагментов" в отноше-

нии ManyToOne

public Collection<BodyFrag> getBodyFragCollection() { return bodyFragCollection;

143

}

public void setBodyFragCollection(Collection<BodyFrag> bodyFragCollection) {

this.bodyFragCollection = bodyFragCollection;

}

// Метод вычисления хеш-функции для упаковки сущностей

@Override

public int hashCode() { int hash = 0;

hash += (idBody != null ? idBody.hashCode() : 0); return hash;

}

//Метод сравнения двух сущностей

@Override

public boolean equals(Object object) {

//TODO: Warning - this method won't work in the case the id fields are not set

if (!(object instanceof Body)) { return false;

}

Body other = (Body) object;

if ((this.idBody == null && other.idBody != null) || (this.idBody != null && !this.idBody.equals(other.idBody))) {

return false;

}

return true;

}

//Метод преобразования в строку

@Override

public String toString() {

return "ggis_ejb.Body[idBody=" + idBody + "]";

}

}

// Класс характеристик тел

package ggis_ejb;

import java.io.Serializable; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id;

import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table;

144

// Аннотации для объявления класса для сущности "Характеристика тела"

@Entity

@Table(name = "body_char") @NamedQueries({

@NamedQuery(name = "BodyChar.findAll", query = "SELECT b FROM BodyChar b"),

@NamedQuery(name = "BodyChar.findByIdBodyChar", query = "SELECT b FROM BodyChar b WHERE b.idBodyChar = :idBodyChar"),

@NamedQuery(name = "BodyChar.findByValue", query = "SELECT b FROM BodyChar b WHERE b.value = :value")})

// Объявление класса для сущности «Характеристика тела» public class BodyChar implements Serializable {

private static final long serialVersionUID = 1L;

//Первичный ключ

@Id

@Basic(optional = false) @Column(name = "id_body_char") private Integer idBodyChar;

//Поле значения

@Basic(optional = false) @Column(name = "value") private float value;

//Внешний ключ на таблицу "Рудное тело" аннотируется

@JoinColumn и @ManyToOne

@JoinColumn(name = «id_body», referencedColumnName = "id_body")

@ManyToOne(optional = false) private Body idBody;

//Внешний ключ на таблицу "Параметры" аннотируется @JoinColumn

и@ManyToOne

@JoinColumn(name = "id_par", referencedColumnName = "id_param")

@ManyToOne(optional = false) private Params idPar;

// Конструкторы сущности "Характеристика тела" public BodyChar() {

}

public BodyChar(Integer idBodyChar) { this.idBodyChar = idBodyChar;

}

public BodyChar(Integer idBodyChar, float value) { this.idBodyChar = idBodyChar;

this.value = value;

}

145

// Методы доступа к свойствам сущностей "Характеристика тела" public Integer getIdBodyChar() {

return idBodyChar;

}

public void setIdBodyChar(Integer idBodyChar) { this.idBodyChar = idBodyChar;

}

public float getValue() { return value;

}

public void setValue(float value) { this.value = value;

}

public Body getIdBody() { return idBody;

}

public void setIdBody(Body idBody) { this.idBody = idBody;

}

public Params getIdPar() { return idPar;

}

public void setIdPar(Params idPar) { this.idPar = idPar;

}

// Вспомогательные методы для упаковки, сравнения и печати

@Override

public int hashCode() { int hash = 0;

hash += (idBodyChar != null ? idBodyChar.hashCode() : 0); return hash;

}

@Override

public boolean equals(Object object) {

// TODO: Warning - this method won't work in the case the id fields are not set

if (!(object instanceof BodyChar)) { return false;

}

BodyChar other = (BodyChar) object;

if ((this.idBodyChar == null && other.idBodyChar != null) || (this.idBodyChar != null && ! this.idBodyChar.equals(other.idBodyChar))) {

146

return false;

}

return true;

}

@Override

public String toString() {

return "ggis_ejb.BodyChar[idBodyChar=" + idBodyChar + "]";

}

}

package ggis_ejb;

import java.io.Serializable; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id;

import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table;

// Аннотации для объявления класса для сущности "Фрагменты тела"

@Entity

@Table(name = "body_frag") @NamedQueries({

@NamedQuery(name = "BodyFrag.findAll", query = "SELECT b FROM BodyFrag b"),

@NamedQuery(name = "BodyFrag.findByIdBodyFrag", query = "SELECT b FROM BodyFrag b WHERE b.idBodyFrag = :idBodyFrag")})

public class BodyFrag implements Serializable { private static final long serialVersionUID = 1L;

@Id

@Basic(optional = false) @Column(name = "id_body_frag") private Integer idBodyFrag;

@JoinColumn(name = "id_body", referencedColumnName = "id_body")

@ManyToOne(optional = false) private Body idBody;

@JoinColumn(name = "id_frag", referencedColumnName = "id_fragment")

147

@ManyToOne(optional = false) private Fragments idFrag;

public BodyFrag() {

}

public BodyFrag(Integer idBodyFrag) { this.idBodyFrag = idBodyFrag;

}

public Integer getIdBodyFrag() { return idBodyFrag;

}

public void setIdBodyFrag(Integer idBodyFrag) { this.idBodyFrag = idBodyFrag;

}

public Body getIdBody() { return idBody;

}

public void setIdBody(Body idBody) { this.idBody = idBody;

}

public Fragments getIdFrag() { return idFrag;

}

public void setIdFrag(Fragments idFrag) { this.idFrag = idFrag;

}

@Override

public int hashCode() { int hash = 0;

hash += (idBodyFrag != null ? idBodyFrag.hashCode() : 0); return hash;

}

@Override

public boolean equals(Object object) {

// TODO: Warning - this method won't work in the case the id fields are not set

if (!(object instanceof BodyFrag)) { return false;

}

BodyFrag other = (BodyFrag) object;

if ((this.idBodyFrag == null && other.idBodyFrag != null) || (this.idBodyFrag != null && ! this.idBodyFrag.equals(other.idBodyFrag))) {

148

return false;

}

return true;

}

@Override

public String toString() {

return "ggis_ejb.BodyFrag[idBodyFrag=" + idBodyFrag + "]";

}

}

Общие правила установления соответствия между таблицами классических ре-

ляционных баз данных и сущностями в Java EE 6 можно сформулировать следующим образом.

1.Каждая таблица имеет собственный класс сущностей.

2.Класс сущности имеет аннотации для задания хранимой таблицы БД:

@Entity

@Table(name = "body")

где body – имя таблицы.

3.Для поиска записей в текст включаются аннотации создания именованных

запросов к таблице: поиск всех записей, поиск записи по ключу, поиск по

полю данных.

4.Класс сущности реализует интерфейс сериализации с необходимым ключом и методами:

public class Body implements Serializable {

// Ключ сериализации

private static final long serialVersionUID = 1L;

@Override

public int hashCode() {

. . .

}

@Override

public boolean equals(Object object) {

. . .

}

@Override

public String toString() {

. . .

}

}

5. Первичный ключ имеет аннотации:

@Id

@Basic(optional = false) @Column(name = "id_body") private Integer idBody;

149

6. Простое поле имеет аннотации:

@Basic(optional = false) @Column(name = "h_body") private BigDecimal hBody;

7. Внешний ключ имеет аннотации

@JoinColumn(name = "id_hor", referencedColumnName = "id_hor") @ManyToOne(optional = false)

private Horizons idHor;

8. Класс имеет конструкторы без параметров и с параметрами:

public Body() {

}

public Body(Integer idBody) { this.idBody = idBody;

}

public Body(Integer idBody, BigDecimal hBody) { this.idBody = idBody;

this.hBody = hBody;

}

9.Если на сущность есть ссылки внешнего ключа из другой таблицы, то класс имеет свойство – коллекцию с методами доступа:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "idBody") private Collection<BodyChar> bodyCharCollection;

public Collection<BodyChar> getBodyCharCollection() { return bodyCharCollection;

}

public void setBodyCharCollection(Collection<BodyChar> bodyCharCollection) {

this.bodyCharCollection = bodyCharCollection;

}

150

Соседние файлы в папке КСТ