You are on page 1of 114

Baze podataka

Tema: Modelom upravljani razvoj PIS


Predmetni nastavnik:
Prof. dr Branko Perišić
Aplikativni aspekti

Implementacija klijentske strane uz


oslonac na odabranu programsku
paradigmu (Python).
Implementaciju serverske strane uz
oslonac na odabrani SUBP (MySQL)
◦ Poslovna logika (Uskladištene procedure i
trigeri u MySQL)
Povezivanje klijentske strane sa
serverom (Python-MySQL – connector)
1
MDBISD – Aplikativni aspekti

Implementacija Povezivanje klijenta Implementacija


klijentske strane sa serverom serverske strane

06.03.2023 Prof. dr Branko Perišić 3


MDBISD – Aplikativni aspekti

Implementacija Povezivanje klijenta Implementacija


klijentske strane sa serverom serverske strane

Prof. dr Branko Perišić 4


Standard korisničkog interfejsa
poslovnih aplikacija
Standard korisničkog interfejsa 1/2
Sa stanovišta korisnika, postojanje standarda je bitno
radi postizanja konsistentnog ponašanja aplikacije, što:
◦ skraćuje vreme učenja
◦ povećava efikasnost rada
◦ smanjuje broj grešaka u toku korišćenja
Sa stanovišta projeknog tima, standard:
◦ sprečava improvizaciju
◦ pospešuje timski rad i upravljanje projektom
◦ obezbeđuje jednostavnije održavanje složenih softverskih
sistema u periodu eksploatacije
◦ olakšava ponovno korišćenje koda

6
Standard korisničkog interfejsa 2/2
Radi definisanja standarda potrebno je:
◦ upoznati korisničku populaciju radi
izolovanja korisničkih profila
◦ formirati listu prioriteta vezanih za kvalitet
aplikacije
◦ definisati izgled i funkcionalnost pojedinačnih
entiteta na svim nivoima za potrebe svih
izolovanih profila korisnika

7
Korisnički profili
Pravilna procena osobina i potreba korisnika i izrada
korisničkog interfejsa u skladu sa tom procenom je jedan
od faktora koji odlučuje o uspehu ili neuspehu projekta
Korisnici se mogu posmatrati sa stanovišta:
◦ pola
◦ godišta
◦ iskustva u radu sa računarima
◦ poslova koje obavljaju
◦ obrazovanja
◦ motivacije
◦ radne sposobnosti
◦ ....

8
Korisnički interfejs u opštem slučaju
Za svaku vrstu posla koju će korisnici obavljati
u okviru aplikacije i svaku grupu korisnika,
potrebno je da korisnički interfejs obezbedi:
◦ minimalno vreme učenja
◦ maksimalnu brzina rada (u broju obavljenih
transakcija od strane korisnika u jedinici vremena)
◦ uslove za minimiziranje broja grešaka
prouzrokovanih od strane korisnika
◦ maksimalnu dužinu pamćenja naučenih funkcija,
tokom vremena
◦ maksimalni subjektivni osećaj zadovoljstva.

9
Korisnički interfejs poslovne aplikacije
 Osnovni zahtev jeste minimiziranje cene koštanja (u
fazi razvoja, održavanja i eksploatacije), i kao
posledica toga se primarno zahteva:
◦ maksimalna brzina rada operative (jer je tako potrebno
manje operatera i radnih stanica)
◦ minimalno vreme učenja (jer se uobičajeni poslovi potrebni
za opstanak firme moraju raditi i u toku uvođenja novog
informacionog sistema)
◦ otpornost na greške (jer njihovo otklanjanje zahteva vreme).
 Lično zadovoljstvo korisnika se smatra najmanje
bitnim faktorom, jer se pretpostavlja da dati korisnik
mora da koristi aplikaciju u okviru svog radnog mesta.

10
Predlog standarda
Elementi standarda
◦ osnovni prozor aplikacije
◦ referat
◦ poslovni podsistem
◦ ekranske forme (maske) za manipulaciju
podacima
 standardna forma
 parent-child forma
 many-to-many forma
 forma za preuzimanje parametara
◦ izveštaji
11
Osnovni prozor aplikacije1/2
Glavni meni sadrži uniju razvijenih opcija, raspoređenih po
poslovnim podsistemima (jedan vertikalni podmeni – jedan
podsistem)
Iza poslednjeg podmenija pridruženog poslovnom podsistemu
staviti podmeni za podešavanje opcija i pomoć
Umesto glavnog menija (ili uz njega), može se koristiti i tree-
view koji prikazuje opcije hijerarhijski organizovane po
podsistemima
U naslov staviti bitne statusne informacije (npr. naziv firme,
ime prijavljenog korisnika, izabranu poslovnu godinu)
Osnovni prozor treba da zaklanja celu radnu površinu, čime se
postiže skrivanje potencijalno pretrpanog ekrana i smanjuje
"vizuelni šum"
Logo firme u sredini

12
Osnovni prozor aplikacije - primer
2/2

13
Izbor preduzeća i poslovne godine
◦ Poslovna aplikacija u opštem slučaju treba da obezbedi
mogućnost registrovanja više firmi i praćenje njihovog
poslovanja kroz više poslovnih godina.
◦ Korisniku treba dozvoliti da prilikom prijavljivanja izabere,
a zatim u toku rada promeni preduzeće i poslovnu godinu sa
kojom želi da radi
◦ Podaci u okviru aplikacije se automatski filtriraju u skladu
sa ovim izborom
◦ Pošto je priroda poslovanja takva da su izmene dozvoljene
samo u aktivnoj poslovnoj godini, potrebno je da aplikacija
obezbedi mogućnost razlikovanja aktivnih od zaključenih
poslovnih godina i spreči mogućnost izmene u zaključenim

