Www.tfzr.uns.ac.rs



UNIVERZITET U NOVOM SADU

TEHNIČKI FAKULTET „MIHAJLO PUPIN“

ZRENJANIN

INFORMACIONI SISTEMI 2

SEMINARSKI RAD: FILMOTEKA

|Profesor: prof. dr Biljana Radulović |Student: Marko Kovač |

|Asistent: doc. dr Zoltan Kazi |Broj indeksa: 49/14 |

|Informacioni sistemi 2 |Smer: IT |

U Zrenjaninu 2018.

Sadržaj:

1. Arhitektura sistema

2. Tehnologije

3. Dijagram komponenti

4. Komponente

1. Docker

2. Modeli baze podataka

3. SQL šema

4. Kreiranje kontrolera

5. Kreiranje servisa i repository

5. Nivo grafičkog interfejsa

6. Angular 5

Arhitektura sistema:

Sam sistem podeljen je na dva dela a cine ga grafički interfejs i nivo logike i baze podataka. Nivo logike je pisam u programskom jeziku Java koja koristi veb alat Spring radi kreiranja API koje kasnije koristi grafički interfejs kako bi korisnicima prikazao podatke koji se čuvaju u bazi podataka.

Tehnologije:

Tehnologije koje su korišćene prilikom izrade ovog seminarskog rada jesu:

• Spring framework

• JPA/Hibernate

• Docker

• Angular 5

• Angular material design

Dijagram komponenti:

[pic]

Komponente:

Docker

Sama baza podataka je podignuta preko Docker kontejnera, alata za virtualizaciju. Kako bi mogli da koristimo Docker potrebno ga je skinuti sa linka. Prvi korak je skinuti Mysql image sa Docker Hub kako bi mogli da podignemo Mysql kontejner.

docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

Pomoću ove komande skidamo Mysql image sa Docker Hub a zatim podižemo kontejner na portu 3306 koji sa mapiramo na host port 3306.

Kada je kontejner podignut možemo mu pristupiti tako što izvršimo komandu:

docker exec -it mysql /bin/bash

Kada smo se prebacili na kontejner možemo pokrenuti Mysql:

mysql -u root -p

Na terminalu ćemo tada morati da ukucamo šifru koju smo gore naveli. Potom možemo pristupiti kreiranju same baze. NAPOMENA: dovoljno je kreirati samo bazu podataka dok će tabele kasnije generisati sam Hibernate. (Baza podataka nosi ime Filmoteka)

Modeli baze podataka

Sami modeli se kreiraju kroz Java programski jezik. Kada se aplikacija pokrene Hibernate alat generiše tabele, polja i relacije. Primer kreiranja jednog od modela koji se koriste:

@Entity

@Table(name="film")

