Logo
Wyślij zapytanie
Case studies

Oracle APEX - Dobre Praktyki

Klaudia Stępień
Klaudia Stępień
Oracle APEX - Dobre Praktyki

Tworząc aplikację przy użyciu Apexa, chcemy rozwiązań, które nie tylko spełnią oczekiwania funkcjonalne, ale także będą zoptymalizowane, oszczędne pod względem pamięci i przemyślane pod kątem prostoty konstrukcji. Niestety, na wczesnym etapie apexowej kariery deweloperzy są często pochłonięci poznawaniem funkcjonalności, zaniedbując przy tym aspekt prostoty w projektowaniu.

Z tego powodu zgromadziliśmy najważniejsze wskazówki, które pomogą Ci poprawić jakość Twojego kodu jak i efektywność aplikacji, które tworzysz. Opierając się na naszych doświadczeniach oraz czerpiąc z mądrości ekspertów platformy Apex i PL/SQL, takich jak Steven Feuerstein, Jeffrey Kemp i Michelle Skamene, podajemy 14 dobrych praktyk, które często są pomijane na początku nauki APEX-a, ale których zastosowanie przynosi wymierne korzyści.


1. Ogranicz ilość kodu – Pisz tylko zapytania wypełniające raporty i tabele

Jedynymi instrukcjami SQL, które należy pisać w Application Builder są zapytania wypełniające raporty i tabele. Nawet wtedy powinniśmy uprościć te zapytania tak bardzo, jak to możliwe, korzystając z widoków i, w przypadku niektórych złożonych scenariuszy, funkcji tabelarycznych.

Korzystając z narzędzi dostępnych dziś, jak choćby ChatGPT, mamy możliwość łatwego generowania kodu, przez co korzystamy z nich nadmiernie. Prowadzi to do tego, że piszemy zapytanie za zapytaniem, kopiujemy kod z jednego warunku/procesu do drugiego. Efektem jest narastająca ilość powtórzeń tego samego zapytania w wielu miejscach, a także duplikacji tych samych reguł zapisanych w różnych warunkach, które w razie potrzeby musimy edytować osobno. Dlatego dobrą praktyką jest tworzenie funkcji w bazie danych, dzięki której ten sam blok kodu mamy zachowany w jednym miejscu, a jego edycji dokonujemy raz. Ponadto chcąc wykorzystać kod ponownie, wystarczy odwołać się do stworzonej funkcji.


2. Nie powtarzaj kodu

W miarę możliwości należy unikać powtarzania kodu. Ograniczmy ilość kodu wewnątrz aplikacji Oracle Application Express przenosząc jak najwięcej do pakietów PL/SQL. Zamiast pisać obszerne anonimowe bloki w procesach i warunkach, przenieśmy ten kod do przechowywanych jednostek programu. Pozwoli nam to jednocześnie zachować porządek oraz zoptymalizować aplikację.

Za zaletą pakietów przemawia również historia opisana przez Jeffrey’a Kempa, który w swoim artykule podaje, że duża ilość logiki PL/SQL,którą miał w swojej aplikacji, prowadziła do dynamicznego kompilowania kodu za każdym razem, gdy strona była ładowana lub przetwarzana. Przeniesienie tego kodu do bazy danych spowodowało, że był kompilowany tylko raz. Dzięki temu łatwiej było mu dostrzec zduplikowany kod oraz dostosować go tak, aby ta sama procedura była wywoływana z wielu stron.


3. Używaj IDE, aby sprawnie poruszać się w kodzie

Używanie IDE do formatowania wszystkich instrukcji SQL i PL/SQL, znacząco ułatwi nam odczytywanie i rozpoznawanie kodu. Mimo, że sama platforma APEX tego nie wymaga, praca z większą ilością kodu jest znacznie łatwiejsza, w efekcie czego prowadzi do mniejszej ilości błędów dewelopera.


4. Przekazuj wartości za pomocą parametrów

Przekazujmy wartości elementów za pomocą parametrów. Widzimy wtedy co przekazujemy do innych funkcji, na przykład, jakie elementy Apexa wprowadzamy. Jeśli wywołamy funkcję bez parametrów to nie wiemy co przyjmuje i co przekazuje, co utrudnia zrozumienie danego podprogramu.