14
Dijalog za prijavljivanje korisnika -
primer

15
Dijalog za izbor preduzeća i poslovne
godine - primer

16
Referat
Zaokružena programska celina koja
modeluje grupu poslova pridruženu
određenom radnom mestu ili radniku.
Referati se obično formiraju
administrativnim putem, izborom iz skupa
raspoloživih podsistema

17
Poslovni podsistem 1/2
Svakiposlovni podsistem treba da ima
odgovarajući vertikalni (padajući)
podmeni u okviru glavnog menija
Podmeni tako organizovati da ako je
moguće:
◦ nijedan podmeni nema više od deset stavki na
istom nivou
◦ stablo podmenija ima maksimalno dva nivoa

18
Poslovni podsistem2/2
Organizacija stavki podmenija
◦ formirati natpise u skladu sa terminologijom korisnika
(ne više od tri reči)
◦ stavke podmenija grupisati tako da odgovaraju
pojedinačnim zadacima u okviru posla
◦ grupe razdvojiti separatorima, radi lakšeg razlikovanja,
i slagati ih po redosledu zadataka koji se obavljaju
(ako je bitan redosled), ili po učestalosti pristupa
◦ u okviru grupa, ako to priroda posla dozvoljava,
obezbediti različit tretman dokumenata u zavisnosti od
njihovog statusa (u fazi formiranja i formirani, na
primer).

19
Organizacija formi
Poslove tako organizovati da se minimizira potreba
za čestim korišćenjem menija.
Kada korisnik uđe u kontekst nekog posla obezbediti
mu:
◦ da ostane u njemu proizvoljno dugo
◦ ako ima potrebu za dodatnim informacijama ili
operacijama u skladu sa tim kontekstom, da može da im
pristupi direktno sa mesta gde se nalazi, bez potrebe
povratka na meni. Sve operacije vezane za kontekst bilo
kog posla treba da su raspoložive kada dođe do njegovog
aktiviranja, nezavisno od načina kako je do toga došlo.
Koncept funkcionalno zaokruženih formi
20
Standardna forma za manipulaciju
podacima
Softverski tasteri sa ikonama za
standardne operacije (toolbar)
Softverski tasteri sa
 natpisima za specične
operacije

Deo rezervisan za podatke

21
Primeri standardne forme1/4

22
Primeri standardne forme
2/4

23
Primeri standardne forme3/4

24
Primeri standardne forme4/4

25
Paleta standardne forme
Pretraga po svimpoljima (Query by Form) Prelazak na prvi slog
Prelazak na prethodni slog
Povratak na prethodnu formu, uz prenos vrednosti ključa tekućeg sloga
Prelazak na sledeći slog
Promena vrste prikaza Prelazak na poslednji slog

Osvežavanje prikaza (ponovno učitavanje podataka) Unos slogova

Pomoć na nivou forme Brisanje tekućeg sloga


Izmena tekućeg sloga
Prelazak na vezane forme Kopiranje tekućeg sloga

26
Organizacija panela standardne forme
◦ ređati polja na isti način kao kolone okviru tabelarnog prikaza, u
redosledu sa leva na desno i odozgo prema dole
◦ grupisati semantički povezana polja (zaokruživanjem, natpisima,
tabovima, separatorima i sl.)
◦ paziti da površina forme bude dovoljna, tako da ekran ne izgleda
pretrpan (screen-density (odnos površine komponenti u odnosu na
površinu forme) je optimalno 40%)
◦ truditi se da polja budu ravnomerno raspoređena, sa jednakim
rastojanjem između redova i poravnata barem po levoj ivici (a ako
je moguće po obe ivice)
◦ paziti da polja budu dovoljne širine tako da podaci mogu da se
ispišu bez potrebe pomeranja prikaza
◦ izabrati minimalan skup boja i fontova i dosledno ih koristiti
◦ koristiti minimalan standardizovan skup komponenti

27
Vrste polja na panelu
poljapridružena kolonama tabela u bazi
(omogućena za ažuriranje)
izvedena polja (koriste se samo za prikaz)
◦ lookup
◦ kalkulisana
◦ agregirana

28
Vrste polja na panelu1/2
lookup polja - omogućavaju prikaz dodatnih
kolona iz druge tabele čiji je primarni ključ
prisutan kao spoljni ključ osnovne tabele
kalkulisana polja – formiraju se primenom željene
formule nad vrednostima različitih obeležja
tekućeg sloga
agregirana polja (polja za prikaz sumarnih
informacija) – formiraju se korišćenjem vrednosti
istog obeležja, nad skupom slogova koji
zadovoljavaju neki kriterijum (suma, prosek,
maksimum i sl.)
29
Vrste polja na panelu2/2

Lookup
polja

Kalkulisa
no polje

Agregiran
a polja

30
Režimi rada:
pregled
unos
izmena
pretraga

31
Mehanizmi za povezivanje standardnih
formi
Next
Zoom

32
Next mehanizam
Ukoliko su tabele u bazi vezane po parent-child
mehanizmu potrebno je omogućiti direktan prelazak sa
forme pridružene parent tabeli na formu pridruženu child
tabeli, tako da se u okviru poslednje nalaze samo podaci
vezani za vrednost ključa tekućeg sloga iz parent forme
Ukoliko postoji više vezanih formi, prilikom aktiviranja
softverskog tastera za prelazak na vezane forme, treba
prikazati pop-up meni sa listom opcija, iz koje korisnik
može izabrati željenu
Polja koja pripadaju ključu parent tabele treba da su u
svim režimima popunjena vrednošću ključa prethodnog
sloga i onemogućena za izmenu