public class Film {

@Id

@GeneratedValue(strategy=GenerationType.AUTO)

private Long id;

private String naziv;

@OneToOne

private Zanr zanr;

private String reziser;

private int trajanje;

@Column(name="godina_izdavanja")

private int godinaIzdavanja;

private int cena;

@JsonIgnore

@ManyToMany(mappedBy="filmovi")

private List racuni = new ArrayList();

public Film() {

// TODO Auto-generated constructor stub

}

public Film(String naziv, Zanr zanr, String reziser, int trajanje, int godinaIzdavanja, int cena) {

super();

this.naziv = naziv;

this.zanr = zanr;

this.reziser = reziser;

this.trajanje = trajanje;

this.godinaIzdavanja = godinaIzdavanja;

this.cena = cena;

}

public Long getId() {

return id;

}

public void setId(Long id) {

this.id = id;

}

public String getNaziv() {

return naziv;

}

public void setNaziv(String naziv) {

this.naziv = naziv;

}

public Zanr getZanr() {

return zanr;

}

public void setZanr(Zanr zanr) {

this.zanr = zanr;

}

public String getReziser() {

return reziser;

}

.........

SQL šema

create table adresa (id bigint not null, grad varchar(255), kucni_broj varchar(255), ulica varchar(255), primary key (id)) engine=MyISAM

create table film (id bigint not null, cena integer not null, godina_izdavanja integer, naziv varchar(255), reziser varchar(255), trajanje integer not null, zanr_id bigint, primary key (id)) engine=MyISAM

create table kupac (id bigint not null, datum_rodjenja varchar(255), ime varchar(255) not null, jmbg varchar(255), prezime varchar(255), adresa_id bigint, primary key (id)) engine=MyISAM

create table racun (id bigint not null, cena integer not null, datum varchar(255), kupac_id bigint, primary key (id)) engine=MyISAM

create table racun_filmovi (racuni_id bigint not null, filmovi_id bigint not null) engine=MyISAM

create table zanr (id bigint not null, naziv varchar(255), primary key (id)) engine=MyISAM

Kreiranje kontrolera

Kako bi grafički interfejs mogao da dobije podatke o svim filmovima koji su kreirani ili o svim kupcima potrebno je da napravimo API koji će upravljati sa bazom podataka. Primer:

@RestController

@RequestMapping("/film")

public class FilmController {

@Autowired

private FilmRepository filmService;

@Autowired

private ZanrRepository zanrService;

@RequestMapping(method = RequestMethod.GET)

public Iterable dajSveFilmove() {

return filmService.findAll();

}

@RequestMapping(method = RequestMethod.POST)

public Film snimiFilm(@RequestBody Film film) {

Optional zanrTemp = zanrService.findById(film.getZanr().getId());

Zanr zanr = new Zanr(zanrTemp.get().getId(), zanrTemp.get().getNaziv());

film.setZanr(zanr);

return filmService.save(film);

}

@RequestMapping(value="/{id}", method = RequestMethod.DELETE)

public Response obrisiFilm(@PathVariable Long id) {

Optional film = filmService.findById(id);

if (film.isPresent()) {

filmService.deleteById(id);

return new Response(HttpStatus.OK, "OK");

}

return new Response(HttpStatus.BAD_REQUEST, GlobalnePoruke.NE_POSTOJI);

}

}

Način ka koji možemo dobiti listu svih filmova iz baze jeste da pošaljemo HTTP GET zahtev na adresu . Sam API reaguje na tri HTTP zahteva GET kada povlačimo listu filmova, POST kada radimo update ili dodajemo novi film i DELETE kada brišemo film.

Kreiranje servisa i repository

Kontroler u sebi sadrži servis koji je direktna implementacija Repository koji sam po sebi nasledjuje CrudRepository

public interface KupacRepository extends CrudRepository {

@Query("select k from Kupac k where k.jmbg = :jmbg")

Kupac findByJmbg(@Param("jmbg") String jmbg);

}

Primer jednog proizvoljno dodatog SQL upita koji se kasnije koristi u aplikaciji kako bi dobili kupca sa odgovarajućim JMBG.

Kada servis implementira ovaj repository tada je duzan da implementira i neke od metoda koje dolaze sa ovim interfejsom.

@Service

@Transactional

public class KupacService implements KupacRepository {

@Autowired

private KupacRepository kupacRepository;

@Autowired

private AdresaRepository adresaRepository;

@Override

public S save(S kupac) {

// TODO Auto-generated method stub

Kupac tempKupac = findByJmbg(kupac.getJmbg());

Adresa adresa = adresaRepository.findByGradAndUlicaAndKucniBroj(

kupac.getAdresa().getGrad(),

kupac.getAdresa().getUlica(),

kupac.getAdresa().getKucniBroj());

if (tempKupac != null) {

kupac.setId(tempKupac.getId());

}

if (adresa != null) {

kupac.setAdresa(adresa);

}

return kupacRepository.save(kupac);

}

@Override

public Iterable saveAll(Iterable entities) {

// TODO Auto-generated method stub

return null;

}

@Override

public Optional findById(Long id) {

// TODO Auto-generated method stub

return kupacRepository.findById(id);

}

@Override

public boolean existsById(Long id) {

// TODO Auto-generated method stub

return false;

}

@Override

public Iterable findAll() {

// TODO Auto-generated method stub

return kupacRepository.findAll();

}

@Override

public void deleteById(Long id) {

// TODO Auto-generated method stub

kupacRepository.deleteById(id);

}

@Override

public Kupac findByJmbg(String jmbg) {

// TODO Auto-generated method stub

return kupacRepository.findByJmbg(jmbg);

}

}

Neke od metoda nisu implementirane zato što se ne koriste u radu ali su tu radi primera. Interfejs sam po sebi vec ima implementirane metode od strane Hibernate dok samu specifikaciju pruža JPA.

Takođe je važno napomenuti javinu anotaciju @Transactional. Ona nam govori o tome da će se svaki upit koji je usmeren ka bazi biti izvršen kao transakcija. U slučaju greškre radi se roll back.

Nivo grafičkog interfejsa:

Grafički deo čini Angular 5 framework koji je podignut na adresi. Sama tema koja se koristi za izradu grafičkog dela jeste Angular Material.

Grafički deo je koncipiran tako da se sastoji iz tri dela:

• Tabela sa filmovima (moguće je dodati, obrisati ili izmeniti film, takodje postoji adekvatna pretraga)

• Tabela sa kupcima (moguće je dodati, obrisati ili izmeniti kupca) Kod tabele se takođe nalazi opcija za kupovinu filmova

• Tabela sa računima (pruža nam uvid u sve račune)

TABELA SA FILMOVIMA I DODAVANJE NOVOG FILMA (KONKRETNA VALIDACIJA POLJA)

[pic]

[pic]

[pic]

TABELA SA KUPCIMA I DODAVANJE NOVOG KUPCA

[pic]

[pic]

KUPOVINA FILMA OD STRANE NEKOG KUPCA I KREIRANJE RAČUNA

[pic]

TABELA SA RAČUNIMA

[pic]

Angular 5

Ceo grafički diyajn se sastoji od mnoštva komponenata. Svaka komponenta u sebi sadrži odgovarajući Typescript kod kao i CSS i HTML fajlove koji pripadaju toj komponenti. Kod Angular 5 takođe imamo modele i servise koji nisam služe da bi povukli podatke sa API koji su kreirani od strane Spring frameworka. Primer modela:

import { Zanr } from "./zanr";

export interface Film {

id: number;

naziv: string;

zanr: Zanr;

reziser: string;

trajanje: number;

godinaIzdavanja: number,

cena: number

}

Model film sadrži sve atribute koji se nalaze i u modelu na strani Spring odnosno sve kolone koje se nalaze u bazi podataka kako bi adekvatno mogli da predstavimo u ovom slučaju film na strani korisnika.

Primer servisa koji izvršava HTTP zahteve:

import { Injectable } from '@angular/core';

import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';

import { Observable } from 'rxjs';

import { Film } from './model/film';

@Injectable({

providedIn: 'root'

})

export class FilmService {

url: string = '';

constructor(private http: HttpClient) { }

getFilmovi(): Observable {

return this.http.get(this.url);

}

deleteFilmById(id: number): Observable {

return this.http.delete(this.url + '/' + id);

}

save(film: Film): Observable {

return this.http.post(this.url, film);

}

}

Takođe svaki servis sadrži metode sa kojima možemo da gađamo izložene END-POINTE. Ovaj servis je identičan servisu na strani Spring alata samo što je glavna razlika u tome što servis na strani grafičkog nivoa samo šalje zahteve dok se na strani logike opisuje šta servis treba da radi kada sam HTTP zahtev dospe do njega.

Primer HTML stranice koja opisuje modalni prozor za dodavanje ili izmenu filma sa adekvatnom validacijom svakog polja:

Dodavanje novog filma / izmena postojeceg

Naziv *

Unesite naziv!

Zanr *

{{ zanr.naziv }}

Izaberite zanr!

Reziser *

Unesite rezisera!

Trajanje (min) *

Unesite trajanje!

Godina izdavanja *

Unesite godinu izdavanja!

Cena (din) *

Unesite cenu!

Odustani

Sacuvaj

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download