Gestiunea Resurselor Unui Parc Auto
GESTIUNEA RESURSELOR UNUI PARC AUTO
CUPRINS
CAPITOLUL 1. BAZE DE DATE
1.1. NOȚIUNI GENERALE DESPRE BAZELE DE DATE
Instanțe și scheme
Schema relațională
Independența de date
Independența logică de date
Independența fizică de date
Avantajele bazelor de date relaționale
Limbaje ale bazelor de date
Funcțiile unui SGBD
Clasificarea SGBD-urilor
1.2. SISTEMUL DE GESTIUNE AL BAZELOR DE DATE ORACLE
CAPITOLUL 2. INTERFAȚA GRAFICĂ ÎN JAVA
2.1. INTRODUCERE ÎN INTERFAȚA JAVA
2.1. MODELUL AWT ȘI SWING
CAPITOLUL 3. APLICAȚIA “GESTIUNEA RESURSELOR UNUI PARC AUTO”
3.1. DESCRIEREA MODELULUI
3.2. DESCRIEREA ENTITĂȚILOR ȘI RELAȚIILOR
3.3 . DIAGRAMA ENTITATE – RELAȚIE
3.4. DIAGRAMA CONCEPTUALĂ
3.5. PREZENTAREA APLICAȚIEI
ANEXĂ
BIBLIOGRAFIE
CAPITOLUL 1. BAZE DE DATE
1.1. NOȚIUNI GENERALE DESPRE BAZELE DE DATE
În ultima perioadă, dezvoltarea sistemelor de baze de date, a reprezentat unul dintre cele mai importante aspecte din domeniul IT, fapt ce a avut un impact decisiv asupra modului de funționare și organizare a companiilor.
Aici se încadrează companiile de comunicație, serviciile de transport, întreprinderile de comerț, băncile, companiile de asigurare, universitățile etc, acestea depinzând de funcționarea corectă și neîntreruptă a sistemelor de baze de date.
Sistemele de baze de date, sunt o componentă importantă a vieții zilnice în societatea modernă. Zilnic, cea mai mare parte a persoanelor, desfașoară activități au legătura cu lucrul cu o bază de date: rezervarea biletelor de avion sau de tren, tranzacțiile bancare, căutarea unui job, comerțul online etc.
O bază de date poate avea dimensiuni si complexități foarte variate, de lao agendă a unui telefon mobil până la mii de înregistrări ( un magazin online, baza de date cu clienți sau cu angajații unei companii).
Majoritatea sistemelor de baze de date care există in momentul de față sunt relaționale, existând un număr foarte mare de astfel de sisteme comerciale ce se pot achiziționa si utiliza în scopul propriilor dezvoltări.
În sens larg, baza de date reprezintă o colecție de date centralizate, corelate logic, creată și menținută computerizat, cu scopul de a prelucra datele, în contextul unei aplicații.
În comparație cu metodele vechi de stocare si înregistrare a datelor unor anumite activități, pe documente scrise sau in fișiere salvate pe discuri, bazele de date, prezintă avantaje considerabile cum ar fi:
controlul centralizat al datelor (permite unei companii să desemneze una sau mai multe persoane responsabile cu administrarea bazei de date);
flexibilitatea (constă în faptul că poate fi modificată structura bazei de date, fără a necesita modificarea majoră a softurilor de aplicație);
viteza mare de de actualizare și regăsire a informațiilor stocate;
compactarea (spațiul de stocare a sistemele de baze de date este foarte redus comparativ cu documentele scrise);
Standardizarea modului de introducere a datelor, permițând interschimbarea acestora între mai multe organizații.
În contextul societății actuale care prezintă un flux de informație de mai multe tipuri, ce circulă prin diferite canale, apare necesitatea unor instrumente complexe pentru stocarea, procesarea și, mai ales, interpretarea acestora. Astfel, a apărut necesitatea de a transforma informația în date și de a le organizarea într-o formă care să permită accesarea lor în orice moment și să poată fi extrase rapid și in mod exact pentru a putea fi folosite pentru un scop predefinit si precis.
Datele reprezintă fapte regasite și adunate din lumea reală. Acestea sunt preluate din observații si măsuratori ce pot fi disparate și necoordonate între ele. Pot fi formate din litere, imagini, numere și altele. Datele în sine, neprelucrate și prezente intr-una din formele amintite, nu au niciun fel de semnificație.Fiind doar o înșiruire de caractere sau imagini, ele chiar pot fi primi diverse interpretări, multe dintre ele greșite.
Informațiile reprezintă date organizate, ce au fost ordonate, selectate și grupate după anumite criterii stabilite. Informațiile se modifică destul de des, ele depinzând de datele stocate în bază dar și de modul de procesare și prezentare. Un sistem de date optim conceput, permite transformarea în dublu sens a informațiilor în date și apoi a datelor înapoi în informații, fără denaturarea sensului lor inițial.
Hemandez, descrie succint diferențele dintre informații și date: „Datele reprezintă ceea ce se înmagazinează; informația reprezintă ceea ce se extrage”.
Datele sunt stocate în baze de date, sunt statice și nu se modifică până ce asupra lor nu intervine un administrator al bazei de date.
Sunt mai multe concepte aplicate datelor pentru a permite transformarea acestora în informatii:
organizarea datelor – datele trebuie sa fie organizate astfel încât să permită prelucrarea lor;
caracterisicile datelor – determinarea caracteristicilor datelor ce permit extragerea esenței semnificației lor este importantă pentru determinarea modului de organizare a acestora în cazul unei aplicații;
modelul de date – este constituit dintr-o mulțime consistentă de reguli;
schema – conține denumirea obiectelor din baza de date, a atributelor și a asocierilor dintre acestea pentru un anumit model;
colecție de date – un ansamblu organizat de date în funcție de mai multe criterii;
mulțimea – ansamblul obiectelor ce au o identitate proprie, condiționate de anumite apartenențe;
organizarea datelor – definirea și structurarea în colecții a datelor
fișierul – o grupare de date, organizate în funcție de criterii calitative de prelucrare și scop. Fișierul are o denumire univocă și conține întotdeauna o cantitate de date bine definită care determină mărimea fișierului.
baza de date – Elsmari și Navathe au definit ca fiind baza de date ca o colecție de date ce se află în asociere. În sens larg, baza de date înseamnă o grupare de date centralizate, corelate logic, creată și menținută computerizat, cu scopul de a prelucra datele, în contextul unei aplicații.
Modelul relațional se bazează pe noțiunea de relație matematică, care corespunde unei entități și are o reprezentare ușor de înțeles și manipulat. Entitățile constau într-un tabel bidimensional care este compus din linii și coloane.
Acesta a fost inventat de E.F. Codd de la IBM în 1970, care a publicat lucrarea “Un model relațional de date pentru bănci mari de date partajate”. Ulterior, acesta împreună cu R.Boyce și J.D. Ullman au perfecționat acest model și au permis dezvoltarea sistemelor de baze de date. ([4]).
Modelul de date orientat obiect se bazează pe limbaje de programare orientate obiect, în care datele sunt independente de durata de viață a programelor care le creează și accesează.
De-a lungul timpului, comunitatea internațională a făcut eforturi semnificative pentru redefinirea și înbunătățirea limbajelor bazate pe calculul rațional sau pe algebra rațională. Astfel, a fost dezvoltată o serie de versiuni ale limbajelor raționale precum: SQL, QUEL și QBE.
Numele SQL, pronunțat “sequel” sau S-Q-L, provine din limba engleză din sintagma Structered Query Language. SQL a fost folosit prima dată de către IBM în anul 1974, într-un proiect de cercetare System R, proiect ce funcționa pe sisteme mainfraime VS/2. Denumirea inițială dată de catre IBM a fost Structured English Query Language (sau SEQueL).
SQL se bazează pe calcul relațional ce folosește variabile compuse din tupluri. În anul 1986, Institutul Național American pentru Standarde (ANSI) a publicat standardele SQL, în acest fel contribuind la extinderea folosirii acestuia în comunitatea producătorilor de baze de date.
Produsele ulterioare ale firmei IBM, SQL/DS și DB2 folosesc acest limbaj.
Instanțe și scheme
Bazele de date sunt structure dinamice ce suferă modificări pe parcursul timpului.Instanța unei baze de date reprezintă ansamblul datelor aflate într-o bază de date la un moment dat.
Schema unei baze de date este proiectul general al bazei de date și reprezintă descrierea datelor conform modelului de date propus.
Schema bazei de date conține:
– informații referitoare la utilizator;
– descrieri de nivel înalt ale tranzacțiilor și aplicațiilor precum și legăturile utilizatorilor cu ele;
– relațiile dintre date și tranzacții;
– informațiile fizice de proiectare;
– statistici de utilizare
Schemele bazelor de date se pot clasifica după nivelul de abstractizare corespunzător în următoarele tipuri:
Schema externă (subschema) – sau aplicația, reprezintă vederea utilizatorilor asupra datelor de la un nivel superior. Aceasta corespunde unei valori a datelor și descrie vederile bazei de date ce se folosesc într-o anumită aplicație și corespunde schemei conceptuale.
Schema conceptuală (logică) – reprezintă perspectiva sistemului de gestiune al bazelor de date și corespunde nivelului conceptual. Aceasta prezintă articolele, relațiile și constrângerile dintre ele printr-o descriere abstractă și integrată a tuturor datelor, independent de sistemul de gestiune al bazelor de date folosit. Schema conceptuală trebuie să corespundă schemei interne.
Schema internă – sau implementarea/perspective realizării sistemului, se află la nivel inferior și conține definițiile tuturor înregistrărilor stocate în baza de date, metodele de reprezentare, câmpurile și indexurile datelor. Aceasta descrie modul de stocare fizică a datelor precum și structurile de acces la date.
Schema relațională
Metastructura sau structura relațională a unei baze de date mai este cunoscută si sub denumirea de schemă relațională. Aceasta reprezintă descrierea unei colecții particulare de date după un anumit model dat. În prezent, modelul relațional al datelor este cel mai utilizat model pe plan mondial.
Schema relațională predefinește posibilele stări ale unei baze de date:
– nicio stare a unei baze de date nu poate conține asocieri între 2 seturi decât dacă această asociere a fost predefinită în schema bazei de date;
– nicio stare a unei baze de date nu poate conține date care să nu fie obținute în urma instanțierii schemei respectivei baze de date.
Procedurile de manipulare a datelor trebuie să fie separate de date. Conceptul de bază ce fundamentează modelul relațional al datelor este dat de relație, aceasta fiind transformată într-un tabel ce conține rânduri și coloane. Pentru fiecare relație există o schemă care descrie coloanele sau câmpurile tabelului – schema bazei de date. Aceasta conține:
– definiția tipurilor de date;
– definiția relațiilor dintre acestea, specificând pentru fiecare dintre ele: intensia (numele tuturor atributelor) și cheia primară.
Este des întâlnit ca într-un sistem relațional atât schema conceptuală cât și cea internă sa fie scheme relaționale. În practică se intâlnește o nptație general acceptată pentru a prezenta proiectul unei baze de date independent de orice limbaj de definire a datelor. Aceasta are formatul:
<nume relatie>: <lista numelor atributelor>
Utlizarea unei astfel de notații este foarte utilă în scopul clarificării organizării generale a bazei de date, dar nu lămurește o serie de detalii cu privire la proprietățile domeniilor de valori ale atributelor. De aceea, pentru o definire mai completă a componentelor bazei de date se poate folosi notația originală propusă de Codd, cu ajutorul căreia se pot crea entitățile, atributele, domeniile de valori precum și cheile sub forma unor entități ale schemei bazei de date. Un astfel de limbaj definește doar structura acestor entități, nu și conținutul lor.
Independența de date
Independența de date înseamnă că în situația aplicării de modificări de date la nivelele inferioare, nivelele superioare nu sunt afectate. Aceasta mai înseamnă și că vederea unui utilizator (schema externă) este independentă de vederea altui utilizator. Independența datelor are un efect foarte favorabil, în special în situația aplicării de modificări de către ad ministratorul bazei de date care poate face modificări ale vederii unui singur utiliosi notația originală propusă de Codd, cu ajutorul căreia se pot crea entitățile, atributele, domeniile de valori precum și cheile sub forma unor entități ale schemei bazei de date. Un astfel de limbaj definește doar structura acestor entități, nu și conținutul lor.
Independența de date
Independența de date înseamnă că în situația aplicării de modificări de date la nivelele inferioare, nivelele superioare nu sunt afectate. Aceasta mai înseamnă și că vederea unui utilizator (schema externă) este independentă de vederea altui utilizator. Independența datelor are un efect foarte favorabil, în special în situația aplicării de modificări de către ad ministratorul bazei de date care poate face modificări ale vederii unui singur utilizator fără a afecta vederile celorlalți utilizatori.
Există 2 niveluri de independență a datelor, conform organizațiilor ANSI/SPARC
Independența logică a datelor
Independența fizică a datelor.
Independența logică de date
Face referire la imunitatea bazelor externe față de modificări ce pot apărea în schema conceptuală. Aceste modificări pot fi: introducerea sau eliminarea unei noi entități, introducerea sau stergerea atributelor, introducerea sau stergerea unei relații.
Independența fizică de date
Aceasta face referire la imunitatea schemei conceptuale asupra schemei interne. Modificările pot fi: fișierele pot fi organizate diferit, pot exista stocări sau dispozitive de stocare diferite sau pot fi indecsi sau algoritmi diferiți.
Avantajele bazelor de date relaționale
Avantajele bazelor de date relaționale sunt multiple:
integritatea și precizia datelor – se pot defini condiții astfel incât datele din cadrul unei tabele să nu poată fi introduse de mai multe ori. În cazul unei relații dintre tabele este asigurată validitatea acestora precum și acuratețea logică a datelor.
independența logică și fizică a colecțiilor de date fața de programele care rulează;
precizia și consistența datelor – există numeroase niveluri de integritate ce se pot introduce în baza de date;
datele pot fi extrase cu ușurință din bază, pe baza cerintelor utilizatorului. Acestea pot fi extrase din mai multe tabele care relaționează, oferind prezentarea datelor într-o multitudine de moduri;
Limbaje ale bazelor de date
Există 2 categorii de împărțire ale limbajelor: DDL (Data Definition Language) limbaje de definire a datelor și DML (Data Manipulation Language).
DDL se utilizează pentru crearea schemei bazei de date, iar DML pentru citire si reactualizare bazei.
Figura 1.1. Limbaje ale bazelor de date
După compilarea instrucțiunilor DDL, rezultatul obținut este reprezentat de un set de tabele stocate în fișiere, denumite catalog de sistem. Acest set definește metadate-le adică date despre date. Acest sistem oferă posibilitatea utilizatorului să denumească și să descrie atât entitățile cerute de aplicație cât și relațiile care pot exista între diferite entități.
DML reprezintă un set de de operațiuni pentru manipularea informațiilor din baza de date cum ar fi: inserarea noilor date, modificările datelor existente, regăsirea datelor sau ștergerea acestora.
De asemenea, aceste limbaje DML se pot impărți în 2: procedurale și neprocedurale.
Cele procedurale descriu modul de obținere a rezultatului unei instrucțiuni pe când cele neprocedurale desriu doar rezultatul care trebuie obținut.
Un sistem de gestiune a bazelor de date reprezintă un complex de programe care asigură interfața între o bază de date și utilizatorii acestuia. SGBD-ul este componenta software care asigură legătura și interdependența elementelor sistemului.
SGBD-ul are numeroase roluri în contextul unui sistem de baze de date:
definire și descriere a structurii bazei de date, lucru ce se realizează printr-un limbaj specific, conform unui anumit model de date;
încărcare și validare a datelor în baza de date cu respectarea restricțiilor de integritate definite în modelul de date;
realizarea accesului la date pentru diferite operațiuni (actualizări, interogări);
întreținerea bazei de date cu ajutorul editoarelor, browsere sau convertoare;
protejarea bazei de date prin asigurarea securității și integrității datelor.
Funcțiile unui SGBD
Descrierea datelor: definirea atributelor din cadrul structurii, a legăturilor dintre tabele sau dintre atributele aceleași entități cu ajutorul LDD;
Manipulare a datelor: inserarea, actualizarea, prelucrarea și regăsirea datelor;
Funcția de utilizare a bazei de date: aceasta conține mulțimea interfețelor prin care utilizatorii pot interacționa cu baza de date;
Administrarea bazei de date: administratorul are rolul de a organiza baza de date conform unei diagrame conceptuală și de a coordona eficient proiectarea acesteia.
De asemenea, administratorul va autoriza accesul la informațiile din baza de date cu ajutorul unor conturi și parole, va reface baza de date in cazul unor incidente, va utiliza eficient memoria internă și externă și va realiza periodic rapoarte ce țin de analize statistice din baza cum ar fi numărul de utilizatori, numar de accesări sau actualizări etc.
Clasificarea SGBD-urilor
Clasificarea SGBD-urilor se poate face după mai multe criterii astfel:
În funție de sistemele de calcul pe care se implementează:
pentru calculatoare mari: acestea se folosesc în cazul bazelor de date foarte mari și complexe (DB2, Oracle, IMS)
pentru minicalculatoare: acestea se folosesc pentru baze de mari și complexe (Oracle)
pentru microcalculatoare: acestea se folosesc pentru baze de date de mărime si complexitate medie si mică
În funcție de limbajul de programare utilizat:
SGBD cu limbaj propriu este cel care deține un limbaj de manipulare a datelor specifice, este procedural și permite implementarea tuturor facilităților oferite de SGBD. Specialiștii în informatică pot programa în acesta, interfețe puternice și proceduri complexe facilitând un acces ușor și optimizat la baza de date.
SGBD cu limbaj “gazdă” cum ar fi Cobol și Pascal sau o extensie a unui astfel de limbaj. Ca și dezavanataj ar fi acela că formularea cererilor de regăsire se face mai greoi, uneori într-un mod inacesibil utilizatorilor finali.
În funcție de modelul logic de date implementat, SGDB-urile se pot clasifica în:
ierarhice – au fost primele utilizate în gestiunea bazelor de date, și implementează modelul de arbore arborescent;
de tip rețea – implementează modelul rețea, au diminuat din limitele utilizării celor ierarhice;
relaționale – au aplicabilitate în majoritatea domeniilor din lumea reală și prezintă avantajul că pot fi folosite de o gamă diversificată de utilizatori (FoxPro, Oracle, Access, Infomix);
orientate obiect – se folosesc în principiu pentru probleme mari, de complexitate ridicată (Oracle, VisualFoxPro) și implementează modelul de date orientat obiect;
În funcție de localizarea bazei de date SGBD-urile pot fi:
centralizate : toți utilizatorii au acces la datele aflate într-o singură bază de date centralizată.
distribuite: acestea gestionează datele care sunt amplasate pe mai multe calculatoare dintr-o rețea, tratându-le ca pe un tot unitar. Acestea au un grad de complexitate foarte ridicat și au componente speciale pentru realizarea conexiunilor și tratarea distribuită a datelor (de exemplu Oracle, DB2).
1.2. SISTEMUL DE GESTIUNE AL BAZELOR DE DATE ORACLE
Oracle este un sistem de gestiune a bazelor de date complex, extins, ce conține elemente din tehnologia orientată obiect.
Acest SGBD, a fost realizat de compania americană Oracle cu sediul central în SUA, companie ce este specializată în conceperea și comercializarea de componente hardware și de soluții software. La nivel mondial, Oracle se situează pe locul 3 în topul companiilor de software, după Microsoft și IBM.
Acest SGBD este funțional pentruu toate categoriile de computere (micro, mini, mainframe) și poate rula sub diferite sisteme de operare.
Oracle a realizat prima versiune de SGBD la finalul anilor ’70, versiune ce s-a bazat pe teoria relațională.
Compania a implementat incă de la început limbajul SQL pe care ulterior l-a dezvoltat față de versiunea standard, culminând cu SQLPlus.
Ca și evoluție în timp, versiunea 5.0 s-a lansat cu funționalități de arhitectură client/server, cu limbaj procedural propriu PL/SQL precum și cu precompilatoare ca interfață cu alte limbaje de programare.
Versiunea 8.0, lansată în 1997, a constituit de asemenea un progres deoarece aceasta permite trecerea de la arhitectura client/server către cea network computing. De asemenea, aceasta prezintă o deschidere mult mai mare, cu optimizări performante și luând în calcul partea de analiză (modelare-funcționalitate) față de programe (codificare).
După numai 1 an, compania lansează în 1998, SGBD Oracle 8i ca sistem de baze de date pe Internet.
Facilitățile introduse în această versiune sunt multiple, acesta fiind primul SGBD pentru Internet cu server Java inclus. Efectul a fost reducerea drastică a costurilor pentru realizarea unei aplicații (de până la 10 ori comparativ cu versiunea anterioară). Din acel moment, Oracle a devenit o platformă multiplă, putând fi folosită pe orice calculator, indiferent de sistemul de operare sau aplicație instalată pe acesta.
Oracle 8i conține diverse instrumente de dezvoltare a aplicațiilor, de la cele bazate pe modelare (Designer, Aplication Server, Developer) până la componente Java, instrumente bazate pe HTML cum ar fi browser-e sau editoare web si XML. Instrumentele de programare cum ar fi procedurile stocate (PL/SQL sau Java), obiectele standard, ODBC sau JDBC, frazele SQL sau cele de tip Internet WebDB fac din aceasta versiune una revoluționară în domeniul bazelor de date.
Ca și caracteristică, această versiune a fost reproiectată arhitectural pentru a se putea încadra în tendința de trecere de la arhitectura client/server la cea NC. Versiunea a permis de asemenea, dezvoltarea bazelor de date de orice dimensiune, în mod centralizat sau distribuit.
Alte facilități importante au fost cele de salvare și restaurare automate, partiționarea integrală pentru tabele și indecși, comunicarea și procesarea offline (mesagerie) chiar dacă aplicațiile nu sunt conectate.
Tot ca și facilități, putem aminti tehnologia object oriented, prin care se permite definirea și utilizarea unor obiecte de dimensiune și complexitate mare, optimizări pe cereri de regăsire prin reutilizarea comenzilor SQL identice care au fost lansate de diferiți utilizatori, precum și un grad ridicat de securitate prin utilizarea unui server de criptare, controlul traficului in rețea, parole, etc.
Oracle 8i, a permis lucrul cu depozite de date (Data Warehouse), acestea continând date multidimensionale obținute cu ajutorul tehnologiei OLAP.
Sistemul SGBD Oracle 9i, marchează trecerea la o nouă generație de servicii Internet oferind mai mult decât un suport pentru baze de date.
Acesta poate rula pe o infrastructură completă în cazul softurilor pentru e-business fiind compatibil cu o multitudine de sisteme de calcul și operare: LINUX, WINDOWS, IBM-AIX, SUN – SOLARIS, HP-UNIX.
Versiunea vine cu o protecție ridicată și automatizată, costurile cu administrarea bazei de date scazând foarte mult.
Principalele facilităti sunt:
Oracle 9i Real Application Clusters ce folosește tehnologia Cache Fusion, practic in momentul indroducerii unui nou computer într-o rețea ce utilizează baze de date Oracle, clusterele se adaptează automat, nemai fiind necesară rescrierea aplicației sau redistribuirea datelor din aceasta. Statistic vorbind, posibilitatea de apariție a unei erori la o configurație cu 12 calculatoare ce rulează Oracle 9i RAC este infimă, aceasta fiind estimată ca durata de timp la circa 100 000 de ani.
Oracle 9i Developer Suite, un mediu complex pentru crearea de aplicații de tip e-business sau Web, bazat pe tehnologiile Java și XML.
Oracle 9i Application Server, permite crearea si utilizarea de aplicații Web foarte rapide și ce permit integrarea serviciilor de Internet.
Versiunea Oracle 9i a fost îmbunătățită continuu în 2003 prin lansarea Oracle 10g, în 2007, odată cu lansarea Oracle 11g, versiune ce aduce în plus o gestionare mult mai eficientă a datelor cu ajutorul partiționărilor.
Ultima versiune este Oracle 12c și a fost lansată în anul 2013.
Arhitectura sistemului SGBD Oracle
Arhitectura de bază Oracle se compune din elemente dispuse într-o configurație client/server:
Figura 1.2. Arhitectura Oracle
Cele 2 componente sunt plasate pe computere diferite în cadrul unei rețele, asigurand funcționalități specifice astfel:
serverul, va asigura atât memorarea și manipularea informațiilor cât și administrarea bazei de date;
clientul asigură interfața cu utilizatorul care prin lansarea aplicației, accesează baza de date.
Arhitectura Oracle este structurată pe 3 niveluri:
Nucleul – conține limbajul SQL și PL/SQL;
Interfețele
Developer Suite – conține generatoarele Forms, Reports și JDeveloper;
Designer – destinată proiectanților de aplicații;
PRO*C – destinată programatorilor în FORTRAN, COBOL, PASCAL, C
DataWarehouse Builder – ajută la analize multidimensionale, utilizând tehnologia OLAP
Oracle Applications – permite crearea aplicațiilor business (Financials, Manufactoring, Projects)
Instrumentele – reprezintă componente destinate mentenanței și a funcționării în condiții optime a bazei de date Oracle. Aici putem face referire la Enterprise Manager Console, ce conține mai multe utilitare necesare unui administrator de baze de date.
CAPITOLUL 2. INTERFAȚA GRAFICĂ ÎN JAVA
2.1. INTRODUCERE ÎN INTERFAȚA JAVA
GUI (Interfața grafică cu utilizatorul), are un înțeles larg și presupune comunicarea vizuală între un program și utilizatorii săi. Ea reprezintă un segment al interfeței cu utilizatorul și ne ajută la înțelegerea intereacțiunii dintre program și utilizatori.
Limbajul Java pune la dispoziție o serie de clase ce ajută la implementarea diverselor funcționalități UI , dar în continuare vom discuta despre cele care permit realizarea interfeței grafice cu utilizatorul (GUI).
Odată cu lansarea limbajului Java, bibliotecile de clase s-au modificat continuu, odată cu trecerea de la o versiune la alta. Acest lucru este datorat, pe de o parte dificultății legate de implementarea noțiunii de portabilitate, iar pe de altă parte a integrării mecanismelor GUI cu noile tehnologii apărute cum ar fi Java Beans.
Momentan există 2 modalități de a crea o aplicație cu interfața grafică și anume:
AWT (Abstract Window Toolkit) – este API-ul inițial pus la dispoziție începând cu versiunile inițiale de Java;
Swing – face parte din proiectul JFC ( Java Foundation Classes ), creat în urma colaborării dintre SUN, Netscape și IBM. Swing are la bază modelul AWT, extinzând funcționalitatea acestuia și adăugând sau înlocuind componente pentru dezvoltarea aplicațiilor GUI.
Așadar , este de preferat ca aplicațiile Java, să fie dezvoltate cu ajutorul tehnologiei Swing, aceasta punând la dispoziție o paletă mult mai largă de facilități, însă nu vom renunța complet la AWT deoarece aici există clase esențiale, reutilizate în Swing.
Voi prezenta în cele ce urmează, module de tratare a claselor de bază, precum și a celor mai importante evenimentr din AWT, deoarece va fi simplificat procesul de înțelegere a dezvoltării unei aplicații GUI, după care voi face trecerea la Swing.
Pentru crearea unei aplicații grafice, vom lua in considerare următoarele aspecte:
Partea de design
alcătuirea unei ferestre unde vom afișa obiectele grafice (componente) ce ne vor ajuta la interacțiune cu utilizatorul (listele, butoanele și controalele pentru editarea textelor, a listelor, etc);
definirea si așezarea componentelor pe suprafața de afișare la pozițiile corespunzătoare;
Partea de funcționalitate
crearea de acțiuni ce urmează a se rula atunci când un utilizator va interacționa cu obiecte grafice din aplicațieș
interceptarea event-urilor care sunt generate de obiecte atunci când utilizatorul va interacționa cu acesteaș
2.1. MODELUL AWT ȘI SWING
Pachetul care oferă accesul la componentele AWT este java.awt.
Toate obiectele ce au legatură cu grafica derivă din Component. Fac excepție cele care derivă din clasa MenuComponent. Plecând de la acest aspect, putem spune ca toate obiectele ce pot fi reprezentate grafic (bare de defilare, liste, butoane, ferestre etc) constituie componente ce pot interacționa cu utilizatorul.
Componentele AWT au propriile clase, acestea regasindu-se în pachetul java.awt. Superclasa tuturor acestora este clasa Component.
Faptul ca am creat un obiect grafic nu însemnă automat afișarea acestora pe ecran.
Mai întâi ele trebuie așezate pe o suprafata de afișare (fereastră sau applet) ulterior putând fi vizibile după ce însăși suprafața de afișare devine vizibilă.
Aceasta suprafață unde pot fi adăugate componentele, poartă denumirea de container acesta fiind o instanță a clasei derivate Container. Această clasă este o subclasă a lui Component, ea fiind superclasa tuturor spațiilor de afișare a limbajului Java.
Așa cum am văzut, interfața grafică servește interacțiunii cu un utilizator.
De multe ori, este necesar ca aplicația să proceseze un set de instrucțiuni atunci când se face o cerere de la un utilizator. În acel moment, componentele vor genera evenimente în funcție de acțiunea suferită (acțiune transmisă de la tastatură, mouse, etc).
Evenimentele au devenit instanțe ale claselor ce derivă din AWTEvent, odată cu lansarea versiunii Java 1.1.
În concluzie, evenimentul este creat automat de acțiunea unui utilizator asupra obiectelor grafice, deci nu este necesară conceperea acestuia de către un programator. Programatorul trebuie în schimb să dezvolte codul ce urmează a se executa atunci când apare un eveniment.
Evenimentele se tratează cu ajutorul claselor de tip listener, aceastea fiind definite în java.awtEvent.
Voi considera un mic exemplu, în care vom crea o fereastră ce conține 2 butoane:
Exemplul 2.1 Definire fereastră cu 2 butoane ([4]).
import java.awt.*;
public class ExempluAWT1 {
public static void main(String args[]){
//crearea ferestrei – obiect de tip Frame
Frame f = new Frame(“Fereastra”);
//setarea modului de dispunere a componentelor
f.setLayout(new FlowLayout());
//crearea celor 2 butoane
Button b1 = new Button(“Ok”);
Button b2 = new Button(“Cancel”);
//adaugarea butoanelor
f.add(b1);
f.add(b2);
f.pack();
//afisarea ferestrei
f.show();
}
}
După cum veți observa la execuția acestui program, atât butoanele adăugate de noi cât și butonul de închidere a ferestrei sunt funcționale dar fără să realizeze nimic.
Acest lucru se întâmplă deoarece nu am specificat nicăieri codul care trebuie să se execute la apăsarea acestor butoane.
De asemenea, vor trebui definite dimensiunile butoanelor și ale ferestrei dar și pozitia de plasare ale acestora. Chiar și fără a le defini, ele apar apropiate, fără însă a se suprapune, cu toate că fereastra este suficient de mare pentru a le cuprinde.
Acest lucru are legătură cu obiectul FlowLayout, specificat în cod și care gestionează fereastra și plasează toate componentele în ordine pe suprafața acesteia.
Modul de aranjare a obiectelor nu este caracteristic suprafeței de afișare (ferestrei), toate containerele având asignate un obiect cu rol de setare a dimensiunii și a dispunerii componentelor. Acest obiect se numește layout manager.
Componentele AWT
Componenetele din biblioteca AWT se pot defini cu ajutorul claselor proprii, acestea regăsindu-se în java.awt. Acestea pot fi:
Button – butoane cu label text;
Canvas – suprafață pentru desenare;
Checkbox – este o componentă ce are 2 stări; în cazul în care avem mai multe obiecte similare, acestea se pot fi grupa utilizând clasa CheckBoxGroup;
Choice – sunt liste în care doar elementul ce este selectat este vizibil și care se deschid la apăsarea lor;
Container – superclasa tuturor suprafețelor de afișare;
Label – etichete cu un singur rând ;
List – acestea pot fi cu selecție simplă sau multiplă;
Scrollbar – utilizate în special în cazul defilării verticale sau orizontale;
TextComponent – componentă utilizată în editarea textului: TextField și TextArea pentru una sau mai multe linii;
Componentele AWT au metode comune, ce derivă din clasa Component și care sunt utilizate în special la setarea de atribute pentru obiecte (font, culoare, poziție, dimensiune).
Cele mai utilizate sunt următoarele:
Poziție
getLocation, getX, getY, getLocationOnScreen
setLocation, setX, setY
Dimensiuni
getSize, getHeight, getWidth
setSize, setHeight, setWidth
Dimensiuni și poziție
getBounds
setBounds
Culoare (text și fundal)
getForeground, getBackground
setForeground, setBackground
Font
getFont
setFont
Vizibilitate
setVisible
isVisible
Interactivitate
setEnabled
isEnabled
Suprafete de afișare (Clasa container)
La definirea obiectelor de tip grafic, vom ține cont de faptul că acestea nu se vor afișa direct pe ecran ele devenind vizibile numai odată afișarea suprafeței care poate fi fereastră sau applet.
Suprafața pe care se plasează componentele poartă denumirea de container, reprezentând de fapt o instanță a clasei ce derivă din Container. Clasele ce pot deriva din Container sunt:
• Window – aceasta este superclasa tututor ferestrelor. Din aceasta derivă:
– Frame – reprezintă ferestrele standard;
– Dialog – acestea pot fi nemodale sau modale;
• Panel – nu se reprezintă grafic și se folosește doar pentru a putea grupa alte componente. Tot din aceeași clasă derivă clasa cu ajutorul căreia se pot crea applet-uri ( clasa Applet);
• ScrollPane – este un tip de container utilizat în cazul derulării unei componente pe verticală sau orizontală.
Dacă nu se specifică niciun index atunci când se adaugă o componentă, atunci ea se va adăuga automat la sfârșitul listei.
Clasa Container conține metodele comune tututor suprafețelor de afișare. Cele mai uzuale sunt următoarele:
• add – va adăuga o componentă pe suprafața de afișare, într-un container. Dacă se dorește mutarea componentei către un alt container, atunci acesta va trebui mai întâi șters din primul container, urmând apoi să fie adăugat pe celălalt;
• remove – elimină o componentă de pe container;
• setLayout – stabilește gestionarul de poziționare al containerului;
• getInsets – determină distanța rezervată pentru marginile suprafeței de afișare;
• validate – forțează containerul să reașeze toate componentele sale. Această metodă trebuie apelată explicit atunci când adăugăm sau eliminăm componente pe suprafața de afișare după ce aceasta a devenit vizibilă.
Exemplul 2.2 Adaugare butoane în fereastră([4]).
Frame f = new Frame("O fereastra");
// Adaugam un buton direct pe fereastra
Button b = new Button("Hello");
f.add(b);
// Adaugam doua componente pe un panel
Label et = new Label("Nume:");
TextField text = new TextField();
Panel panel = new Panel();
panel.add(et);
panel.add(text);
// Adaugam panel-ul pe fereastra
// si, indirect, cele doua componente
f.add(panel);
Folosirea gestionărilor de poziționare
Așa cum am prezentat mai sus, containerul deține un gestionar de poziționare cu o valoare implicită (obiect ce implementează LayoutManager) și care este atașat odată cu crearea sa. Dacă dorim să modificăm valoarea implicită, acest lucru poate fi facut cu ușurință. Gestionarii din pachetul java.awt care sunt folosiți în mod uzual sunt:
• FlowLayout
• BorderLayout
• GridLayout
• CardLayout
• GridBagLayout
Setarea explicită a unuia dintre gestionarii de poziție în cazul unui container, se poate face cu o metodă (setLayout) din clasa Container. Această metodă primește ca parametru o instanță a unei clase care implementează interfața LayoutManager. Pentru a exemplifica modul de asignare particularizată a unui gestionar în cazul unui container pentru FlowLayout, putem folosi următoarea comandă:
FlowLayout gestionar = new FlowLayout();
container.setLayout(gestionar);
// sau, mai uzual:
container.setLayout(new FlowLayout());
De regulă, aplicațiile nu apelează metode ce țin de gestionarea poziției, dar în situația în care este nevoie de acesta, se poate obține cu ajutorul metodei getLayout aflat în cadrul clasei Container.
Dintre facilitățile utile ale gestionarilor de poziție, amintim rearanjarea automată a componentelor unui container în cazul redimensionării acestuia. De asemenea, pozițiile și dimensiunile componentelor se vor ajusta în mod automat la fiecare redimensionare, astfel încât să se pastreze cât mai estetic fereastra sau orice altă suprafață de afișare.
Orice clasă ce derivă din Component, poate să implementeze urmatoarele metode: getMinimumSize, getMaximumSize și getPrefferedSize. Acestea vor returna atât dimensiunea implicită a componentei cât și acele limite dincolo de care nu se mai poate desena acea componentă. Gestionarii de poziționare, vor calcula pe baza acestor metode, dimensiunea de afișare a componentei respective.
Dacă însă se dorește păstrarea componentelor la poziții fixe, indiferent de redimensionarea containerului, va trebui să se renunțe la gestionarea automată a acestuia urmând ca apoi să utilizăm un gestionar de poziționare absolută a componentelor. Pentru aceasta, va trebui să setam valoarea null la apelarea metodei setLayout.
// pozitionare absoluta a componentelor in container
container.setLayout(null);
În situația în care dorim să folosim poziționarea absolută a obiectelor pe suprafața de afișare, va deveni insuficientă doar utilizarea metodei add. În acest caz, va fi nesară specificarea dimensiunii și poziției acestuia:
container.setLayout(null);
Button b = new Button("Buton");
b.setSize(10, 10);
b.setLocation (0, 0);
container.add(b);
De regulă, folosirea gestionarilor de poziție este recomandată în toate acele situații când este posibil, pentru a permite aplicației să arate asemănător, indiferent de rezoluția sau platforma pe care rulează aceasta.
Gestionarul FlowLayout
Gestionatul FlowLayout se ocupă de așezarea componentelor în fereastră în linie, mai exact una după alta, atât cât permite spațiul disponibil.
În situația în care, o componentă nu mai are loc pe linia curentă, atunci se va trece automat pe următoarea linie.
Procedeul de adăugare se face de la stânga spre dreapta în linie, se pot de asemenea alinia la stânga, pe centru respectiv la dreapta. După adaugare, componentelese vor centra pe fiecare linie, distanța standard între acestea fiind de 5 pixeli pe verticală și 5 pixeli pe orizontală.
Gestionarul FlowLayout este considerat gestionarul implicit pentru toate containerele ce derivă din clasa Panel și implicit al applet-urilor.
Exemplul 2.3 Gestionarul FlowLayout ([4]).
import java . awt .*;
public class TestFlowLayout {
public static void main ( String args []) {
Frame f = new Frame (" Flow Layout ");
f. setLayout (new FlowLayout ());
Button b1 = new Button (" Button 1");
Button b2 = new Button ("2");
Button b3 = new Button (" Button 3");
Button b4 = new Button ("Long – Named Button 4");
Button b5 = new Button (" Button 5");
f.add(b1); f.add (b2); f. add(b3); f.add(b4); f.add(b5);
f. pack ();
f. show ();
}
}
Componentele ferestrei vor fi afișate astfel:
Figura 2.1. Componentele ferestrei ([4]).
Redimensionând fereastra astfel încât cele cinci butoane să nu mai încapă pe o singură linie, atunci ultimele vor trece pe linia următoare:
Figura 2.2. Fereastră redimensionată ([4]).
Gestionarul BorderLayout
BorderLayout, este un gestionar ce împarte în 5 regiuni suprafața de afișare. Aceste regiuni corespund punctelor cardinale și centrului. Componentele pot fi plasate în oricare din cele 5 regiuni, iar dimensiunile acestora, se vor calcula în așa fel încât să ocupe toată suprafața regiunii respective.
Dacă însă dorim să adăugăm două sau mai multe componente într-una din cele 5 zone, va trebui să le grupăm mai întâi într-un Panel urmând ca ulterior să putem plasa panel-ul în regiunea respectivă.
În această situație, metoda add va trebui să primească în afară de referința unei componente, zona de amplasare ce poate fi NORTH, SOUTH, EAST, WEST sau CENTER.
Exemplul 2.4 Gestionarul BorderLayout ([4]).
import java . awt .*;
public class TestareBorderLayout {
public static void main ( String args []) {
Frame f = new Frame (" Border Layout ");
// Apelul de mai jos poate sa lipseasca
f. setLayout (new BorderLayout ());
f.add(new Button (" Nord "), BorderLayout . NORTH );
f.add(new Button (" Sud"), BorderLayout . SOUTH );
f.add(new Button (" Est"), BorderLayout . EAST );
f.add(new Button (" Vest "), BorderLayout . WEST );
f.add(new Button (" Centru "), BorderLayout . CENTER );
f. pack ();
f. show ();
}
}
La execuția script-ului, butoanele se vor afișa astfel:
Figura 2.3. Poziționare butoane în BorderLayout ([4]).
Dacă vom redimensiona fereastra, vom observa căestul și vestul se vor redimensiona numai pe verticală, nordul și sudul se vor redimensiona pe orizontală, iar centru se redimensioneaza atât pe verticală cât și pe orizontală.
Se observă că pentru fiecare din cele 5 zone, redimensionarea se va face ocupând întreaga zonă din containerul din care acestea fac parte.
Gestionarul GridLayout
GridLayout este un gestionar ce organizează un container asemănător unui tabel, adică pe rânduri și coloane. Celule acestui tabel sunt egale în dimensiune, o componentă putând ocupa doar o singură celulă.
Popularea celulelor se va face de la stânga spre drepta, pornind de la primul rând.
La definirea gestionarului, se vor seta numarul de linii și de coloane pe care acesta il va conține cu ajutorul metodelor setRows pentru linii respectiv setCols pentru coloane.
În situația în care avem valoarea zero fie la numărul de linii, fie la numărul de coloane atunci toate componentele se vor plasa pe o singură linie sau coloană.
Se va putea modifica inclusiv distanța dintre componentele aflate pe verticală sau orizontală.
Exemplul 2.5 Gestionarul GridLayout ([4]).
import java . awt .*;
public class TestGridLayout {
public static void main ( String args []) {
Frame f = new Frame (" Grid Layout ");
f. setLayout (new GridLayout (3, 2));
f.add(new Button ("1"));
f.add(new Button ("2"));
f.add(new Button ("3"));
f.add(new Button ("4"));
f.add(new Button ("5"));
f.add(new Button ("6"));
f. pack ();
f. show ();
}
}
Rezultatul afișat mai jos, prezintă butoanele ce sunt afișate pe 3 rânduri și 2 coloane:
Figura 2.4. Poziționare butoane în GridLayout ([4]).
Dacă redimensionăm fereastra, observăm că se vor redimensiona toate componentele din aceasta pe verticală și orizontală.
Gestionarul CardLayout
CardLayout este un gestionar ce așează componenetele pe suprafața ferestrei întocmai ca și dispunerea carților de joc dintr-un pachet. Ele se vor suprapune și întotdeauna va putea fi vizibilă doar cea care este deasupra.
Utilizarea CardLayout-ului are ca efect principal, o utilizare mai eficientă a ferestrei, astfel încât cel ce utilizează aplicația să poată interacționa cu anumite obiecte, celelalte nefiind vizibile.
Exemplul 2.6 Gestionarul CardLayout ([4]).
import java . awt .*;
import java . awt. event .*;
public class TestCardLayout extends Frame implements ActionListener {
Panel tab;
public TestCardLayout () {
super (" Test CardLayout ");
Button card1 = new Button (" Card 1");
Button card2 = new Button (" Card 2");
Panel butoane = new Panel ();
butoane . add( card1 );
butoane . add( card2 );
tab = new Panel ();
tab . setLayout ( new CardLayout ());
TextField tf = new TextField (" Text Field ");
Button btn = new Button (" Button ");
tab .add (" Card 1", tf);
tab .add (" Card 2", btn);
add ( butoane , BorderLayout . NORTH );
add (tab , BorderLayout . CENTER );
pack ();
show ();
card1 . addActionListener ( this );
card2 . addActionListener ( this );
}
public void actionPerformed ( ActionEvent e) {
CardLayout gestionar = ( CardLayout ) tab. getLayout ();
gestionar . show (tab , e. getActionCommand ());
}
public static void main ( String args []) {
TestCardLayout f = new TestCardLayout ();
f. show ();
}
}
Afișare Card1 Afișare Card2
Figura 2.5. Funcționalitate CardLayout ([4]).
Gruparea componentelor
Se recomandă să grupăm în panel-uri componentele pe care dorim să le adaugăm în fereastră și nu direct pe aria de afișare, pentru o gestionare cât mai buna a acestora.
Panel-ul este un model simplist de container, ce nu este vizibil la afișare, dar cu rol de afișare a componentelor grafice ce pot fi de asemenea alte panel-uri.
Se poate seta ce gestionar să fie utilizat in cadrul panel-ului cu ajutorul metodei setLayout.
La crearea panel-ului, FlowLayout este implicit gestionarul de container.
Putem afirma în acest sens, că o poziționare eficientă în ceea ce privește componenetele unei ferestre ar însemna urmatoarele:
gruparea tuturor componenetelor cu legătură între ele în panel-uri;
specificarea gestionarului de poziționare pentru poziționarea componentelor în panel;
utilizarea unui gestionar de poziționare a panel-ului în cadrul unei ferestre.
Exemplul 2.7 Gruparea componentelor ([4]).
import java . awt .*;
public class TestPanel {
public static void main ( String args []) {
Frame f = new Frame (" Test Panel ");
Panel intro = new Panel ();
intro . setLayout (new GridLayout (1, 3));
intro .add(new Label (" Text :"));
intro .add(new TextField ("", 20) );
intro .add(new Button (" Adaugare "));
Panel lista = new Panel ();
lista . setLayout (new FlowLayout ());
lista .add(new List (10) );
lista .add(new Button (" Stergere "));
Panel control = new Panel ();
control . add( new Button (" Salvare "));
control . add( new Button (" Iesire "));
f.add(intro , BorderLayout . NORTH );
f.add(lista , BorderLayout . CENTER );
f.add( control , BorderLayout . SOUTH );
f. pack ();
f. show ();
}
}
Tratarea evenimentelor
Evenimentele se produc în momentul când un utilizator acționează asupra uneia din componentele grafice poziționate pe suprafața de afișare, acesta comunicând în mod direct cu aplicația respectivă.
Acestea pot fi diverse: click pe un buton, redimensionarea ferestrei, introducerea sau modificarea unui text într-un câmp de editare, selectarea unei inregistrări din cadrul unui comboBox etc.
Cu ajutorul claselor listener, putem intercepta aceste evenimente, iar programatorul poate decide ce secțiune de cod să se execute la acționarea componentelor grafice.
Figura 2.6. “Consumarea” evenimentelor generate de o componentă grafică([4]).
Urmărind descrierea din Figura 2.6. putem spune că pentru a dezvolta sub formă de cod ce anume trebuie să facă un program la interacționarea cu componentele grafice, va trebui ca:
programatorul să insereze o clasă listener care să preia un eveniment ce se produce la nivelul componentei grafice;
să înregistrăm acea clasă ca și “consumator” al unui eveniment produs de acea componentă grafică;
Evenimentele sunt de asemenea obiecte, iar clasele care le descriu pot fi împărțite pe mai multe tipuri. La acționarea unui buton de exemplu, evenimentul care se generează va fi descris de ActionEvent, pentru modificare sau inserarea unui text, evenimentul se preia de către TextEvent.
Din EventListener, pot deriva mai multe interfețe in funcție de tipul de eveniment ce urmează a se produce. De exemplu în cazul TextEvent se va implementa o interfață TextListener, pentru ActionEvent se implementează ActionListener.
Exemplul 2.8 Definire metode evenimente ([4]).
class AscultaButoane implements ActionListener {
public void actionPerformed(ActionEvent e) {
// Metoda interfetei ActionListener
…
}
}
class AscultaTexte implements TextListener {
public void textValueChanged(TextEvent e) {
// Metoda interfetei TextListener
…
}
}
Datorită faptului că mai multe interfețe pot fi implementate de o anumită clasă, aceasta din urmă va putea la randul ei să preia mai multe tipuri de evenimente:
Exemplul 2.9 Tipuri de evenimente ([4]).
class Ascultator implements ActionListener, TextListener {
public void actionPerformed(ActionEvent e) { … }
public void textValueChanged(TextEvent e) { … }
}
Tipuri de evenimente
Voi descrie în continuare tipurile de evenimentele ce pot avea loc în funcție de ce anume le generează:
O singură acțiune a unui utilizator, poate să genereze mai mult de un eveniment. Putem lua exemplul tastării unei litere, vom avea așadar de tratat mai multe evenimente: apasarea tastei, eliberarea acesteia și evenimentul de tastare. Avantajul acestui lucru este că programatorul va putea dezvolta cod pentru fiecare din cele 3 evenimente.
Celălalt tip de evenimente, este cel semantic, și presupune interacțiunea cu una dintre componentele grafice: click pe buton, selecții din liste, derularea unui scrollPanel și altele.
Am descris mai jos, clasele în funcție de tipurile de evenimente:
Am descris în cele ce urmează, tipurile de evenimente ce pot fi generate de componente din clasa AWT:
Dacă un obiect de tip listener va trata același tip de evenimente ce vin de la mai multe componenete, va trebui săa aflăm care este sursa evenimentului tratat.
Tipurile evenimentelor moștenesc metoda getSource, aceasta returnează în schimb obiectul ce este responsabil cu generarea acelui eveniment.
CAPITOLUL 3. APLICAȚIA “GESTIUNEA RESURSELOR UNUI PARC AUTO”
DESCRIEREA MODELULUI
Grupul de firme X Construct, este constituit din 3 companii, fiecare din cele 3, deținând un parc auto propriu.
Companiile au ales sa țină evidența vehiculelor, împărțindu-le pe mai multe flote: Management, Vânzări, Operațiuni etc.
Pentru fiecare vehicul, este obligatoriu sa se țină evidența la nivel de număr de inmatriculare, marca, model, an de fabricație, capacitate cilindrică etc.
Șeful de parc auto trebuie sa fie informat asupra schimbărilor care au loc in cadrul vehiculelor, a șoferilor precum și asupra asigurărilor de tip RCA, facturi de revizii, accidente și alimentări cu carburant. Ulterior, acesta va introduce sau modifica informațiile în aplicația Gestiune Parc Auto.
3.2. DESCRIEREA ENTITĂȚILOR ȘI RELAȚIILOR
COMPANIE(#cod_companie, nume_companie, cod_fiscal, regiune)
FLOTA(#cod_flota, nume_flota, fk-cod_companie)
VEHICUL(#cod_vehicul,fk-cod_flota,nr_inmatriculare,marca_vehicul, model_vehicul,an_fabricatie, capac_cilindrica, vin, localitate_vehicul, judet_vehicul, tip_vehicul, fk-cod_sofer)
REVIZIE(#cod_revizie,fk-cod_vehicul,data_efect_revizie, data_urm_revizie)
SOFER(#cod_sofer, fk-cod_companie, nume_sofer)
FACTURA(#cod_factura,fk-cod_revizie,fk-cod_vehicul,data_factura, valoare_factura)
ACCIDENT(#cod_accident, fk-id_vehicul, fk-id_sofer, data_accident)
ALIMENTARI(#cod_alimentare,fk-cod_vehicul,data_alimentare, volum_alimentat)
ASIGURARE(#cod_asigurare, fk-cod_vehicul, serie_polita, valoare_polita, data_expirare_polita, data_incheiere_polita)
3.3 . DIAGRAMA ENTITATE – RELAȚIE
Figura 3.3.1. Diagrama Entitate – Relație
3.4. DIAGRAMA CONCEPTUALĂ
Figura 3.4.1. Diagrama conceptuală
3.5. PREZENTAREA APLICAȚIEI
Baza de date a fost creată cu ajutorul Oracle 11g, iar pentru interfața grafică am folosit Java prin intermediul Eclipse Luna.
Tabelele au fost create utilizând comanda CREATE:
CREATE TABLE COMPANIE (
ID_COMPANIE NUMBER(10),
NUME_COMPANIE VARCHAR(20) NOT NULL,
COD_FISCAL NUMBER(20) UNIQUE,
REGIUNE VARCHAR(20));
Pentru fiecare tabelă, au fost setate constrângeri de cheie primară și cheie externă:
ALTER TABLE VEHICUL ADD CONSTRAINT PK_VEHICUL PRIMARY KEY(ID_VEHICUL);
ALTER TABLE VEHICUL ADD CONSTRAINT FK_VEHICUL_FLOTA FOREIGN KEY(ID_FLOTA) REFERENCES FLOTA(ID_FLOTA);
Ulterior, am populat tabelele cu ajutorul instrucțiunii INSERT:
INSERT INTO FLOTA VALUES(1,1,’DISTRIBUTIE’);
Accesarea aplicației
Accesarea se face prin intermediul ecranului de login și numai după ce au fost introduse corect datele de autentificare:
Figura 3.5.1. Ecran de login
După autentificare, utilizatorul are posibilitatea de selectare a companiei cu care dorește să lucreze, prin intermediul ecranului de selectie a companiei:
Figura 3.5.2. Ecran de selectare companie
După selectarea companiei, se lansează automat interfața principala de lucru:
Figura 3.5.3. Ecran interfață de lucru
Interfața principală a aplicației este compusă din 2 paneluri, unul pentru butoane în partea stângă a ecranului și altul pentru afișarea informațiilor, în partea centrală a ecranului.
Vizualizarea flotele disponibile pe compania selectată in ecranul anterior, se face prin click pe butonul Flote. În panel-ul central vor aparea rezultatele returnate din vizualizarea stocată in baza de date vizualizare_flote:
CREATE OR REPLACE VIZUALIZARE_FLOTE AS
SELECT NUME_COMPANIE, NUME_FLOTA FROM FLOTA F, COMPANIE C
WHERE F.ID_COMPANIE = C.ID_COMPANIE;
Figura 3.5.4. Ecran flote
Utilizatorul va putea edita informațiile legate de nume flota, dând click pe una dintre ele. Acestea vor putea fi editate numai dupa apăsarea butonului Edit.
Figura 3.5.5. Ecran editare flote
Tot din acest ecran, utilizatorul va putea șterge flota selectata, dar aceasta se va face doar daca pe flota respectivă, nu există vehicule alocate. În caz contrar, va apărea următorul mesaj:
Figura 3.5.6. Ecran mesaj stergere flotă
Adăugarea unei noi flote, se poate face prin intermediul butonului Adauga flota, situat în partea de jos a ecranului. Se va deschide o fereastra în care putem introduce numele flotei pe care dorim să o adăugam:
Figura 3.5.7. Ecran adăugare flotă
Accesul la lista de vehicule se poate face accesând butonul Vehicule. În panel-ul central vor fi afișate rezultatele view-ului vizualizare_vehicule:
CREATE OR REPLACE VIEW VIZUALIZARE_VEHICULE AS
SELECT V.ID_VEHICUL, S.ID_SOFER, F.ID_FLOTA, NR_INMATRICULARE, MARCA_VEHICUL, MODEL_VEHICUL, LOCALITATE_VEHICUL, NUME_SOFER, NUME_FLOTA FROM VEHICUL V, SOFER S, FLOTA F
WHERE S.ID_COMPANIE = 1 AND V.ID_SOFER=S.ID_SOFER AND V.ID_FLOTA=F.ID_FLOTA;
Rezultatul se prezintă astfel:
Figura 3.5.8. Ecran Vizualizare vehicule
Informațiile legate id_vehicul, id_sofer și id_flota au fost ascunse, afișarea acestora fiind irelevantă pentru utilizatorul aplicației.
Editarea datelor referitoare la vehicule se poate face prin click pe una din liniile din tabel.
Rezultatul va fi apariția unei ferestre de dialog cu opțiuni de editare sau ștergere a vehiculului selectat:
Figura 3.5.9. Ecran editare informații vehicule
La apăsarea butonului Edit, câmpurile devin edit-abile, astfel incât utilizatorul va putea introduce manual alte valori.
În cazul valorilor pentru Flota si Șofer, am folosit un ComboBox ce permite afișarea tuturor opțiunilor disponibile pentru a ușura procesul de selecție și pentru a evita eventualele erori cauzate de introducerea greșită a datelor.
Figura 3.5.10. Ecran editare Vehicule
Această funționalitate este utilă șefului de parc auto, el putând afla cu ușurință în orice moment, pe ce flotă este alocat un vehicul și care este conducătorul auto asignat vehiculului respectiv.
Vehiculele pot fi șterse din același ecran prin apăsarea butonului Sterge acest lucru fiind posibil numai dacă nu există alte înregistrări în bază care au cheie externă către vehiculul selectat.
Prin apăsarea butonului Adauga, se va deschide fereastra ce permite introducerea unui nou vehicul în aplicație.
Figura 3.5.11. Ecran adăugare vehicule
La fel ca și in cazul editării vehiculului, am folosit ComboBox-uri pentru selectarea flotelor și a șoferilor definiți în aplicație.
Pentru generarea cheii primare a noului vehicul, am utilizat secvențe definite în baza de date:
CREATE SEQUENCE pk_vehicul
START WITH 100
INCREMENT BY 1 CACHE 2;
Lista șoferilor introduși la nivel de companie, poate fi accesată cu ajutorul butonului Soferi.
Aplicația va returna informațiile prin apelarea view-ului vizualizare_soferi:
CREATE OR REPLACE VIEW VIZUALIZARE_SOFERI AS
SELECT NUME_SOFER, NUME_COMPANIE FROM SOFER S, COMPANIE C WHERE S.ID_COMPANIE=C.ID_SOFER;
Rezultatul afișat va fi:
Figura 3.5.12. Ecran vizualizare șoferi
Un rol deosebit de important în administrarea parcului auto îl reprezintă cheltuielile cu acesta. Am introdus în aplicație cheltuielile cu reviziile, asigurările și cele privind alimentările cu carburant.
Introducerea cheltuielilor la nivel de vehicul și implicit la nivel de flotă, va permite o evidențiere clară a acestora și va fi utilă în analiza privind reducerea cheltuielilor cu întreg parcul auto.
Facturile de revizii pot fi vizualizate prin click pe butonul Facturi revizii.
Rezultatul va fi afisat sub formă tabelară prin apelarea vizualizarii definite in baza de date:
SELECT F.ID_VEHICUL, V.NR_INMATRICULARE, F.ID_FACTURA, F.NR_FACTURA, TO_CHAR(DATA_FACTURA,’MM/DD/YYYY’) AS DATA, F.VALOARE_FACTURA
FROM VEHICUL V, FACTURA F
WHERE F.ID_VEHICUL=V.ID_VEHICUL;
Figura 3.5.13. Ecran vizualizare facturi
La fel ca și în celelalte ecrane, a fost ascunsă informația referitoare la cheile primare, acestea fiind irelevante pentru utilizator.
După selectarea uneia dintre facturi, vor putea fi editate informațiile despre factură și eventual aceasta poate fi ștearsă.
Figura 3.5.14. Ecran editare facturi
Odată efectuate reviziile în cadrul service-urilor specializate, șeful de parc auto va putea introduce în aplicație, date despre facturi la nivel devehicul, prin accesarea butonului Adauga factura:
Figura 3.5.15. Ecran adăugare factură
ANEXĂ
Creare tabele în Oracle 11g
–login
create table login (
id_login number(10),
username varchar(20) not null,
pass varchar(20) not null);
alter table login add constraint pk_login primary key(id_login);
insert into login values (1,'admin','pass');
–companie
create table companie (
id_companie number(10),
nume_companie varchar(20) not null,
cod_fiscal number(20) unique,
regiune varchar(20));
alter table companie add constraint pk_companie primary key(id_companie);
alter table companie add constraint nume_companie unique (nume_companie);
–flota
create table flota (
id_flota number(10),
id_companie number(10),
nume_flota varchar(20));
alter table flota add constraint pk_flota primary key(id_flota);
alter table flota add constraint fk_flota_companie foreign key (id_companie) references companie(id_companie);
alter table flota modify (id_companie not null);
alter table flota modify (nume_flota not null);
–vehicul
create table vehicul (
id_vehicul number(10),
id_flota number(10) not null,
nr_inmatriculare varchar(20) not null,
vin varchar(17) not null,
marca_vehicul varchar(30) not null,
model_vehicul varchar(30) not null,
tip_vehicul varchar(30),
combustibil varchar(20) not null,
capac_cilindrica number(6) not null,
an_fabricatie number(4) not null,
localitate_vehicul varchar(30),
judet_vehicul varchar(30),
id_sofer number(10));
alter table vehicul add constraint pk_vehicul primary key(id_vehicul);
alter table vehicul add constraint fk_vehicul_flota foreign key (id_flota) references flota(id_flota);
–sofer
create table sofer (
id_sofer number(10),
id_vehicul number(10),
id_companie number(10),
nume_sofer varchar(50));
alter table sofer add constraint pk_sofer primary key (id_sofer);
alter table sofer add constraint fk_sofer_vehicul foreign key (id_vehicul) references vehicul(id_vehicul);
alter table sofer add constraint fk_sofer_companie foreign key (id_companie) references companie(id_companie);
alter table sofer modify(id_companie not null);
alter table sofer modify(nume_sofer not null);
–accident
create table accident(
id_accident number(10),
data_accident date not null,
id_vehicul number(10) not null,
id_sofer number(10));
alter table accident add constraint pk_accident primary key (id_accident);
alter table accident add constraint fk_accident_vehicul foreign key (id_vehicul) references vehicul(id_vehicul);
alter table accident add constraint fk_accident_sofer foreign key (id_sofer) references sofer(id_sofer);
–alimentari
create table alimentari (
id_alimentare number(10),
data_alimentare date not null,
volum_alimentat number(5) not null,
pret_litru decimal(4,2) not null,
km_alimentare number(10) not null,
alimentare_plin varchar(2) not null,
id_vehicul number(10) not null);
alter table alimentari add constraint pk_alimentari primary key(id_alimentare);
alter table alimentari add constraint fk_alimentari_vehicul foreign key (id_vehicul) references vehicul(id_vehicul);
alter table alimentari add valoare_alimentare number(10,2) not null;
–conduce
create table conduce (
id_sofer number(10),
id_vehicul number(10),
id_conduce number(10));
alter table conduce add constraint pk_conduce primary key (id_conduce);
–factura
create table factura (
id_factura number(10),
nr_factura varchar(20) not null,
data_factura date not null,
valoare_factura number(10) not null,
id_vehicul number(10) not null);
alter table factura add constraint pk_factura primary key (id_factura);
alter table factura add constraint fk_factura_vehicul foreign key (id_vehicul) references vehicul(id_vehicul);
–alter table factura add constraint fk_factura_revizie foreign key (id_revizie) references revizie(id_revizie);
–revizie
create table revizie (
id_revizie number(10),
data_urm_revizie date,
id_vehicul number(10) not null);
alter table revizie add constraint pk_revizie primary key (id_revizie);
alter table revizie add constraint fk_revizie_vehicul foreign key (id_vehicul) references vehicul(id_vehicul);
–leasing
–rca
create table asigurari (
id_asigurare number(10) primary key,
serie_polita varchar(20) not null,
valoare_polita number(10,2) not null,
data_incheiere_polita date not null,
data_expirare_polita date not null,
id_vehicul number(10) not null);
alter table asigurari add constraint fk_asigurari_vehicul foreign key (id_vehicul) references vehicul(id_vehicul);
Creare vizualizări
–vizualizari
create or replace view vizualizare_flote as
select nume_companie, nume_flota from flota f, companie c
where f.ID_COMPANIE = c.ID_COMPANIE;
select * from vizualizare_flote;
create or replace view vizualizare_soferi as
select nume_sofer, nume_companie from sofer s, companie c
where s.id_companie = c.id_companie;
select * from vizualizare_soferi;
create or replace view vizualizare_tot as
select nume_companie as Companie, nume_flota as Flota, nr_inmatriculare as Vehicul, nume_sofer as Sofer
from companie c, flota f, vehicul v, sofer s
where v.ID_FLOTA=f.ID_FLOTA and f.ID_COMPANIE = c.ID_COMPANIE and v.id_sofer = s.id_sofer;
select * from vizualizare_tot;
create or replace view vizualizare_vehicule as
select nr_inmatriculare, marca_vehicul, model_vehicul, localitate_vehicul, nume_sofer, nume_flota from vehicul v, sofer s, flota f
where s.id_companie = 1 and v.id_sofer = s.id_sofer and v.ID_FLOTA = f.ID_FLOTA;
select * from vizualizare_vehicule;
create or replace view vizualizare_companii as
select id_companie, nume_companie, cod_fiscal, regiune from companie;
create or replace view vizualizare_alimentari as
select nr_inmatriculare, data_alimentare, volum_alimentat, pret_litru, km_alimentare, valoare_alimentare, alimentare_plin
from vehicul v, alimentari a
where v.id_vehicul = a.id_vehicul;
create or replace view vizualizare_asigurari as
select nr_inmatriculare, serie_polita, valoare_polita, data_incheiere_polita, data_expirare_polita from
vehicul v, asigurari a
where v.id_vehicul = a.id_vehicul;
create or replace view vizualizare_accidente as
select nr_inmatriculare, nume_sofer, data_accident from
vehicul v, sofer s, accident a
where a.id_sofer = s.id_sofer and a.id_vehicul = v.id_vehicul;
create or replace view vizualizare_facturi as
select f.ID_VEHICUL, v.NR_INMATRICULARE, f.ID_FACTURA, f.NR_FACTURA, TO_CHAR(DATA_FACTURA,'mm/dd/YYYY') AS DATA, f.VALOARE_FACTURA from
vehicul v, factura f
where f.id_vehicul = v.id_vehicul;
Creare secvențe
–creare secvente generare chei primare
–flota
CREATE SEQUENCE pk_flota
START WITH 100
INCREMENT BY 1
CACHE 2;
–vehicul
CREATE SEQUENCE pk_vehicul
START WITH 100
INCREMENT BY 1
CACHE 2;
–sofer
CREATE SEQUENCE pk_sofer
START WITH 100
INCREMENT BY 1
CACHE 2;
–factura
CREATE SEQUENCE pk_factura
START WITH 100
INCREMENT BY 1
CACHE 2;
BIBLIOGRAFIE
Athanasiu I. , Constantinescu B., Drăgoi O. A. , Popovici F. I. , Limbajul Java din perspectivă pragmatică, Ediția a 2-a
Cole B, Eckstein R., Elliott J, Loy M., Wood D. , Java™ Swing, 2nd Edition, 2002
Connolly, T., Begg, C., Strachan, A. – Baze de date, Ed. Teora, 2000.
Frasineanu, Cristian “ Curs practic de Java”
Lupu V. – Curs practic de baze de date, 2010
Popescu I. , Velcescu L. – Proiectarea bazelor de date, 2007
Velicanu, M., Lungu, I., Bodea C., Ioniță, C., Bădescu G. – Database Management Systems, Editura Petrion, 2000
BIBLIOGRAFIE
Athanasiu I. , Constantinescu B., Drăgoi O. A. , Popovici F. I. , Limbajul Java din perspectivă pragmatică, Ediția a 2-a
Cole B, Eckstein R., Elliott J, Loy M., Wood D. , Java™ Swing, 2nd Edition, 2002
Connolly, T., Begg, C., Strachan, A. – Baze de date, Ed. Teora, 2000.
Frasineanu, Cristian “ Curs practic de Java”
Lupu V. – Curs practic de baze de date, 2010
Popescu I. , Velcescu L. – Proiectarea bazelor de date, 2007
Velicanu, M., Lungu, I., Bodea C., Ioniță, C., Bădescu G. – Database Management Systems, Editura Petrion, 2000
ANEXĂ
Creare tabele în Oracle 11g
–login
create table login (
id_login number(10),
username varchar(20) not null,
pass varchar(20) not null);
alter table login add constraint pk_login primary key(id_login);
insert into login values (1,'admin','pass');
–companie
create table companie (
id_companie number(10),
nume_companie varchar(20) not null,
cod_fiscal number(20) unique,
regiune varchar(20));
alter table companie add constraint pk_companie primary key(id_companie);
alter table companie add constraint nume_companie unique (nume_companie);
–flota
create table flota (
id_flota number(10),
id_companie number(10),
nume_flota varchar(20));
alter table flota add constraint pk_flota primary key(id_flota);
alter table flota add constraint fk_flota_companie foreign key (id_companie) references companie(id_companie);
alter table flota modify (id_companie not null);
alter table flota modify (nume_flota not null);
–vehicul
create table vehicul (
id_vehicul number(10),
id_flota number(10) not null,
nr_inmatriculare varchar(20) not null,
vin varchar(17) not null,
marca_vehicul varchar(30) not null,
model_vehicul varchar(30) not null,
tip_vehicul varchar(30),
combustibil varchar(20) not null,
capac_cilindrica number(6) not null,
an_fabricatie number(4) not null,
localitate_vehicul varchar(30),
judet_vehicul varchar(30),
id_sofer number(10));
alter table vehicul add constraint pk_vehicul primary key(id_vehicul);
alter table vehicul add constraint fk_vehicul_flota foreign key (id_flota) references flota(id_flota);
–sofer
create table sofer (
id_sofer number(10),
id_vehicul number(10),
id_companie number(10),
nume_sofer varchar(50));
alter table sofer add constraint pk_sofer primary key (id_sofer);
alter table sofer add constraint fk_sofer_vehicul foreign key (id_vehicul) references vehicul(id_vehicul);
alter table sofer add constraint fk_sofer_companie foreign key (id_companie) references companie(id_companie);
alter table sofer modify(id_companie not null);
alter table sofer modify(nume_sofer not null);
–accident
create table accident(
id_accident number(10),
data_accident date not null,
id_vehicul number(10) not null,
id_sofer number(10));
alter table accident add constraint pk_accident primary key (id_accident);
alter table accident add constraint fk_accident_vehicul foreign key (id_vehicul) references vehicul(id_vehicul);
alter table accident add constraint fk_accident_sofer foreign key (id_sofer) references sofer(id_sofer);
–alimentari
create table alimentari (
id_alimentare number(10),
data_alimentare date not null,
volum_alimentat number(5) not null,
pret_litru decimal(4,2) not null,
km_alimentare number(10) not null,
alimentare_plin varchar(2) not null,
id_vehicul number(10) not null);
alter table alimentari add constraint pk_alimentari primary key(id_alimentare);
alter table alimentari add constraint fk_alimentari_vehicul foreign key (id_vehicul) references vehicul(id_vehicul);
alter table alimentari add valoare_alimentare number(10,2) not null;
–conduce
create table conduce (
id_sofer number(10),
id_vehicul number(10),
id_conduce number(10));
alter table conduce add constraint pk_conduce primary key (id_conduce);
–factura
create table factura (
id_factura number(10),
nr_factura varchar(20) not null,
data_factura date not null,
valoare_factura number(10) not null,
id_vehicul number(10) not null);
alter table factura add constraint pk_factura primary key (id_factura);
alter table factura add constraint fk_factura_vehicul foreign key (id_vehicul) references vehicul(id_vehicul);
–alter table factura add constraint fk_factura_revizie foreign key (id_revizie) references revizie(id_revizie);
–revizie
create table revizie (
id_revizie number(10),
data_urm_revizie date,
id_vehicul number(10) not null);
alter table revizie add constraint pk_revizie primary key (id_revizie);
alter table revizie add constraint fk_revizie_vehicul foreign key (id_vehicul) references vehicul(id_vehicul);
–leasing
–rca
create table asigurari (
id_asigurare number(10) primary key,
serie_polita varchar(20) not null,
valoare_polita number(10,2) not null,
data_incheiere_polita date not null,
data_expirare_polita date not null,
id_vehicul number(10) not null);
alter table asigurari add constraint fk_asigurari_vehicul foreign key (id_vehicul) references vehicul(id_vehicul);
Creare vizualizări
–vizualizari
create or replace view vizualizare_flote as
select nume_companie, nume_flota from flota f, companie c
where f.ID_COMPANIE = c.ID_COMPANIE;
select * from vizualizare_flote;
create or replace view vizualizare_soferi as
select nume_sofer, nume_companie from sofer s, companie c
where s.id_companie = c.id_companie;
select * from vizualizare_soferi;
create or replace view vizualizare_tot as
select nume_companie as Companie, nume_flota as Flota, nr_inmatriculare as Vehicul, nume_sofer as Sofer
from companie c, flota f, vehicul v, sofer s
where v.ID_FLOTA=f.ID_FLOTA and f.ID_COMPANIE = c.ID_COMPANIE and v.id_sofer = s.id_sofer;
select * from vizualizare_tot;
create or replace view vizualizare_vehicule as
select nr_inmatriculare, marca_vehicul, model_vehicul, localitate_vehicul, nume_sofer, nume_flota from vehicul v, sofer s, flota f
where s.id_companie = 1 and v.id_sofer = s.id_sofer and v.ID_FLOTA = f.ID_FLOTA;
select * from vizualizare_vehicule;
create or replace view vizualizare_companii as
select id_companie, nume_companie, cod_fiscal, regiune from companie;
create or replace view vizualizare_alimentari as
select nr_inmatriculare, data_alimentare, volum_alimentat, pret_litru, km_alimentare, valoare_alimentare, alimentare_plin
from vehicul v, alimentari a
where v.id_vehicul = a.id_vehicul;
create or replace view vizualizare_asigurari as
select nr_inmatriculare, serie_polita, valoare_polita, data_incheiere_polita, data_expirare_polita from
vehicul v, asigurari a
where v.id_vehicul = a.id_vehicul;
create or replace view vizualizare_accidente as
select nr_inmatriculare, nume_sofer, data_accident from
vehicul v, sofer s, accident a
where a.id_sofer = s.id_sofer and a.id_vehicul = v.id_vehicul;
create or replace view vizualizare_facturi as
select f.ID_VEHICUL, v.NR_INMATRICULARE, f.ID_FACTURA, f.NR_FACTURA, TO_CHAR(DATA_FACTURA,'mm/dd/YYYY') AS DATA, f.VALOARE_FACTURA from
vehicul v, factura f
where f.id_vehicul = v.id_vehicul;
Creare secvențe
–creare secvente generare chei primare
–flota
CREATE SEQUENCE pk_flota
START WITH 100
INCREMENT BY 1
CACHE 2;
–vehicul
CREATE SEQUENCE pk_vehicul
START WITH 100
INCREMENT BY 1
CACHE 2;
–sofer
CREATE SEQUENCE pk_sofer
START WITH 100
INCREMENT BY 1
CACHE 2;
–factura
CREATE SEQUENCE pk_factura
START WITH 100
INCREMENT BY 1
CACHE 2;
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Gestiunea Resurselor Unui Parc Auto (ID: 121379)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