33
Next mehanizam - primer
Računopolagači

Službe
Sifra službe A1
Naziv BL

Magacinske kartice
Godina kartice A4

Promet magacinske kartice


Redni broj promene N6

34
Next mehanizam - primer

35
Zoom mehanizam
◦ Zoom mehanizam podrazumeva aktiviranje
forme pridružene nezavisnoj (parent) tabeli, iz
koje korisnik može izabrati željeni slog i
"prevući" ga (preuzeti njegove vrednosti) u polje
ili polja forme pridružene zavisnoj (child) (3)
Povratak na prethodnu formu,
uz preuzimanje vrednosti
tabeli.
Naseljena Aktiviranje
mesta
Šifra mesta A5
"zoom"- a (1)
Naziv A40
mesta

Radnici
Šifra A5
Izbor željenog sloga
radnika
Prezime A18
(2)
Mesto rodjenja
radnika
Ime A18
radnika

36
Kompozitni zoom
◦ Ako se radi o kompozitnom spoljnom ključu,
čija je polja korisnik delimično popunio, u
okviru zoom forme treba obezbediti automatsko
filtriranje podataka u skladu sa unetim
vrednostima

37
Primer nastajanja kompozitnih spoljnih
ključeva
Preduzeæa Sektori Službe Odelenja
Šifra preduzeæa A1 Sifra sektora A1 Sifra službe A1 Sifra odelenja A1
Sadrzi sektore Sadrzi službe Sadrzi odelenja
Naziv preduzeæa A60 Naziv sektora A40 Naziv službe A40
....... Naziv odelenja A40
....... ....... .......

Konceptualni model dela organizacione šeme preduzeća


PR_SIFRA = PR_SIFRA
SEK_SIFRA = SEK_SIFRA
SLU_SIFRA = SLU_SIFRA
PR_SIFRA = PR_SIFRA
SEK_SIFRA = SEK_SIFRA ODELENJA
PR_SIFRA = PR_SIFRA SLUZBE PR_SIFRA CHAR(1)
SEK_SIFRA CHAR(1)
SEKTORI PR_SIFRA CHAR(1)
SEK_SIFRA CHAR(1) SLU_SIFRA CHAR(1)
PREDUZECA PR_SIFRA CHAR(1) ODE_SIFRA CHAR(1)
PR_SIFRA CHAR(1) SEK_SIFRA CHAR(1) SLU_SIFRA CHAR(1)
......
SLU_NAZIV CHAR(40) ODE_NAZIV CHAR(40)
PR_NAZIV CHAR(60) SEK_NAZIV CHAR(40) ...... ......
...... ......

Fizički model dela organizacione šeme preduzeća

Kompozitni Zoom u okviru forme pridružene tabeli Odelenja

38
ComboZoom
◦ Kombinacija zoom-a i ComboBox-a
◦ Korisnik može izabrati vrednost iz
ComboBox-a, a ukoliko potrebna vrednost ne
postoji, može je uneti aktviranjem zoom forme

39
Parent-child forma
◦ “Parent-Child” forma se koristi za rad sa
poslovnim dokumentima koji poseduju
hijerarhijski organizovanu strukturu (tipa n-
arnog stabla), pri čemu je svaki element
hijerarhije modelovan jednim entitetom u bazi
podataka
◦ U ovom slučaju, Next mehanizam ne pruža
zadovoljavajuću funkcionalnost jer korisnik ne
želi odvajanje dokumenta u okviru više formi,
već je potrebna jedna forma koja udružuje sve
segmenta dokumenta u jedinstvenu celinu
40
Primer Parent-child forme sa tri child-a
Raspored sedenja

Radnici Anali tika radnog staža

Raspored na radno m esto

41
Primer Parent-child forme sa tri child-a

42
Many-to-many forma
◦ namenjena za intenzivan unos podataka u
okviru tabela koje u svom ključu kombinuju
ključeve dve ili više drugih tabela

Porez
Katalog poreza
Poreske stope
Oznaka poreza A2
Naziv poreza A50 Za porez Datum primene D
Uplacuje se na racun A30 Poreska stopa DC4,2

Tarifni stavovi
Porezi za tarifni stav Tarifne grupe
Oznaka tarifnog stava A2
Vaze od D Naziv tarifnog stava A40 Oznaka tarifne grupe A2
Pripada tarifnom Pripada
Roba sa faznim porezom? BL Naziv tarifne grupe A60
stavu grupi

43
Many-to-many forma - primer

44
Forma za unos parametara
◦ Omogućava unos parametara potrebnih za
pokretanje složenih transakcija i izveštaja

45
Standardna forma
Rad sa jednom tabelom
u bazi

03.06.2020.g.
Osnovne operacije nad slogovima u bazi
Navigacija – prelazak na prvi, prethodni, sledeći i
poslednji slog u tabeli
Operacije nad podacima: unos, izmena, brisanje,
pretraga

Za svaku operaciju realizovati po jednu privatnu


