Вызов хранимой PL/SQL-функции из ADF

Наконец-то разобрался как вызывать хранимые PL/SQL процедуры/функции из ADF, и для тех кто тоже хочет разобраться, но еще этого не сделал (а также для себя, чтобы не забыть), я написал это пошаговое руководство. За основу приложения взят пример из учебника “Developing Rich Web Applications With Oracle ADF” для стандартной демо-схемы БД Oracle HR.

1) В БД добавляем простую функцию (я решил подсчитать сумму зарплаты по департаменту):

create or replace function get_sum_salary_by_dept 
(
  p_dept_id in number 
) return number as 
  v_result number;
begin
  select sum(salary)
    into v_result
    from employees
    where department_id = p_dept_id;
  return v_result;
end get_sum_salary_by_dept;

2) Создаем имплементацию Application Module:
2

3) В получившийся java-класс добавляем общий метод (для удобства я его сделал статическим) запуска хранимых функций:

    // Some constants
        public static int NUMBER = Types.NUMERIC;
        public static int DATE = Types.DATE;
        public static int VARCHAR2 = Types.VARCHAR;

    //Делаем метод статическим и добавляем передачу в него транзакции
    /* В import надо добавить
       import java.sql.CallableStatement;
       import java.sql.SQLException;
       import java.sql.Types;
       import oracle.jbo.JboException;
       import oracle.jbo.server.DBTransaction;
    */
    public static Object callStoredFunction(DBTransaction tr, int sqlReturnType, String stmt,
                                            Object[] bindVars) {
      CallableStatement st = null;
      try {
        // 1. Create a JDBC CallabledStatement  
        st = tr.createCallableStatement(
               "begin ? := "+stmt+";end;",0);
        // 2. Register the first bind variable for the return value
        st.registerOutParameter(1, sqlReturnType);
        if (bindVars != null) {
          // 3. Loop over values for the bind variables passed in, if any
          for (int z = 0; z < bindVars.length; z++) {
            // 4. Set the value of user-supplied bind vars in the stmt
            st.setObject(z + 2, bindVars[z]);
          }
        }
        // 5. Set the value of user-supplied bind vars in the stmt
        st.executeUpdate();
        // 6. Return the value of the first bind variable
        return st.getObject(1);
      }
      catch (SQLException e) {
        throw new JboException(e);
      }
      finally {
         if (st != null) {
            try {
              // 7. Close the statement
              st.close();
            }
            catch (SQLException e) {
               throw new JboException(e);
            }
         }
      }
   }

4) Генерируем класс для объекта сущности:

4

5) В получившийся класс добавляем метод:

public Number callGetSumSalaryByDept() {
      Number n = this.getDepartmentId();
      return (Number)AppModuleImpl.callStoredFunction(getDBTransaction(),
               AppModuleImpl.NUMBER, “get_sum_salary_by_dept(?)”, new Object[]{n});
}

 

6) Генерируем классы для объекта представления и строки представления:

6

7) В класс объекта представления (в моем примере DepartmentsViewImpl.java) добавляем метод, вызывающий метод класса сущности:

    public Float getDepartmentSalarySum(Row row){
        DepartmentsViewRowImpl currentRow = (DepartmentsViewRowImpl)row;
        DepartmentsImpl departmentEntity = currentRow.getDepartments();

        Float res = departmentEntity.callGetSumSalaryByDept().floatValue();
        return res;
    }

 

8) В свойствах представления, на вкладке Java, в разделе Client Interface, кликаем кнопку редактирования и, в открывшемся окне, переносим наш метод в Selected:

8

9) С моделью на этом все. Нажимаем Save All и Rebuid All и переходим к интерфейсу

10) Для управления я взял основную страницу приложения (в моем примере DeptEmpPage.jsf). В AppModuleDataControl присутствует наш метод:

11

11) Из палитры компонентов бросаем на страницу кнопку (Button):

11_

12) У отмеченной кнопки нажимаем на выпадающее меню (Button Actions, справа от кнопки) и выбираем Bind to ADF Control в котором выбираем наш метод:

12

После этого откроется окно Edit Action Binding:

12-2

В этом окне, в параметрах, в колонке Value, нужно открыть выпадающий список и выбрать Show El Expression Builder. В открывшемся окне выбрать источник откуда параметр получит строку (в моем примере текущая строка):
12-3

