Доброе время суток хабравчане. Моя предыдущая статья была небольшим интро в ADF. И так как по результатам опроса я вижу, что тема оказалась интересна, то я продолжаю писать об ADF.
Теперь после небольшого рассказа о данном фреймворке, можно «ринуться в бой» и рассмотреть фичи ADF более конкретно. Данная статья будет об ADF Business Components. О том как работать с ними декларативно и программно.
ADF Business Components (далее BC) – это часть фреймворка для работы с БД, предоставляющая визуальную и декларативную разработку. Конфигурация BC хранится в XML файлах, но при желании можно сгенерировать Java классы и добавить и/или переопределить логику.
BC делятся на 5 основных частей:
EO представляет собой таблицу из БД, и, соответственно, экземпляр EO – это строка из таблицы.
Данный компонент инкапсулирует в себе данные, правила валидации и логику персистентности.
EO associations определяют связи между двумя сущностями (таблицами)
VO – компонент, ответственный за чтение данных из data source, а также включает в себя операции по их обновлению.
View Links – определяют связи между VO (по аналогии с associations)
Application Module – это уровень сервиса, предоставляющий работу с бизнес компонентами (а именно с VO и View Links). Также в него можно добавить дополнительные методы и вкладывать другие Application Modules. В конечном счете Application Module используется, как Data Control.
Для тестовых БД данных я буду использовать employees таблицу из oracle HR схемы.
После прохождения визарда «Business Components from tables», в результате получим следующий набор файлов.
![](https://habrastorage.org/r/w780q1/storage2/55b/cba/e29/55bcbae2950f570dc4dfc39a99a03504.jpg)
Здесь Employees – EO, EmployeesView – VO, EmployeesAppModule – Application Module, EmpManagerFkAssoc – ассоциация между работниками и их менеджерами, EmpManagerFkLink – View link для аналогичной связи, но для VO, Business Components Diagram — диаграмма компонентов.
А на панели Data Controls создастся соответствующий data control.
![](https://habrastorage.org/r/w780q1/storage2/332/438/a94/332438a947a4ac84aad1026c62cefa41.jpg)
Взглянем на диаграмму.
![](https://habrastorage.org/r/w780q1/storage2/38e/9b1/31c/38e9b131c97e70d1b16f091b47a423f2.jpg)
Можно увидеть, что EmployeesView создан на основе Employees EO. А в ApplicationModule попали два инстанса EmployeesView. Один отвечает за менеджера, а второй за его работников.
Краткий обзор сгенерированных файлов.
Employees
В сгенерированном EO можно посмотреть какие атрибуты в него входят, отредактировать, добавить свои или удалить.
![](https://habrastorage.org/r/w780q1/storage2/0d2/085/9f4/0d20859f4e9676740c5ed8ef5d85ab03.jpg)
Также можно управлять правилами валидации данных.
![](https://habrastorage.org/r/w780q1/storage2/0bd/b1e/0b6/0bdb1e0b6e4e04bee600e54d971a58b6.jpg)
EmployeesView
Из атрибутов VO видно, что они берутся из Employees EO.
![](https://habrastorage.org/r/w780q1/storage2/09f/e41/025/09fe410259926f3bb191427d0effe7bc.jpg)
Можно посмотреть запрос VO, его переменные и критерии (named where clauses)
![](https://habrastorage.org/r/w780q1/storage2/296/e30/764/296e30764edf559945a4b51e19925966.jpg)
EmployeesAppModule
Application Module, как мы видели раньше, содержит два экземпляра EmployeesView
![](https://habrastorage.org/r/w780q1/storage2/fd3/91b/4dc/fd391b4dc56ffc158208f11dc8ce4732.jpg)
EmpManagerFkAssoc
Связь между сущностями.
![](https://habrastorage.org/r/w780q1/storage2/d4d/a6e/9f2/d4da6e9f26eec31f4c2020aadb2de903.jpg)
EmpManagerFkLink
Одинаковые Source и Destination, говорят о том, что View Link построена на базе Associations.
![](https://habrastorage.org/r/w780q1/storage2/46d/ea5/7bb/46dea57bbc95ab8654a9a107b404de9e.jpg)
![](https://habrastorage.org/r/w780q1/storage2/2f2/948/260/2f2948260fc437ce6639474d72f27e93.jpg)
Да-да. CRUD будет реализован полностью декларативным путем, мною не будет написано ни одной строчки кода.
Посмотрим какой будет результат.
Вначале будет показана таблица с сотрудниками.
![](https://habrastorage.org/r/w780q1/storage2/5e3/15c/528/5e315c52899e96145ec197414204a122.jpg)
При нажатии на Create employee, произойдет переход на создание нового сотрудника.
![](https://habrastorage.org/r/w780q1/storage2/9e8/ab3/534/9e8ab3534dc089bf196109aa7e8d9225.jpg)
При нажатии на Save новый сотрудник добавится в БД, и мы вернемся к таблице.
![](https://habrastorage.org/r/w780q1/storage2/a87/edb/59f/a87edb59f8f22e1634ee8cd6b5a9a5ab.jpg)
При нажатии на Update employee, произойдет переход на редактирование информации сотрудника.
![](https://habrastorage.org/r/w780q1/storage2/d0b/977/e30/d0b977e3029d37cbb60f8f5abde92ce7.jpg)
После сохранения изменений, снова возврат к таблице.
![](https://habrastorage.org/r/w780q1/storage2/945/30d/539/94530d539f6fc9d96229bbfe6e75db59.jpg)
Ну и наконец при нажатии на Delete employee, сотрудник испарится.
![](https://habrastorage.org/r/w780q1/storage2/92d/4f5/4c2/92d4f54c2b375cb32e7fe39c40250c4f.jpg)
Ходом операций управляет bounded task flow. О том, как работать с task flows, будет отдельная статья. Пока просто посмотрим на диаграмму.
![](https://habrastorage.org/r/w780q1/storage2/0b7/9e4/76f/0b79e476fa60fe9eb2710e852d8dd24c.jpg)
ViewEmployees, createEmployee и updateEmployee это view activities с JSFF, отвечающие за отображение таблицы и форм.
Для отображения сотрудников в таблице, нужно перенести EmployeeView из Data Control на страницу и выбрать в опциях создания – нужный вид таблицы (в моем случае – это read only)
![](https://habrastorage.org/r/w780q1/storage2/7ff/998/8ce/7ff9988ce00498bc20d1fc67a0b2305f.jpg)
Для вывода форм на страницах createEmployee и updateEmployee нужно сделать аналогичную операцию, но выбрать из категории Form (в моем случае – это ADF Form)
![](https://habrastorage.org/r/w780q1/storage2/938/c6f/652/938c6f65218558064e0fb5b688d1d224.jpg)
Все остальные activities – это операции над DataControl’ом. Перенесены эти операции также с Data Controls панели.
![](https://habrastorage.org/r/w780q1/storage2/e1e/af8/b96/e1eaf8b96eebca72633f208f91eb4717.jpg)
CreateInsert создает в итераторе новую строку и переводит курсор итератора на нее.
Delete удаляет строку в итераторе, на которой в данный момент находится курсор.
Чтобы действия CreateInsert и Delete вступили в силу, необходимо вызвать операцию Commit, а для того, чтобы откатить изменения – Rollback.
На этом реализация CRUD’а завершена.
Теперь рассмотрим случай, когда мы не отказываемся полностью от декларативного пути, но операции хотим вызывать в каком-либо managed bean’e.
Для простоты рассмотрим только реализацию вставки, так как остальные выполняются аналогично.
Первым шагом необходимо создать managed bean.
![](https://habrastorage.org/r/w780q1/storage2/b14/df1/cd1/b14df1cd1d0388d65a5d4cd629b5c520.jpg)
Код bean’a рассмотрим в самом конце.
Я создам новую страницу и перенесу на нее таблицу, чтобы можно было увидеть новые данные, и форму для добавления нового сотрудника.
В input компонентах проставлю связи value на managed bean. И в конце добавлю кнопку, используя в качестве action listener’a метод managed bean'а.
В итоге разметка jspx выглядит следующим образом:
А описание страницы будет выглядеть так.
![](https://habrastorage.org/r/w780q1/storage2/a37/61c/b56/a3761cb56594a56203a3070d36cd5bb3.jpg)
Код managed bean’a (get’ры и set’ры опустим).
Поля:
Метод вставки, использующийся кнопкой на странице:
Проверим работу managed bean’a, убедившись, что в таблицу попала новая запись.
![](https://habrastorage.org/r/w780q1/storage2/099/d5c/d26/099d5cd26a9fdb722d56106624aafc17.jpg)
И последний пример, в котором будет только использование кода.
Для начала нужно подготовить классы у Business Components.
Для этого откроем EmployeeView перейдем на вкладку Java и сгенерируем следующие классы.
![](https://habrastorage.org/r/w780q1/storage2/057/03b/9bb/05703b9bb889c077cf79830dc165d0a5.jpg)
EmployeesViewImpl необходим для работы с запросами, а EmployeesViewRowImpl будет представлять из себя строку с атрибутами.
Таким же путем сгенерируем класс для Application Module.
![](https://habrastorage.org/r/w780q1/storage2/f5e/09b/11d/f5e09b11ddea693e1e635eeea8c1d989.jpg)
Осталось написать новый метод для добавления строки в БД в EmployeesAppModuleImpl, создать TO класс для передачи данных в этот метод, и вызвать данный метод в managed bean’e.
Метод в Application Module:
Новый метод bean’a:
Проверяем работу:
![](https://habrastorage.org/r/w780q1/storage2/44d/edc/66e/44dedc66eefb7dcb6ffae203cb1ab647.jpg)
На этом сегодня все. Много всего еще осталось за бортом по этой теме, поэтому оставлю ссылку на дополнительную информацию здесь.
P.S. Следующая статья будет о task flows.
Теперь после небольшого рассказа о данном фреймворке, можно «ринуться в бой» и рассмотреть фичи ADF более конкретно. Данная статья будет об ADF Business Components. О том как работать с ними декларативно и программно.
Общие понятия
ADF Business Components (далее BC) – это часть фреймворка для работы с БД, предоставляющая визуальную и декларативную разработку. Конфигурация BC хранится в XML файлах, но при желании можно сгенерировать Java классы и добавить и/или переопределить логику.
BC делятся на 5 основных частей:
- Entity Objects (EO)
- View Objects (VO)
- Associations
- View Links
- Application Module
EO представляет собой таблицу из БД, и, соответственно, экземпляр EO – это строка из таблицы.
Данный компонент инкапсулирует в себе данные, правила валидации и логику персистентности.
EO associations определяют связи между двумя сущностями (таблицами)
VO – компонент, ответственный за чтение данных из data source, а также включает в себя операции по их обновлению.
View Links – определяют связи между VO (по аналогии с associations)
Application Module – это уровень сервиса, предоставляющий работу с бизнес компонентами (а именно с VO и View Links). Также в него можно добавить дополнительные методы и вкладывать другие Application Modules. В конечном счете Application Module используется, как Data Control.
IDE time
Для тестовых БД данных я буду использовать employees таблицу из oracle HR схемы.
После прохождения визарда «Business Components from tables», в результате получим следующий набор файлов.
![](https://habrastorage.org/storage2/55b/cba/e29/55bcbae2950f570dc4dfc39a99a03504.jpg)
Здесь Employees – EO, EmployeesView – VO, EmployeesAppModule – Application Module, EmpManagerFkAssoc – ассоциация между работниками и их менеджерами, EmpManagerFkLink – View link для аналогичной связи, но для VO, Business Components Diagram — диаграмма компонентов.
А на панели Data Controls создастся соответствующий data control.
![](https://habrastorage.org/storage2/332/438/a94/332438a947a4ac84aad1026c62cefa41.jpg)
Взглянем на диаграмму.
![](https://habrastorage.org/storage2/38e/9b1/31c/38e9b131c97e70d1b16f091b47a423f2.jpg)
Можно увидеть, что EmployeesView создан на основе Employees EO. А в ApplicationModule попали два инстанса EmployeesView. Один отвечает за менеджера, а второй за его работников.
Краткий обзор сгенерированных файлов.
Employees
В сгенерированном EO можно посмотреть какие атрибуты в него входят, отредактировать, добавить свои или удалить.
![](https://habrastorage.org/storage2/0d2/085/9f4/0d20859f4e9676740c5ed8ef5d85ab03.jpg)
Также можно управлять правилами валидации данных.
![](https://habrastorage.org/storage2/0bd/b1e/0b6/0bdb1e0b6e4e04bee600e54d971a58b6.jpg)
EmployeesView
Из атрибутов VO видно, что они берутся из Employees EO.
![](https://habrastorage.org/storage2/09f/e41/025/09fe410259926f3bb191427d0effe7bc.jpg)
Можно посмотреть запрос VO, его переменные и критерии (named where clauses)
![](https://habrastorage.org/storage2/296/e30/764/296e30764edf559945a4b51e19925966.jpg)
EmployeesAppModule
Application Module, как мы видели раньше, содержит два экземпляра EmployeesView
![](https://habrastorage.org/storage2/fd3/91b/4dc/fd391b4dc56ffc158208f11dc8ce4732.jpg)
EmpManagerFkAssoc
Связь между сущностями.
![](https://habrastorage.org/storage2/d4d/a6e/9f2/d4da6e9f26eec31f4c2020aadb2de903.jpg)
EmpManagerFkLink
Одинаковые Source и Destination, говорят о том, что View Link построена на базе Associations.
![](https://habrastorage.org/storage2/46d/ea5/7bb/46dea57bbc95ab8654a9a107b404de9e.jpg)
CRUD
![](https://habrastorage.org/storage2/2f2/948/260/2f2948260fc437ce6639474d72f27e93.jpg)
Да-да. CRUD будет реализован полностью декларативным путем, мною не будет написано ни одной строчки кода.
Посмотрим какой будет результат.
Вначале будет показана таблица с сотрудниками.
![](https://habrastorage.org/storage2/5e3/15c/528/5e315c52899e96145ec197414204a122.jpg)
При нажатии на Create employee, произойдет переход на создание нового сотрудника.
![](https://habrastorage.org/storage2/9e8/ab3/534/9e8ab3534dc089bf196109aa7e8d9225.jpg)
При нажатии на Save новый сотрудник добавится в БД, и мы вернемся к таблице.
![](https://habrastorage.org/storage2/a87/edb/59f/a87edb59f8f22e1634ee8cd6b5a9a5ab.jpg)
При нажатии на Update employee, произойдет переход на редактирование информации сотрудника.
![](https://habrastorage.org/storage2/d0b/977/e30/d0b977e3029d37cbb60f8f5abde92ce7.jpg)
После сохранения изменений, снова возврат к таблице.
![](https://habrastorage.org/storage2/945/30d/539/94530d539f6fc9d96229bbfe6e75db59.jpg)
Ну и наконец при нажатии на Delete employee, сотрудник испарится.
![](https://habrastorage.org/storage2/92d/4f5/4c2/92d4f54c2b375cb32e7fe39c40250c4f.jpg)
Ходом операций управляет bounded task flow. О том, как работать с task flows, будет отдельная статья. Пока просто посмотрим на диаграмму.
![](https://habrastorage.org/storage2/0b7/9e4/76f/0b79e476fa60fe9eb2710e852d8dd24c.jpg)
ViewEmployees, createEmployee и updateEmployee это view activities с JSFF, отвечающие за отображение таблицы и форм.
Для отображения сотрудников в таблице, нужно перенести EmployeeView из Data Control на страницу и выбрать в опциях создания – нужный вид таблицы (в моем случае – это read only)
![](https://habrastorage.org/storage2/7ff/998/8ce/7ff9988ce00498bc20d1fc67a0b2305f.jpg)
Для вывода форм на страницах createEmployee и updateEmployee нужно сделать аналогичную операцию, но выбрать из категории Form (в моем случае – это ADF Form)
![](https://habrastorage.org/storage2/938/c6f/652/938c6f65218558064e0fb5b688d1d224.jpg)
Все остальные activities – это операции над DataControl’ом. Перенесены эти операции также с Data Controls панели.
![](https://habrastorage.org/storage2/e1e/af8/b96/e1eaf8b96eebca72633f208f91eb4717.jpg)
CreateInsert создает в итераторе новую строку и переводит курсор итератора на нее.
Delete удаляет строку в итераторе, на которой в данный момент находится курсор.
Чтобы действия CreateInsert и Delete вступили в силу, необходимо вызвать операцию Commit, а для того, чтобы откатить изменения – Rollback.
На этом реализация CRUD’а завершена.
CRUD v2
Теперь рассмотрим случай, когда мы не отказываемся полностью от декларативного пути, но операции хотим вызывать в каком-либо managed bean’e.
Для простоты рассмотрим только реализацию вставки, так как остальные выполняются аналогично.
Первым шагом необходимо создать managed bean.
![](https://habrastorage.org/storage2/b14/df1/cd1/b14df1cd1d0388d65a5d4cd629b5c520.jpg)
Код bean’a рассмотрим в самом конце.
Я создам новую страницу и перенесу на нее таблицу, чтобы можно было увидеть новые данные, и форму для добавления нового сотрудника.
В input компонентах проставлю связи value на managed bean. И в конце добавлю кнопку, используя в качестве action listener’a метод managed bean'а.
В итоге разметка jspx выглядит следующим образом:
<af:form id="f1">
<af:table value="#{bindings.EmployeesView1.collectionModel}" var="row"
rows="#{bindings.EmployeesView1.rangeSize}"
emptyText="#{bindings.EmployeesView1.viewable ? 'No data to display.' : 'Access Denied.'}"
fetchSize="#{bindings.EmployeesView1.rangeSize}" rowBandingInterval="0" id="t1">
<af:column sortProperty="#{bindings.EmployeesView1.hints.FirstName.name}" sortable="false"
headerText="#{bindings.EmployeesView1.hints.FirstName.label}" id="c1">
<af:outputText value="#{row.FirstName}" id="ot1"/>
</af:column>
<af:column sortProperty="#{bindings.EmployeesView1.hints.LastName.name}" sortable="false"
headerText="#{bindings.EmployeesView1.hints.LastName.label}" id="c2">
<af:outputText value="#{row.LastName}" id="ot2"/>
</af:column>
<af:column sortProperty="#{bindings.EmployeesView1.hints.Email.name}" sortable="false"
headerText="#{bindings.EmployeesView1.hints.Email.label}" id="c3">
<af:outputText value="#{row.Email}" id="ot3"/>
</af:column>
<af:column sortProperty="#{bindings.EmployeesView1.hints.PhoneNumber.name}" sortable="false"
headerText="#{bindings.EmployeesView1.hints.PhoneNumber.label}" id="c4">
<af:outputText value="#{row.PhoneNumber}" id="ot4"/>
</af:column>
<af:column sortProperty="#{bindings.EmployeesView1.hints.JobId.name}" sortable="false"
headerText="#{bindings.EmployeesView1.hints.JobId.label}" id="c5">
<af:outputText value="#{row.JobId}" id="ot5"/>
</af:column>
</af:table>
<af:panelFormLayout id="pfl1">
<af:inputText value="#{backingBeanScope.employeeBean.employeeId}" label="#{bindings.EmployeeId.hints.label}"
required="#{bindings.EmployeeId.hints.mandatory}"
columns="#{bindings.EmployeeId.hints.displayWidth}"
maximumLength="#{bindings.EmployeeId.hints.precision}"
shortDesc="#{bindings.EmployeeId.hints.tooltip}" id="it1">
<f:validator binding="#{bindings.EmployeeId.validator}"/>
<af:convertNumber groupingUsed="false" pattern="#{bindings.EmployeeId.format}"/>
</af:inputText>
<af:inputText value="#{backingBeanScope.employeeBean.firstName}" label="#{bindings.FirstName.hints.label}"
required="#{bindings.FirstName.hints.mandatory}"
columns="#{bindings.FirstName.hints.displayWidth}"
maximumLength="#{bindings.FirstName.hints.precision}"
shortDesc="#{bindings.FirstName.hints.tooltip}" id="it2">
<f:validator binding="#{bindings.FirstName.validator}"/>
</af:inputText>
<af:inputText value="#{backingBeanScope.employeeBean.lastName}" label="#{bindings.LastName.hints.label}"
required="#{bindings.LastName.hints.mandatory}"
columns="#{bindings.LastName.hints.displayWidth}"
maximumLength="#{bindings.LastName.hints.precision}"
shortDesc="#{bindings.LastName.hints.tooltip}" id="it3">
<f:validator binding="#{bindings.LastName.validator}"/>
</af:inputText>
<af:inputText value="#{backingBeanScope.employeeBean.email}" label="#{bindings.Email.hints.label}"
required="#{bindings.Email.hints.mandatory}"
columns="#{bindings.Email.hints.displayWidth}"
maximumLength="#{bindings.Email.hints.precision}"
shortDesc="#{bindings.Email.hints.tooltip}" id="it4">
<f:validator binding="#{bindings.Email.validator}"/>
</af:inputText>
<af:inputText value="#{backingBeanScope.employeeBean.phoneNumber}" label="#{bindings.PhoneNumber.hints.label}"
required="#{bindings.PhoneNumber.hints.mandatory}"
columns="#{bindings.PhoneNumber.hints.displayWidth}"
maximumLength="#{bindings.PhoneNumber.hints.precision}"
shortDesc="#{bindings.PhoneNumber.hints.tooltip}" id="it5">
<f:validator binding="#{bindings.PhoneNumber.validator}"/>
</af:inputText>
<af:inputDate value="#{backingBeanScope.employeeBean.hireDate}" label="#{bindings.HireDate.hints.label}"
required="#{bindings.HireDate.hints.mandatory}"
columns="#{bindings.HireDate.hints.displayWidth}"
shortDesc="#{bindings.HireDate.hints.tooltip}" id="id1">
<f:validator binding="#{bindings.HireDate.validator}"/>
<af:convertDateTime pattern="#{bindings.HireDate.format}"/>
</af:inputDate>
<af:inputText value="#{backingBeanScope.employeeBean.jobId}" label="#{bindings.JobId.hints.label}"
required="#{bindings.JobId.hints.mandatory}"
columns="#{bindings.JobId.hints.displayWidth}"
maximumLength="#{bindings.JobId.hints.precision}"
shortDesc="#{bindings.JobId.hints.tooltip}" id="it6">
<f:validator binding="#{bindings.JobId.validator}"/>
</af:inputText>
<af:commandButton text="Create Employee" id="cb1"
actionListener="#{backingBeanScope.employeeBean.createEmployee}"/>
</af:panelFormLayout>
</af:form>
А описание страницы будет выглядеть так.
![](https://habrastorage.org/storage2/a37/61c/b56/a3761cb56594a56203a3070d36cd5bb3.jpg)
Код managed bean’a (get’ры и set’ры опустим).
Поля:
private int employeeId;
private String firstName;
private String lastName;
private String email;
private String phoneNumber;
private Timestamp hireDate;
private String jobId;
private BindingContainer bindings;
Метод вставки, использующийся кнопкой на странице:
public void createEmployee(ActionEvent actionEvent) {
// Получаем binding контейнер
BindingContainer bindings = getBindings();
// Выполняем операцию создания новой строки
OperationBinding createOperation =
bindings.getOperationBinding("CreateInsert");
createOperation.execute();
// Забиваем атрибуты данными
AttributeBinding employeeId =
(AttributeBinding)bindings.getControlBinding("EmployeeId");
employeeId.setInputValue(this.employeeId);
AttributeBinding firstName =
(AttributeBinding)bindings.getControlBinding("FirstName");
firstName.setInputValue(this.firstName);
AttributeBinding lastName =
(AttributeBinding)bindings.getControlBinding("LastName");
lastName.setInputValue(this.lastName);
AttributeBinding phoneNumber =
(AttributeBinding)bindings.getControlBinding("PhoneNumber");
phoneNumber.setInputValue(this.phoneNumber);
AttributeBinding email =
(AttributeBinding)bindings.getControlBinding("Email");
email.setInputValue(this.email);
AttributeBinding hireDate =
(AttributeBinding)bindings.getControlBinding("HireDate");
hireDate.setInputValue(this.hireDate);
AttributeBinding jobId =
(AttributeBinding)bindings.getControlBinding("JobId");
jobId.setInputValue(this.jobId);
// Коммитим и тем самым сохраняем новую строку
OperationBinding commitOperation =
bindings.getOperationBinding("Commit");
commitOperation.execute();
}
Проверим работу managed bean’a, убедившись, что в таблицу попала новая запись.
![](https://habrastorage.org/storage2/099/d5c/d26/099d5cd26a9fdb722d56106624aafc17.jpg)
CRUD v3
И последний пример, в котором будет только использование кода.
Для начала нужно подготовить классы у Business Components.
Для этого откроем EmployeeView перейдем на вкладку Java и сгенерируем следующие классы.
![](https://habrastorage.org/storage2/057/03b/9bb/05703b9bb889c077cf79830dc165d0a5.jpg)
EmployeesViewImpl необходим для работы с запросами, а EmployeesViewRowImpl будет представлять из себя строку с атрибутами.
Таким же путем сгенерируем класс для Application Module.
![](https://habrastorage.org/storage2/f5e/09b/11d/f5e09b11ddea693e1e635eeea8c1d989.jpg)
Осталось написать новый метод для добавления строки в БД в EmployeesAppModuleImpl, создать TO класс для передачи данных в этот метод, и вызвать данный метод в managed bean’e.
Метод в Application Module:
public void createEmployee(EmployeeInfo employeeInfo) {
// Получаем ViewObject
EmployeesViewImpl employeeView = getEmployeesView1();
// Готовим новую строку.
EmployeesViewRowImpl employee = (EmployeesViewRowImpl)employeeView.createRow();
employee.setEmployeeId(employeeInfo.getEmployeeId());
employee.setEmail(employeeInfo.getEmail());
employee.setPhoneNumber(employeeInfo.getPhoneNumber());
employee.setFirstName(employeeInfo.getFirstName());
employee.setLastName(employeeInfo.getLastName());
employee.setHireDate(new Timestamp(employeeInfo.getHireDate()));
employee.setJobId(employeeInfo.getJobId());
// Производим операцию вставки.
employeeView.insertRow(employee);
// Коммитим
getDBTransaction().commit();
}
Новый метод bean’a:
public void createEmployee2(ActionEvent actionEvent) {
// Получаем application module
String applicationModuleClass = "com.matim.forhabr.model.EmplyeesAppModuleImpl";
String config = "EmplyeesAppModuleLocal";
EmplyeesAppModuleImpl appModule = (EmplyeesAppModuleImpl)
Configuration.createRootApplicationModule(applicationModuleClass, config);
// Забиваем данными TO
EmployeeInfo employeeInfo = new EmployeeInfo();
employeeInfo.setEmail(this.email);
employeeInfo.setEmployeeId(this.employeeId);
employeeInfo.setFirstName(this.firstName);
employeeInfo.setHireDate(this.hireDate);
employeeInfo.setJobId(this.jobId);
employeeInfo.setLastName(this.lastName);
employeeInfo.setPhoneNumber(this.phoneNumber);
// Вызываем метод по созданию нового сотрудника
appModule.createEmployee(employeeInfo);
// Освобождаем ресурсы
Configuration.releaseRootApplicationModule(appModule, false);
// Так как вставка идет на стороне AppModule,
// то только для целей, обновления таблицы
// выполним операцию Execute
BindingContainer bindings = getBindings();
OperationBinding executeIterator =
bindings.getOperationBinding("Execute");
executeIterator.execute();
}
Проверяем работу:
![](https://habrastorage.org/storage2/44d/edc/66e/44dedc66eefb7dcb6ffae203cb1ab647.jpg)
На этом сегодня все. Много всего еще осталось за бортом по этой теме, поэтому оставлю ссылку на дополнительную информацию здесь.
P.S. Следующая статья будет о task flows.