metodu u okviru forme, koja će se pozivati od
strane actionPerformed metode
odgovarajućeg elementa korisničkog interfejsa
Time se dobija na fleksibilnosti jer se metode i
uzajamno pozivati po potrebi
47
Navigacija
Potrebne metode:
JTable:
void setRowSelectionInterval (int index0, int index1)
Selektuje niz redova od Index0 do index1. Indeksi redova
počinju od 0.
int getSelectedRow()
Vraća indeks prvog selektovanog reda
TableModel:
int getRowCount()
Vraća broj redova
Object getValueAt(int rowIndex, int columnIndex)
Vraća objekat u zadatom redu i koloni. Redovi i kolone
počinju od 0.

48
Primer 1
Prelazak na poslednji slog:

private void goLast() {


int rowCount = tblGrid.getModel().getRowCount();
if (rowCount > 0)
tblGrid.setRowSelectionInterval(rowCount - 1,
rowCount - 1);
}

Napomena: tblGrid je naziv tabele, tj. instance klase


JTable

49
Sinhronizacija prikaza
Prilikom navigacije nad slogovima,
potrebno je sinhronizovati tekući red u
okviru tabele sa linijama za unos u okviru
panela:

50
Primer 2
Sinhronizacija prikaza:

private void sync() {


int index = tblGrid.getSelectedRow();
if (index < 0) {
tfSifra.setText("");
tfNaziv.setText("");
return;
}
String sifra = (String)tableModel.getValueAt(index, 0);
String naziv = (String)tableModel.getValueAt(index, 1);
tfSifra.setText(sifra);
tfNaziv.setText(naziv);
}

Napomena: tfSifra i tfNaziv su nazivi linija za unos šifre i naziva


države, respektivno

51
Operacije nad podacima

Dugme za potvrdu
akcije
Dugme za
odustajanje od akcije

Izmena – samo u okviru linija za unos. Korisnik u svakom


trenutku može da unese željenu vrednost i pritisne dugme za
potvrdu
Unos – Korisnik ulazi u režim za unos pritiskom na
odgovarajuće dugme na toolbar-u. Linije za unos se tada brišu
i kursor postavlja na prvu komponentu u panelu. Slogovi se
unose sve dok korisnik ne pritisne dugme za odustajanje
52
Pretraga
Brisanje – briše se tekući slog pritiskom na odgovarajuće
dugme na toolbar-u, uz obavezno traženje potvrde od
strane korisnika.
Pretraga – Korisnik ulazi u režim za pretragu pritiskom na
odgovarajuće dugme na toolbar-u. Linije za unos se tada
brišu i kursor postavlja na prvu komponentu u panelu.
Pretraga se izvršava pritiskom na dugme za potvrdu,
posle čega se u tabeli prikazuje rezultat pretrage, a
forma vraća u režim za izmenu.

53
Režimi forme
izmena (default)
unos

pretraga

Podrška za režime u okviru forme:

private static final int MODE_EDIT = 1;


private static final int MODE_ADD = 2;
private static final int MODE_SEARCH = 3;
private int mode;

54
Režimi forme
Pri promeni režima voditi računa koje
komponente su omogućene
Pri promeni podataka u bazi potrebno je osvežiti
i podatke u tabeli:
◦ ponovnim učitavanjem iz baze (zahtevno sa
stanovišta servera i mreže)
◦ održavanjem podataka u tabeli korišćenjem metoda
TableModel-a:
removeRow(index);
addRow(new String[]{sifra, naziv});
setValueAt
55
Primer 3
Brisanje reda (metoda klase DrzaveTableModel)

public void deleteRow(int index) throws SQLException {


PreparedStatement stmt =
DBConnection.getConnection().prepareStatement(
"DELETE FROM drzava WHERE dr_sifra=?");
String sifra = (String)getValueAt(index, 0);
stmt.setString(1, sifra);
//Brisanje iz baze
int rowsAffected = stmt.executeUpdate();
stmt.close();
DBConnection.getConnection().commit();
if (rowsAffected > 0) {
// i brisanje iz TableModel-a
removeRow(index);
fireTableDataChanged();
}
}

56
Primer 4
Metoda u okviru forme, aktivira se izborom dugmeta
za brisanje:

private void removeRow() {


int index = tblGrid.getSelectedRow();
if (index == -1) //Ako nema selektovanog reda (tabela prazna)
return; // izlazak
//kada obrisemo tekuci red, selektovacemo sledeci (newindex):
int newIndex = index;
//sem ako se obrise poslednji red, tada selektujemo prethodni
if (index == tableModel.getRowCount() - 1)
newIndex--;
try {
DrzaveTableModel dtm = (DrzaveTableModel)tblGrid.getModel();
dtm.deleteRow(index);
if (tableModel.getRowCount() > 0)
tblGrid.setRowSelectionInterval(newIndex, newIndex);
} catch (SQLException ex) {
JOptionPane.showMessageDialog(this, ex.getMessage(), "Greska",
JOptionPane.ERROR_MESSAGE);
}
}

57
Unos slogova
Problem – gde staviti uneti red:
◦ na početak?
◦ na kraj?
◦ u sredinu tako da tabela ostane sortirana?

◦ Za sortiranje treba voditi računa i o slovima:


čšćđž, koje metoda String.compare stavlja na
kraj.
◦ Rešenje: realizovati sopstvenu klasu za
sortiranje (uključiti u projekat klasu SortUtils)
58
Primer 5
Sortni unos u tabelu, metoda klase DrzavaTableModel:
private int sortedInsert(String sifra, String naziv) {
int left = 0;
int right = getRowCount() - 1;
int mid = (left + right) / 2;
while (left <= right ) {
mid = (left + right) / 2;
String aSifra = (String)getValueAt(mid, 0);
if (SortUtils.getLatCyrCollator().compare(sifra, aSifra) > 0)
left = mid + 1;
else if (SortUtils.getLatCyrCollator().compare(sifra, aSifra) < 0)
right = mid - 1;
else
// ako su jednaki: to ne moze da se desi ako tabela ima primarni
kljuc
break;
}
insertRow(left, new String[] {sifra, naziv});
return left;
}
}