Нажимаем OK везде, где оно есть

13) В свойствах кнопки, в поле Text переименовываем ее в что-либо более человечное Подмигивающая рожица

14) Из Data Control кидаем возвращаемое значение метода на страницу и выбираем Text –> ADF Output Text w/ Label (можем сразу и изменить label):
14

15) Теперь создадим Partial trigger, чтобы после вызова функции, в компоненте Output Text отобразилось возвращаемое значение. Для этого в свойствах текста (Output Text), в разделе Behavior, нажимаем правую кнопку на свойстве Partial Triggers и выбираем Edit. В открывшемся окне переносим, созданную ранее кнопку в Selected:
15
Нажимаем OK

16) Сохраняем и запускаем наше приложение. После запуска нажимаем кнопку и наслаждаемся результатом:
16

Ссылки:
Мой готовый пример
руководство Developing Rich Web Applications With Oracle ADF
раздел документации Developing Fusion Web Applications with Oracle Application Development Framework – 16 Extending Business Components Functionality

Установка русской MSDN Library на английскую VS2010, продолжение

К сожелению выяснилось, что после установки библиотеки, описанной в предыдущей статье, не работает обновление через интернет, а так же добавление новых (например, доку по Silverlight’у) и удаление (!) старых разделов. Обидно, но студию пришлось удалить полностью, потом руками удалить HelpLibrary и потом студию поставить обратно и накатить SP1. LanguagePack на Help не трогал, видимо он остался жить в системе какой-то своей жизнью. Дальше процесс такой:

1. Правим ярлык “Manage Help Settings” как написано в предыдущей статье

2. Устанавливаем русские библиотеки из интернета

3. Правим queryManifest.?.xml: копи-пастим весь каталог с русскими библиотеками и в одной копии меняем атрибут productLocale на “EN-US”

4. Запускаем студию, проверяем. Все работает.

Снимок

Установка русской MSDN Library на английскую Visual Studio 2010

Вот лично у меня локализованные среды разработки вызывают резкую антипатию (ставил ради интереса русскую Visual Studio 2008 долго искал где там Debug Подмигивающая рожица), чего нельзя сказать о документации (хотя она тоже бывает переведена так, что лучше бы и не переводили). Если с 2008 студией все было просто – ставим английскую студию без MSDN потом ставим MSDN от русской студии, то с 2010 студией не все так просто, но не невозможно.

Для установки понадобится: установленная Visual Studio 2010 ENG без библиотек Help’а, дистрибутив Visual Studio 2010 RUS (можно скачать trial, устанавливать ее мы все равно не собираемся), notepad Подмигивающая рожица

1. Распаковываем iso с русской VS2010, вытаскиваем оттуда папки Help и ProductDocumentation

2. Из папки Help устанавливаем Language Pack (HelpSetupLP_x64_RUS.exe или HelpSetupLP_x86_RUS.exe в зависимости от системы)

3. В папке ProductDocumentation правим файл HelpContentSetup.msha заменяя значения ru-ru на en-us

4. Правим ярлык “Microsoft Visual Studio 2010\Visual Studio Tools\Manage Help Settings – ENU” в поле “Объект” меняем параметр /locale с en-US на ru-RU

image

5. Запускаем Manage Help Settings (должно запуститься на русском языке) и выбираем “Установить содержимое с диска”

6. В качестве “Расположения носителя справки” выбираем правленный HelpContentSetup.msha

image

7. Выбираем что хотим установить и давим “Обновить”

image

8. Залезаем в папку с установленным хелпом (по-умолчанию c:\ProgramData\Microsoft\HelpLibrary) и  бекапим её

9. Заходим в catalogs\VS\100 там 2 папки: EN-US и RU-RU, переносим все из EN-US в RU-RU

10. Заходим в manifest и правим файл queryManifest.3.xml методом удаления строк как показано на картинке ниже

image

11. Запускаем студию, вызываем Help

image

12. Убеждаемся что все работает, убиваем бэкапы

PS: Вполне может быть, что какой-то шаг я пропустил, потому, что папка с заготовленной ProductDocumentation у меня была подготовленна задолго до написания этой статьи.

PS2: Вполне возможно, что шаг 9 является лишним

UPD: Продолжение