5. Unikaj używania funkcji V

Unikajmy używania funkcji V do uzyskiwania wartości zmiennej na podstawie jej nazwy. Dlaczego? Ponieważ nie widzimy jakie argumenty trafiają do naszej funkcji. Jeśli w ciągu życia aplikacji elementy, z których korzystaliśmy zmienią swoje nazwy, to środowisko APEX tego nie wykryje i nie powiadomi nas o błędzie. Zamiast funkcji V korzystajmy z parametrów.

Oto przykład:

Stwórzmy przykładową funkcję, której zadaniem jest zwrócenie wartości Y, kiedy dany pracownik jest czyimś leaderem oraz wartości N w przypadku, kiedy nie jest. Wartość elementu, o który opieramy swoje sprawdzenie pobieramy za pomocą funkcji V.

CREATE OR REPLACE FUNTION is_lead_team
	RETURN CHAR
IS
	v_flag CHAR(1);
BEGIN
	SELECT
		CASE
			WHEN EXISTS (
				SELECT 1
				FROM PEQ_EMPLOYEE
				WHERE direct_manager_employee_id  = v(‘P7_USER_ID’)
			)
			THEN ‘Y’
			ELSE ‘N’
		END AS team_lead
	INTO
		v_flag
	FROM
		DUAL;
	RETURN v_flag;
END;

Funkcję wywołujemy w ten sposób:

--PL/SQL
RETURN is_team_lead();

W tym przypadku nie widzimy, jakie argumenty trafiają do naszej funkcji. Jeśli w ciągu życia aplikacji elementy, z których korzystaliśmy zmienią swoje nazwy, to środowisko APEX tego nie wykryje i nie powiadomi nas o błędzie.

Zamiast wywoływania funkcji V, przekazujmy wszystkie wartości elementów do funkcji i procedur za pomocą parametrów.

CREATE OR REPLACE FUNTION is_lead_team (
	v_user_id IN VARCHAR2
)
    RETURN CHAR
IS
	v_flag CHAR(1);
BEGIN
	SELECT
		CASE
			WHEN EXISTS (
				SELECT 1
				FROM PEQ_EMPLOYEE
				WHERE direct_manager_employee_id  = v_user_id
			)
			THEN ‘Y’
			ELSE ‘N’
		END AS team_lead
	INTO
		v_flag
	FROM
		DUAL;
	RETURN v_flag;
END;
RETURN is_team_lead(:P20_USER_ID);

Dzięki sparametryzowanej funkcji Oracle Application Express może sprawdzić w czasie kompilacji dowolnego procesu lub warunku, który wywołuje tę funkcję, czy nazwa elementu jest błędnie wpisana (a zatem niezdefiniowana).

oa5.png

Odczytując wywołanie tej funkcji wewnątrz aplikacji, każdy może również natychmiast zobaczyć, że funkcja opiera się na wartościach identyfikatora użytkownika, co znacznie ułatwia utrzymanie kodu.


6. Stosuj zmienne bindowane, aby skrócić zapytanie

W zapytaniach lepiej jest użyć zmiennej bind :APP_USER, ponieważ nie uruchamia ona PL/SQL. Dzięki tej praktyce zapytanie będzie trwało krócej, gdyż odczyt zapytania odbędzie się w całości w SQL-u. Używając funkcji V spowodujemy, że każda linijka kodu, spełniająca warunek zapytania, wymusi przełączenie się kontekstów na PL/SQL-a.

SELECT task_name
FROM tasks
WHERE assigned_to=v('APP_USER');

Versus

SELECT task_name
FROM tasks
WHERE assigned_to=:APP_USER;

7. Do stałych wartości wykorzystuj substitution strings

W przypadku, gdy w naszej aplikacji pojawiają się stałe wartości, takie jak nazwa aplikacji, zaleca się korzystanie z substitution strings lub zmiennych statycznych zdefiniowanych na poziomie aplikacji.

Substitution string to specjalna forma oznaczana przy użyciu składni, na przykład &APP_NAME., która reprezentuje z góry zdefiniowaną wartość. Wykorzystanie substitution string pozwala na dynamiczne odwoływanie się do stałych w różnych miejscach aplikacji.