59
Primer 6
Unos sloga, metoda klase DrzavaTableModel:
public int insertRow(String sifra, String naziv) throws
SQLException {
int retVal = 0;
PreparedStatement stmt =
DBConnection.getConnection().prepareStatement(
"INSERT INTO drzava (dr_sifra, dr_naziv) VALUES (? ,?)");
stmt.setString(1, sifra);
stmt.setString(2, naziv);
int rowsAffected = stmt.executeUpdate();
stmt.close();
//Unos sloga u bazu
DBConnection.getConnection().commit();
if (rowsAffected > 0) {
// i unos u TableModel
retVal = sortedInsert(sifra, naziv);
fireTableDataChanged();
}
return retVal;
}

60
Primer 7
Metoda u okviru forme, aktivira se
izborom dugmeta za potvrdu unosa:
private void addRow() {
String sifra = tfSifra.getText().trim();
naziv = tfNaziv.getText().trim();
try {
DrzaveTableModel dtm =
(DrzaveTableModel)tblGrid.getModel();
dtm.insertRow(sifra, naziv);
tblGrid.setRowSelectionInterval(index, index);
setMode(MODE_ADD);
} catch (SQLException ex) {
JOptionPane.showMessageDialog(this,
ex.getMessage(), "Greska",
JOptionPane.ERROR_MESSAGE);
}

61
Ključni elementi aplikacije

62
MDBISD – Aplikativni aspekti

Implementac
Implementacija klijentske
strane
Povezivanje klijenta sa
serverom ija serverske
strane

Prof. dr Branko Perišić 63


Uskladištene procedure
funkcije i trigeri
MySQL – Storred Objects
Uskladišteni objekti
Uskladišteni objekti predstavljaju
procedurne delov SQL koda koji se
skladište na strani servera baze
(POSLOVNA LOGIKA).
Postoje tri tipa uskladištenih objekata:
◦ Uskladištene procedure (Stored procedures)
◦ Uskladištene funkcije (Storred functions)
◦ Okidači (Triggers)

65
Uskladišteni objekti
Uskladištene procedure: Predstavlja
objekat koji se formura uz oslonac na
CREATE PROCEDURE iskaz a poziva
upotrebol CALL iskaza.
Procedura ne poseduje povratnu vrednost
ali može menjati vrednost svojih
parametara.
Obično formira rezultujući skup podataka
koji vraća klijentu (programu).
66
Uskladišteni objekti - procedure
CREATE
[DEFINER = user]
PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
proc_parameter: [ IN | OUT | INOUT ] param_name type

characteristic: {
COMMENT 'string'
| LANGUAGE SQL
| [NOT] DETERMINISTIC
|{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
}
CALL sp_name ([parameter[,...]])
routine_body:
CALL sp_name [()]
Valid SQL routine statement
67
Uskladišteni objekti - procedure
LANGUAGE - karakteristika definiše
programski jezik na kome je procedura
napisana. Server IGNORIŠE ovu vrednost –
jedni je podržan SQL.
Procedura se naziva “determinističkom” ako
ovek daje isti rezultat za iste vrednosti
ulaznih parametara, u protivnom se naziva
“nedeterminističkom” .
Podrazumevana vrednost je NOT
DETERMINISTIC.
68
Uskladišteni objekti - procedure
Postoji niz karakteristika koje nude
informacije o prirodi podataka koje
procedura koristi.
U slučaju MySQL, one se samo
preporučuju, njihova primena nije
obavezna.
Server ih uopšte ne kloristi kao podlogu
za primenu ograničenja bilo kog tipa.

69
Uskladišteni objekti - procedure
CONTAINS SQL indicira da procedura
ne sadrži iskaze koji čitaju ili pišu
podatke
To je podrazumenava interpretacija.
Primer:
◦ SET @x = 1 ili
◦ DO RELEASE_LOCK('abc'),
◦ Izvršava se ali niti čita niti zapisuje podatke u
bazu.

70
Uskladišteni objekti - procedure
NO SQL indicira da procedura ne sadrži
SQL iskaze.
READS SQL DATA indicira da procedura
sadrži iskaze koji čitaju podatke (npr,
SELECT), ali ne sadrži iskaze koji vrše
zapisivanje.
MODIFIES SQL DATA indicira da
procedura sadrži iskaze koji koji modifikuju
podatke u bazi (npr, INSERT ili DELETE).

71
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT][SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr] ...
[into_option]
[FROM table_references
[PARTITION partition_list]]
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[into_option]
[FOR UPDATE | LOCK IN SHARE MODE]

72
into_option: {
INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name] ...
}

