To jest stara wersja strony!
Ogólnopolska baza połączeń minibusowych
Autorzy: Jakub Gorzała, Łukasz Kowalski
Projekt bazy danych, która będzie wykorzystywana w projekcie z przedmiotu Technologie i programowanie WWW. Projekt ten ma na celu stworzenie portalu zawierającego rozkłady jazdy minibusów z całej polski.
2. Analiza stanu wyjściowego
W sieci istnieje strona o podobnej tematyce, lecz posiada ona sporo wad. Po pierwsze jest wykonana w bardzo prostej technologii (zwykły html + css), jest nieczytelna przez co prezentuje się bardzo nie atrakcyjnie i nie wzbudza zainteresowania. Nie jest aktualizowana, więc informacje na niej zawarte mogą być mylące dla użytkowników. Strona w głównej mierze jest zbiorem linków do poszczególnych przewoźników, a nie centralnym zbiorem rozkładów, przez co wyszukiwanie interesującego połączenia jest trudne. Storna nie posiada możliwości wystawiania opinii ani komentarzy przewoźnikom, a takie informacje mogły by być przydatne.
3. Analiza wymagań użytkownika (wstępna)
Główne funkcjonalności portalu:
zarejestrowanie nowej firmy przewozowej + podstawowych informacji adresowych
dodanie kursów oferowanych przez tą firmę
możliwość wyszukiwania kursów filtrując po przystankach z miejscowości A do B
możliwość dodania komentarzy dla poszczególnych firm przez użytkowników
moduł rejestracji użytkowników
dodawanie cen biletów na poszczególnych trasach
powiadomienia mailowe odnośnie nowych przewoźników w regionie bądź zmian w rozkładach jazdy
4. Określenie scenariuszy użycia
Scenariusze dla Użytkownika
Wyszukanie połączenia:
Wejście na stronę
Przejście na zakładkę 'Szukaj busa'
Wprowadzenie danych przystanku początkowego i końcowego
Podanie godziny odjazdu lub przyjazdu
Uruchomienie wyszukiwania i przeglądnięcie wyników
Założenie konta:
Wejście na stronę
Kliknięci w panel 'Rejestracja!'
Wprowadzenie danych użytkownika
Potwierdzenie założenia konta
Scenariusze dla Użytkownika posiadającego firmę
Założenie firmy
Wejście na stronę
Zalogowanie się
Kliknięcie w panel 'Dodaj firmę'
Wprowadzenie nazwy firmy oraz maila firmowego
Potwierdzenie dodania firmy
Wprowadzenie trasy
Wejście na stronę
Zalogowanie się
Wybranie zakładki 'Dodaj linię'
Wprowadzenie kolejnych przystanków, czasów odjazdu oraz cen biletów
Potwierdzenie dodania linii
Zarządzanie trasami
5. Identyfikacja funkcji
Baza danych będzie przechowywać informacje o:
6. Analiza hierarchii funkcji projektowanej aplikacji (FHD – Functional Hierarchy Diagram)
7. Budowa i analiza diagramu przepływu danych (DFD – Data Flow Diagram)
8. Wybór encji (obiektów) i ich atrybutów
@Entity
@Table(name="COMPANIES")
@NamedQueries({
@NamedQuery(name="findCompanyByName", query="SELECT c FROM Company c WHERE c.name = :name"),
@NamedQuery(name="findCompanyByOwnerName", query="SELECT c FROM Company c WHERE c.owner.name = :name")
})
public class Company implements Serializable {
private static final long serialVersionUID = 5074588959885714521L;
@GeneratedValue(strategy=GenerationType.AUTO)
private long companyid;
@Column(nullable=false)
private String name;
@Column(nullable=false)
private String mail;
@ManyToOne
private User owner;
@OneToMany(mappedBy="company", targetEntity=Opinion.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private Set<Opinion> opinions;
@OneToMany(mappedBy="owner", targetEntity=Course.class, cascade=CascadeType.ALL, fetch=FetchType.LAZY)
private Set<Course> courses;
}
@Entity
@Table(name="COURSES")
@NamedQuery(name="findCourseByCompany", query="SELECT c FROM Course c WHERE c.owner.name = :name")
public class Course implements Serializable {
private static final long serialVersionUID = 3008699718560976506L;
@GeneratedValue(strategy=GenerationType.AUTO)
private long courseid
@OneToOne
private Company owner;
@Column(nullable=true)
private String description;
@OneToMany(mappedBy="course", targetEntity=Stop.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private List<Stop> stops;
}
@Entity
@Table(name="OPINIONS")
@NamedQuery(name="findOpinionByCompany", query="SELECT o FROM Opinion o WHERE o.company.name = :name")
public class Opinion implements Serializable {
private static final long serialVersionUID = 2475121744579807544L;
@GeneratedValue(strategy=GenerationType.AUTO)
private long opinionid;
@ManyToOne
private Company company;
@Column(nullable=true)
private boolean positive;
@Column(nullable=true)
private String description;
}
@Entity
@Table(name="PLACES")
@NamedQueries({
@NamedQuery(name="findPlaceByName", query="SELECT p FROM Place p WHERE p.city = :city AND p.name = :name"),
@NamedQuery(name="autocompletePlace", query="SELECT p FROM Place p WHERE p.city LIKE :city AND p.name LIKE :name"),
@NamedQuery(name="autocompletePlaceByCity", query="SELECT p FROM Place p WHERE p.city LIKE :city"),
@NamedQuery(name="autocompletePlaceByName", query="SELECT p FROM Place p WHERE p.name LIKE :name")
})
public class Place implements Serializable {
private static final long serialVersionUID = 7561920390812143011L;
@GeneratedValue(strategy=GenerationType.AUTO)
private long placeid;
@Column(nullable=false)
private String city;
@Column(nullable=false)
private String name;
@Column(nullable=true)
private BigDecimal lon;
@Column(nullable=true)
private BigDecimal lat;
}
@Entity
@Table(name="STOPS")
@NamedQuery(name="findStopByPlace", query="SELECT s FROM Stop s WHERE s.place.city = :city and s.place.name = :name")
public class Stop implements Serializable {
private static final long serialVersionUID = 2015220800633676479L;
@GeneratedValue(strategy=GenerationType.AUTO)
private long stopid;
@ManyToOne
private Course course;
@OneToOne
private Place place;
@Column(nullable=false)
private int orderNumber;
@Column(nullable=true)
private BigDecimal cost;
@Column(nullable=true)
private String hours;
}
@Entity
@Table(name="USERS")
public class User implements Serializable {
private static final long serialVersionUID = 8651753619995718647L;
@GeneratedValue(strategy=GenerationType.AUTO)
private long userid;
@Column(nullable=false)
private String name;
@Column(nullable=false)
private String password;
@Column(nullable=false)
private String mail;
@Column(nullable=false)
private int role = 1;
@OneToMany(mappedBy="owner", targetEntity=Company.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private Set<Company> companies;
}
9. Projektowanie powiązań (relacji) pomiędzy encjami (ERD)
10. Projekt diagramów STD (State Transition Diagram)
11. Projektowanie tabel, kluczy, kluczy obcych, powiązań między tabelami, indeksów
CREATE TABLE companies
(
id BIGINT NOT NULL,
"name" CHARACTER VARYING(255) NOT NULL,
mail CHARACTER VARYING(255) NOT NULL,
owner_id BIGINT,
CONSTRAINT companies_pkey PRIMARY KEY (id),
CONSTRAINT fk51e1f1bbedbce178 FOREIGN KEY (owner_id)
REFERENCES users (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE courses
(
id BIGINT NOT NULL,
description CHARACTER VARYING(255),
hours CHARACTER VARYING(255),
owner_id BIGINT,
CONSTRAINT courses_pkey PRIMARY KEY (id),
CONSTRAINT fk63e4af986eae0d5e FOREIGN KEY (owner_id)
REFERENCES companies (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE opinions
(
id BIGINT NOT NULL,
positive BOOLEAN,
description CHARACTER VARYING(255),
company_id BIGINT,
CONSTRAINT opinions_pkey PRIMARY KEY (id),
CONSTRAINT fk176ead31d905f754 FOREIGN KEY (company_id)
REFERENCES companies (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE places
(
id BIGINT NOT NULL,
city CHARACTER VARYING(255) NOT NULL,
"name" CHARACTER VARYING(255) NOT NULL,
lon NUMERIC(19,2),
lat NUMERIC(19,2),
CONSTRAINT places_pkey PRIMARY KEY (id)
)
CREATE TABLE stops
(
id BIGINT NOT NULL,
ordernumber INTEGER NOT NULL,
"cost" NUMERIC(19,2),
lag NUMERIC(19,2),
place_id BIGINT,
course_id BIGINT,
CONSTRAINT stops_pkey PRIMARY KEY (id),
CONSTRAINT fk4b9009137509994 FOREIGN KEY (place_id)
REFERENCES places (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk4b90091894e45e0 FOREIGN KEY (course_id)
REFERENCES courses (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE users
(
id BIGINT NOT NULL,
"name" CHARACTER VARYING(255) NOT NULL,
"password" CHARACTER VARYING(255) NOT NULL,
mail CHARACTER VARYING(255) NOT NULL,
"role" INTEGER NOT NULL,
CONSTRAINT users_pkey PRIMARY KEY (id)
)
CREATE SEQUENCE hibernate_sequence
INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1;
12. Analiza zależności funkcyjnych i normalizacja tabel
Wydaje się, że baza danych spełnia założenia 3NF. Wynika to z faktu, że przechowywane w niej dane są istnotnie atomiczne - z punktu widzenia implementacji projektu. W każdej tabeli atrybuty są w pełni bezpośrednio zależne od klucza głównego. Generalnie baza była projektowana tak by przy możlie maksymalnej funkcjonalności tabel, zapewnić trzecią postać normalną.
13. Projektowanie operacji na danych
Kwerendy i zapytania wynikają z mechanizmu mapowania obiektowo relacyjnego w j2ee i są poniekąd dostarczone przez klasę EntityManager standardu JPA Hibernate. Pozostałe zapytania w celu optymalizacji wydajności pracy aplikacji zrealizowane zostały jako NamedQuery - zapytania prekompilowane i stworzone przy użyciu składni HQL - Hibernate Query Language. Można je zobaczyć nad kodem encji do których przynależą.
RAPORT KOŃCOWY
14. Stos technologiczny
Aplikacja zrealizowana jest na bazie wzorca projektowego MVC (model widok kotroller).
Sklada sie z 3 wyraznie wyrożnionych warstw:
baza danych - Postrgres 8.3, Mapowanie relacyjno obiektowe standard Java JPA Persistence
logika biznesowa - Zrealizowana za pomocą technologii EJB 3.0
widok - Zrealizowany za pomocą JSF (java server faces 1.2) z nakładką jQery oraz jQueryUI
15. Implementacja bazy danych
Patrz punkt 11. Projektowanie tabel, kluczy, kluczy obcych, powiązań między tabelami, indeksów.
16. Zdefiniowanie interfejsów do prezentacji, edycji i obsługi danych
-formularz rejestracji użytkownika
-formularz logowania użytkownika
-formularz zakładania firmy przez użytkownika
-formularz edycji danych użytkownika
-formularz dodawania komentarzy
-formularz dodawania połączenia
-formularz wyszukiwania połączeń
17. Zdefiniowanie dokumentów do przetwarzania i prezentacji danych
-prezentacja wyników wyszukiwania
-prezentacja dodanej trasy
-prezentacja aktualnosci
-prezentacja komentarzy