oa8.png

oa9.png

Odpowiednie zastosowanie substitution strings sprawi, że nasza aplikacja stanie się bardziej elastyczna, umożliwiając łatwe dostosowanie wartości stałych na poziomie całego projektu. W ten sposób unikamy wielokrotnego wprowadzania tych samych danych w różnych częściach aplikacji, co przyczynia się do zwiększenia spójności kodu i ułatwia jego utrzymanie. Warto więc świadomie korzystać z substitution strings, aby uczynić naszą aplikację bardziej efektywną i dostosowywalną.


8. W miarę możliwości - unikaj substitution string w zapytaniach

W celu optymalizacji wydajności zapytań w Oracle APEX, zaleca się unikanie substitution stringów i zamiast tego używanie zmiennych bind, na przykład :ZMIENNA zamiast $ZMIENNA. Przechodzenie na zmienną bind może znacząco wpłynąć na oszczędność zasobów, ponieważ pozwala Oracle na efektywne ponowne użycie zapytań.

Nie rób tego w SQLu:

'f?p=&APP_ID.:PAGE:&SESSION.::&DEBUG.:'

Rób tak:

'f?p=' || :APP_ID || ':PAGE:' || :APP_SESSION || '::' || :DEBUG || ':'

Wersja ze zmienną bind umożliwia ponowne użycie tego samego zapytania, co przyczynia się do zminimalizowania obciążenia pamięci shared pool. Unikamy w ten sposób zalewania pamięci unikalnymi instrukcjami, które nie mogą być efektywnie ponownie wykorzystane.


9. Używaj zmiennej #TIMING# do identyfikacji powolnych regionów raportów

Warto skorzystać ze zmiennej #TIMING# w stopce regionu raportów, jeśli chcemy wyświetlić czas ich uruchomienia. Wykorzystanie tej zmiennej może znacząco pomóc w identyfikacji regionów raportów, które działają szczególnie powoli na stronie. Informacja o czasie uruchomienia pozwala skoncentrować się na obszarach wymagających głębszej analizy, co z kolei ułatwia optymalizację wydajności aplikacji. Dzięki tej prostej praktyce zyskujemy narzędzie do szybkiego rozpoznawania potencjalnych problemów i skutecznej optymalizacji naszych raportów w Oracle APEX.

oa11.png

Zadeklarowana zmienna #TIMING# wyświetla się pod tabelą, jak na załączonym poniżej obrazku:

Obraz1.png


10. Używaj logiki deklaratywnej do poprawy wydajności

Najefektywniejszym sposobem na uniknięcie nadmiernego kodowania jest unikanie pisania kodu tam, gdzie nie jest to konieczne. W kreatorze aplikacji APEX warto wykorzystać elementy deklaratywne, zwłaszcza w przypadku definiowania warunków wyświetlania elementów na stronie.

oa13.png

Podczas określania warunków, kiedy konkretne elementy powinny być widoczne, zaleca się korzystanie z predefiniowanych typów warunków i walidacji, dostępnych w APEX. Wykorzystanie wbudowanych elementów nie tylko redukuje ilość kodu, ale również poprawia wydajność aplikacji, ponieważ ta logika jest integralną częścią frameworka.


11. Stosuj Build Options zamiast Server Side Conditions, aby nie tracić warunków

Zamiast ustawiania warunków dla poszczególnych komponentów w Server Side Condition na Never, zaleca się korzystanie z funkcji Build Options ze statusem Exclude dostępnej w Shared Components. Build Options stosujmy do różnych komponentów strony, oceniając efekty każdej zmiany na stronie.

oa14.png

oa15.png

Opcje Status w Build Options obejmują:

Include: Włącz tę funkcję lub składnik. Powiązane składniki aplikacji są włączone i dołączone do aplikacji.

Exclude: Nie dołączaj tej funkcji lub składnika. Powiązane składniki aplikacji są wyłączone i wykluczone z aplikacji.

oa16.png