73
INSERT
[LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
{VALUES | VALUE} (value_list) [, (value_list)] ...
[ON DUPLICATE KEY UPDATE assignment_list]

value: {
expr | DEFAULT
}

value_list:
value [, value] ...

assignment:
col_name = value

assignment_list:
assignment [, assignment] ...

74
DELETE
[LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]

75
Uskladišteni objekti - funkcije
CREATE
[DEFINER = user]
FUNCTION sp_name ([func_parameter[,...]])
RETURNS type
[characteristic ...] routine_body

76
Uskladišteni objekti – okidači(trigeri)
Okidač je imenovani uskladišteni objekat
pridružen tabeli koji se aktivira kada se nad
tabelom primenjuje neka od operacija (INSERT,
UPDATE, DELETE)
Okidać (triger) se povezuje za tabelu definisanu u
tbl_name, svojstvu koje mora biti ime stalne tabele
u bazi. Okidače nije moguće povezati za
privremene (TEMPORARY) tabele ili poglede
(VIEW).
Imena okidača se uključuju u prostor imena šeme
baze tako da dupliciranje imena nije dozvoljeno
unutar iste šeme.
77
Uskladišteni objekti - funkcije
CREATE
[DEFINER = user]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
[trigger_order] trigger_body

trigger_time: {BEFORE | AFTER }


trigger_event: {INSERT | UPDATE | DELETE }
trigger_order: {FOLLOWS | PRECEDES }
other_trigger_name
78
Uskladišteni objekti – okidači(trigeri)
trigger_body - sadrži iskaz koji će se izvršiti ako
dođe do aktiviranja okidača.
Ako telo funkcije sadrži više od jednog iskaza
pottrebno je koristiti blok-iskaz (BEGIN ... END).
Unutar blok iskaza moguće je smestiti proizvoljne
SQL naredne.
Šta se dešava ako je to poziv uskladištene
procedure?

79
MDBISD – Aplikativni aspekti

Povezivanje
Implementacija klijentske
strane klijenta sa Implementacija serverske
strane

serverom

Prof. dr Branko Perišić 80


Povezivanje sa skladištem
podataka (serverom)
Povezivanje MySQL sa Python klijentom
MySQL Connector/Python omogućava Python
programima pristup MySQL bazama, uz oslonac
na API usklađen sa Python
Database API Specification v2.0 (PEP 249).
Detalje vezane za različite verzije
Connector/Python, možete dobiti preko sledećeg
linka: MySQL Connector/Python Release Notes.
Za informaciju o tome koja Python verzija može
da se koristi sa različitim verzijama MySQL
Connector/Python, referencirajte Chapter 3,
Connector/Python Versions.

82
Povezivanje MySQL sa Python klijentom

83
Uputstva za Python programere
 For security, do not hardcode the values needed to
connect and log into the database in your main
script. Python has the convention of a config.py
module, where you can keep such values separate
from the rest of your code.
 Python scripts often build up and tear down large
data structures in memory, up to the limits of
available RAM. Because MySQL often deals with
data sets that are many times larger than available
memory, techniques that optimize storage space and
disk I/O are especially
 Any application that accepts input must expect to
handle bad data.
84
Uputstva za Python programere
 Because the result sets from SQL queries can be very large,
use the appropriate method to retrieve items from the result
set as you loop through them.
◦ fetchone() retrieves a single item, when you know the result set
contains a single row.
◦ fetchall() retrieves all the items, when you know the result set
contains a limited number of rows that can fit comfortably into
memory.
◦ fetchmany() is the general-purpose method when you cannot predict
the size of the result set: you keep calling it and looping through the
returned items, until there are no more results to process.
 Since Python already has convenient modules such as
pickle and cPickle to read and write data structures on disk,
data that you choose to store in MySQL instead is likely to
have special characteristics:
85
Guidelines for Python Developers
 Too large to all fit in memory at one time. You use SELECT
statements to query only the precise items you need, and
aggregate functions to perform calculations across multiple items. You
configure the innodb_buffer_pool_size option within the MySQL
server to dedicate a certain amount of RAM for caching query results.
 Too complex to be represented by a single data structure. You
divide the data between different SQL tables. You can recombine data
from multiple tables by using a join query. You make sure that related
data is kept in sync between different tables by setting up foreign key
relationships.
 Updated frequently, perhaps by multiple users simultaneously. The
updates might only affect a small portion of the data, making it
wasteful to write the whole structure each time. You use the SQL
INSERT, UPDATE, and DELETE statements to update different items
concurrently, writing only the changed values to disk. You use InnoDB
tables and transactions to keep write operations from conflicting with
each other, and to return consistent query results even as the
underlying data is being updated.
86
Guidelines for Python Developers
◦ Upotreba sadržanih SQL iskaza u Python
programima obično uključuje deklaraciju dugih
stringova, koji sadrže više linija.
◦ Kako stringovi u SQL iskazima mogu sadržavati
jednostruke, i dvostruke navodnike, opravdano je
koristiti Python-ov mehanizam trostrukih
navodnika kojima se obuhvata celi iskaz.

87
Connector/Python Coding Examples
 5.1 Connecting to MySQL Using Connector/Python
 5.2 Creating Tables Using Connector/Python
 5.3 Inserting Data Using Connector/Python
 5.4 Querying Data Using Connector/Python

 The connect() constructor creates a connection to the MySQL server


and returns a MySQLConnection object.
 The following example shows how to connect to the MySQL server:

88
Connector/Python Coding Examples
 Itis also possible to create connection objects using the
connection.MySQLConnection() class:

89
Connector/Python Coding Examples
 To handle connection errors, use the try statement and
catch all errors using the errors.Error exception:

90
Connector/Python Coding Examples
 Alternativno:

91
Connector/Python Coding Examples
 Kreiranje tabele

92
Connector/Python Coding Examples
 Insertiranje podataka

93
Connector/Python Coding Examples
 Pretraga

94
Calling stored procedures from Python
To call a stored procedure in Python, you follow the
steps below:
◦ Connect to the database by creating a new
MySQLConnection object.
◦ Instantiate a new MySQLCursor object from the
MySQLConnection object by calling the cursor() method.
◦ Call  callproc() method of the MySQLCursor object. You
pass the stored procedure’s name as the first argument of the 
callproc() method. If the stored procedure requires parameters,
you need to pass a list as the second argument to the 
callproc() method. In case the stored procedure returns a result
set, you can invoke the  stored_results() method of the
MySQLCursor object to get a list iterator and iterate this result
set by using the  fetchall() method.
◦ Close the cursor and database connection as always.
95
Calling stored procedures from Python

96
Connector/Python Coding Examples
import mysql.connector
from mysql.connector import Error
try:
connection = mysql.connector.connect(host='localhost',
database='Obrazovanje',
user='bperisic',
password='admI!23gz29')
cursor = connection.cursor()
cursor.callproc('get_students', [1, ])
# print results
print("Prikaz podataka o studentima")
for result in cursor.stored_results():
print(result.fetchall())
except mysql.connector.Error as error:
print("Greška prilikom izvršavanja obrade:{}".format(error))

finally:
if (connection.is_connected()):
cursor.close()
connection.close()
print("MySQL konekcija je zatvorene!")

97
Connector/Python Coding Examples
import mysql.connector
from mysql.connector import Error
try:
Uključivanje MySQL
connection = mysql.connector.connect(host='localhost',
drajvera za pristup bazi
database='Obrazovanje',
podataka
user='bperisic',
password='admI!23gz29')
cursor = connection.cursor()
cursor.callproc('get_students', [1, ])
# print results
print("Prikaz podataka o studentima")
for result in cursor.stored_results():
print(result.fetchall())
except mysql.connector.Error as error:
print("Greška prilikom izvršavanja obrade:{}".format(error))

finally:
if (connection.is_connected()):
cursor.close()
connection.close()
print("MySQL konekcija je zatvorene!")

98
Connector/Python Coding Examples
import mysql.connector
from mysql.connector import Error
try:
connection = mysql.connector.connect(host='localhost',
database='Obrazovanje',
Uključivanje Error objekta iz
user='bperisic',
mysql.connector
password='admI!23gz29')
cursor = connection.cursor()
Primer: ER_ACCESS_DENIED_ERROR
cursor.callproc('get_students', [1, ])
# print results
print("Prikaz podataka o studentima")
for result in cursor.stored_results():
print(result.fetchall())
except mysql.connector.Error as error:
print("Greška prilikom izvršavanja obrade:{}".format(error))

finally:
if (connection.is_connected()):
cursor.close()
connection.close()
print("MySQL konekcija je zatvorene!")

99
Connector/Python Coding Examples
import mysql.connector
from mysql.connector import Error
try:
connection = mysql.connector.connect(host='localhost',
database='Obrazovanje',
user='bperisic',
password='admI!23gz29')
cursor = connection.cursor()
cursor.callproc('get_students', [1, ])
Povezivanje
# print sa instancom MySQL baze
results
print("Prikaz podataka o studentima")
na serveru
for result in cursor.stored_results():
print(result.fetchall())
except mysql.connector.Error as error: Eksplicitno
definisani
print("Greška prilikom izvršavanja obrade:{}".format(error))
konekcioni
finally: parametri
if (connection.is_connected()):
cursor.close()
connection.close()
print("MySQL konekcija je zatvorene!")

100
Calling stored procedures from Python
Konekcioni parametri
◦ use_unicode: Whether to use Unicode. The default value is True.
◦ port: The TCP/IP port of the MySQL server. This value must be an
integer. We can specify the different port number if MySQL server is
listening to the different port. The default value for this port
argument is 3306.
◦ charset: MySQL character set to use, character set variables relate
to a client’s interaction with the server. There are almost 30 to 40
charset MySQL server supports. The default value of the charset
argument is “utf8″.
◦ auto-commit: Whether to auto-commit transactions. If you want to
manage transactions in MySQL from Python, you need to set this
value to true or false. The default value is False, i.e. the changes are
not committed to the database. You need to explicitly call a commit
method to persist your changes in the database.

101
Calling stored procedures from Python
Konekcioni parametri
◦ get_warnings: To fetch warning, this is helpful to know the
connection is established but with warnings. The default value is
False.
◦ raise_on_warnings: Whether to raise an exception on warnings.
The Default value is False.
◦ connection_timeout (connect_timeout*) : Timeout for the TCP and
Unix socket connections. The connection terminates after this
timeout expired.
◦ buffered: Whether cursor objects fetch the results immediately after
executing queries. The default value is False.
◦ raw: Whether MySQL results are returned as-is, rather than
converted to Python types. The default value is False. You can set it
to true if you want a query result in python type.

102
Calling stored procedures from Python
Konekcioni parametri
◦ force_ipv6: When setting to True, uses IPv6 when an address
resolves to both IPv4 and IPv6. By default, IPv4 used in such cases.
The default value for this argument is false.
◦ pool_name: It is the Connection pool name that you are creating or
using.
◦ pool_size: Connection pool size that you want to create. the default
value is 5.
◦ pool_reset_session: Whether to reset session variables when the
connection returned to the pool. the default is True.
◦ use_pure: Whether to use pure Python or C Extension. If
use_pure=False then pure python module is used otherwise it
connects MySQL using C extension. Moreover, if C Extension is not
available, then My SQL Connector Python automatically fall back to
the pure Python implementation.

103
Calling stored procedures from Python
Konekcioni parametri
◦ unix_socket: The location of the Unix socket file. These enable
communication between two processes.
◦ auth_plugin: Authentication plugin to use.
◦ collation: MySQL collation to use. you can use the collation that
you set while installing MySQL Server. The default value is
utf8_generalW_chiich.
◦ sql_mode: Set the sql_mode session variable at connection time.

104
Connector/Python Coding Examples
import mysql.connector
from mysql.connector import Error
try:
connection = mysql.connector.connect(host='localhost',
database='Obrazovanje',
user='bperisic',
password='admI!23gz29')
cursor = connection.cursor()
cursor.callproc('get_students', [1, ])
# print results
print("Prikaz podataka o studentima")
for result in cursor.stored_results():
print(result.fetchall())

print("Greška cursor
except mysql.connector.Error as error:
Kreiranje objekta obrade:{}".format(error))
prilikom izvršavanja

finally:
if (connection.is_connected()):
cursor.close()
connection.close()
print("MySQL konekcija je zatvorene!")

105
Calling stored procedures from Python
Klasa MySQLCursor
◦ Instancira objekte koji mogu izvršavati SQL iskaze.
Kursor objekat je u interakciji sa MySQL bazom uz
oslonac na MySQLConnection objekat.
◦ MySQLCursor kao roditeljsku klasu nasleđuje i
specijalizuje skup klasa potomaka čije se instanciranje
pokreće prosleđivanjem parametara cursor() metodi
(konstruktoru).

106
Calling stored procedures from Python

107
Connector/Python Coding Examples
import mysql.connector
from mysql.connector import Error
try:
connection = mysql.connector.connect(host='localhost',
database='Obrazovanje',
user='bperisic',
password='admI!23gz29')
cursor = connection.cursor()
cursor.callproc('get_students', [1, ])
# print results
print("Prikaz podataka o studentima")
for result in cursor.stored_results():
print(result.fetchall())
Poziv uskladištene procedure
except mysql.connector.Error as error:
print("Greška prilikom izvršavanja obrade:{}".format(error))
Rezultujući skup podataka se vraća u
finally:
ifobjektu klase MySQLCursorBuffered
(connection.is_connected()):
cursor.close()
connection.close()
print("MySQL konekcija je zatvorene!")

108
Calling stored procedures from Python
Klasa MySQLCursor
◦ Pristup rezultujućem skupu podataka smeštenom u
instanci klase MySQLCursofBuffered omogućava
metoda cursor.storred_results() koja vraća objekat listu
koja poseduje iterator:
iterator = cursor.stored_results()
◦ Rezultujući skup ostaje na raspolaganju sve dok se kursor
ne upotrebi za neku drugu operaciju ili se ne pozove
druga uskladištena procedura.
◦ Obrada ima formu:
for result in cursor.stored_results():
radite_nesto()
109
Connector/Python Coding Examples
import mysql.connector
from mysql.connector import Error
try:
connection = mysql.connector.connect(host='localhost',
database='Obrazovanje',
user='bperisic',
password='admI!23gz29')
cursor = connection.cursor()
cursor.callproc('get_students', [1, ])
# print results
print("Prikaz podataka o studentima")
for result in cursor.stored_results():
print(result.fetchall())

except mysql.connector.Error as error:


print("Greška prilikom izvršavanja obrade:{}".format(error))

finally:
if (connection.is_connected()):
cursor.close()
connection.close()
print("MySQL konekcija je zatvorene!")
110
Calling stored procedures from Python
Najčešće referencirane metode
◦ MySQLCursor.column_names – vraća nazive kolona iz rezultujućeg
skupa podataka u formi niza Unicod stringova (Vodite računa da su to
kodovi polja a ne labele). Možemo ih iskoristiti za pristup metaopisu
iz koga vadimo Labele.
◦ MySQLCursor.description - vraća niz uređenih torki koje sadrže
deskriptore kolona u rezultujućem skupu podataka (U našem slučaju
mi te podatke čuvamo u sklopu metaopisa)
Torka
(column_name,
type,
None, None, None, None,
null_ok,
column_flags)
111
Calling stored procedures from Python
Najčešće referencirane metode
◦ MySQLCursor.lastrowid - vraća identifikator poslednjeg dodatog
zapisa (reda). (upotreba kod automatskog inkrementiranja)
◦ MySQLCursor.rowcount - vraća broj redova u rezultujućem
skupu
◦ MySQLCursor.statement – vraća u formi stringa poslednju
izvršenu komandu
◦ MySQLCursor.with_rows – vraća True ako u rezultujućem skup
podataka koji je formiran kursorom postoje zapisi.

112
Calling stored procedures from Python
◦ 10.5.1 cursor.MySQLCursor Constructor
◦ 10.5.2 MySQLCursor.callproc() Method
◦ 10.5.3 MySQLCursor.close() Method
◦ 10.5.4 MySQLCursor.execute() Method
◦ 10.5.5 MySQLCursor.executemany() Method
◦ 10.5.6 MySQLCursor.fetchall() Method
◦ 10.5.7 MySQLCursor.fetchmany() Method
◦ 10.5.8 MySQLCursor.fetchone() Method
◦ 10.5.9 MySQLCursor.fetchwarnings() Method
◦ 10.5.10 MySQLCursor.stored_results() Method
◦ 10.5.11 MySQLCursor.column_names Property
◦ 10.5.12 MySQLCursor.description Property
◦ 10.5.13 MySQLCursor.lastrowid Property
◦ 10.5.14 MySQLCursor.rowcount Property
◦ 10.5.15 MySQLCursor.statement Property
◦ 10.5.16 MySQLCursor.with_rows Property
113
Projektovanje informacionih sistemacija

?
Baze podataka
Aplikativni aspekti PIS

You might also like