Utworzony build można następnie zastosować w Configuration, dostępnej m. in. w opcjach związanych z regionem ale także w itemach i processingach. Taki sposób zarządzania opcjami budowy pozwala unikać utraty wcześniej zdefiniowanych warunków w Server Side Condition. Aby skuteczniej optymalizować aplikację, po utworzeniu builda, możesz go dołączać do dowolnych itemów/regionów i uruchamiać stronę bez utraty wcześniej ustalonych warunków.


12. Używaj Activity Monitor do optymalizacji aplikacji

W przypadku, gdy nasza aplikacja wydaje się działać wolno, a nie znamy przyczyny, warto skonsultować Activity Monitor, który może dostarczyć cennych informacji. W monitorze aktywności dostępnych jest kilka raportów, z których szczególnie przydatny może okazać się By Weighted Page Performance.

Rozwiń listę i kliknij Activity Monitor:

oa17.png

I następnie w Page View Analysis wybieramy By Weighted Page Performance:

Obraz2.png

W tym raporcie każda odsłona strony w przestrzeni roboczej i aplikacji jest rejestrowana z informacjami o użytkowniku, dacie, znaczniku czasu, aplikacji, page_id i najważniejsze, czasie, który upłynął. Warto skupić się na stronach, które wykazują dużą liczbę eventów (czyli częste dostępy) oraz wysoki średni czas wyświetlania.

Obraz3.png

Activity Monitor umożliwia wygodną analizę z interaktywnego raportu. Jednak, jeśli potrzebujemy bardziej szczegółowych informacji, możemy uzyskać dostęp do pełnych danych poprzez widok APEX_WORKSPACE_ACTIVITY_LOG. Regularne sprawdzanie Activity Monitor stanowi skuteczny sposób na identyfikację obszarów wymagających optymalizacji w naszej aplikacji Oracle APEX.


13. Popraw wydajność z Region Caching

Aby zwiększyć wydajność aplikacji, szczególnie w przypadku dashboardów, które są często odwiedzane przez wielu użytkowników a dane nie muszą być odświeżane przy każdym wyświetleniu strony, włącz opcję Server Cache, dostępną w ustawieniach regionu.

oa20.png

Domyślnie buforowanie jest wyłączone, jednak po włączeniu tej opcji możemy skonfigurować limit czasu buforowania. Ustawienie odpowiedniego czasu pozwala zoptymalizować wydajność dashboardu, a im większa wartość limitu czasu buforowania, tym lepiej.

W przypadku włączeniu buforowania, możesz poinformować użytkowników o ostatnim odświeżeniu danych. W takim przypadku użyj funkcji APEX_UTIL.CACHE_GET_DATE_OF_REGION_CACHE.

oa21.png

Region Caching to skuteczne narzędzie, które pozwala ograniczyć niepotrzebne odświeżanie danych przy każdym wyświetlaniu strony, co przekłada się na szybsze i bardziej efektywne korzystanie z aplikacji Oracle APEX.


14. Sprawdź swój kod z APEX Advisor

APEX Advisor to program, który analizuje kod pod kątem błędów i złych praktyk. Uruchamia wstępnie napisane automatyczne testy w celu sprawdzenia:

  • błędów programistycznych,
  • problemów związanych z bezpieczeństwem,
  • ostrzeżeń,
  • wydajności,
  • użyteczności, itp.

oa22.png

Wygenerowanie wyników może zająć trochę czasu, zależy ono od rozmiaru aplikacji i liczby wybranych kontroli do wykonania. Po zakończeniu wyświetlone zostaną wyniki każdego sprawdzenia oznaczonego jako problem.

Każdy wynik zawiera szczegółowe informacje na temat kontroli, w tym:

  • lokalizację w aplikacji,
  • sprawdzany atrybut,
  • kategorię i typ sprawdzenia,
  • komunikat wyjaśniający, dlaczego błąd został oznaczony,
  • wartość - może to być na przykład nieprawidłowe zapytanie lub link.

Przycisk Wyświetl przeniesie nas do źródła błędu w kreatorze stron co ułatwia i przyspiesza proces naprawy wykrytych problemów.

oa23.png

Powyższe wskazówki pochodzące od ekspertów pomogą nam sprawniej korzystać z APEXa oraz udoskonalić nasz kod. Dzięki temu poprawimy wydajność tworzonych aplikacji oraz jakość naszej pracy.