Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Poprzednia wersja
Nowa wersja
Poprzednia wersja
pl:dydaktyka:ztb:2010:projekty:z_impetem:start [2010/06/01 18:25]
ztb2010
pl:dydaktyka:ztb:2010:projekty:z_impetem:start [2019/06/27 15:50] (aktualna)
Linia 3: Linia 3:
 [[kisielkis@wp.pl|Kisielewski Marcin]], [[lukaszkokosza@o2.pl|Kokosza Łukasz]], [[mat.jop@gmail.com|Jop Mateusz]] [[kisielkis@wp.pl|Kisielewski Marcin]], [[lukaszkokosza@o2.pl|Kokosza Łukasz]], [[mat.jop@gmail.com|Jop Mateusz]]
  
-==== Wprowadzenie ====+
 Projekt ten jest częścią bazodanową projektu gry internetowej,​ który realizujemy na przedmiocie Technologie i Programowanie WWW. Projekt ten jest częścią bazodanową projektu gry internetowej,​ który realizujemy na przedmiocie Technologie i Programowanie WWW.
  
Linia 203: Linia 203:
 ==== Diagram struktury bazodanowej ==== ==== Diagram struktury bazodanowej ====
  
-{{:​pl:​dydaktyka:​ztb:​2010:​projekty:​z_impetem:​baza.png|}}+{{:​pl:​dydaktyka:​ztb:​2010:​projekty:​z_impetem:​bazaNowa.jpeg|}}
  
  
Linia 319: Linia 319:
 | Specjalne wymagania | Jeden użytkownik może tylko jeden raz wypełnić jedną ankietę | | Specjalne wymagania | Jeden użytkownik może tylko jeden raz wypełnić jedną ankietę |
 | Notatki i uwagi | Uwaga na poprawne odpowiedzi. System powinien w możliwie łatwy sposób sprawdzać poprawność ankiet bez udziału administratorów | | Notatki i uwagi | Uwaga na poprawne odpowiedzi. System powinien w możliwie łatwy sposób sprawdzać poprawność ankiet bez udziału administratorów |
 +
 +
 +==== Encje podstawowe ====
 +
 +**Użytkownik** – każdy gracz będzie posiadał swój unikalny identyfikator będący kluczem głównym określonym jako id_uzytkownika oraz takie pola jak login, hasło, adres e mail, data urodzenia, zdobyte punkty oraz zestaw kluczy obcych, które są kluczami głównymi innych encji takich jak reklama, ankieta, świat, bagaż, adres. ​
 +
 +**Swat** – obecnie przyjęliśmy ze będą w naszej grze dwa światy, dlatego encja ta posiada identyfikator będący kluczem głównym. W tym obiekcie będziemy pamiętać aktualne położenie na mapie gry, Obiekt ten będzie pamiętał identyfikatory aktualnie toczonych bitew. Bitwy będą mogły odbywać się pomiędzy dwoma graczami, albo graczem i komputerem. Pamiętane są również klucze obce  encji pogoda, artefakt oraz bitwy.
 +
 +**BitwaUzytkownikow** oraz BitwaPrzeciwnik są to dwie encje, które zapamiętują ​    ​aktualne położenie na mapie świata, oraz posiadają identyfikatory dwóch toczących walkę ze sobą użytkowników,​ lub walkę użytkownika z komputerowym stworem. Przyjęliśmy założenie,​ że klucze główne tych dwóch encji mają wartości unikalne.
 +
 +**Adres** – encja przechowująca informacje dotyczące adresu zamieszkania użytkownika. Zawiera takie pola jak: ulica, numer domu, miejscowość oraz klucz obcy do encji KodPocztowy.
 +
 +**Reklama** – obiekt zawierający pola takie jak identyfikator użytkownika,​ nazwa reklamy, opis oraz czy jest ona widoczna czy nie. Zdefiniowany tez jest klucz główny id_reklamy.
 +
 +**Bagaz** – użytkownik będzie mógł zbierać różne artefakty i ta encja służy do ich przechowywania. Zawarte tu będą informacje dotyczące doświadczenia,​ zbroi, broni.
 +
 +==== Szata graficzna ====
 +
 +W naszym projekcie, aby w łatwy sposób kontrolować i formatować wygląd stron WWW zastosujemy kaskadowe arkusze stylów. CSS jest sposobem na oddzielenie strukturalnych elementów witryny od jej prezentacji. Pozwala na zmianę architektury dokumentów i ograniczenie ich rozmiarów do minimum, zachowując jednocześnie pełną kontrolę nad wyglądem witryny. Użytkownik może zmieniać rozmiar i kolor czcionki oraz inne elementy wyglądu z jednego pliku CSS. Wygląd witryny która nie została zaprojektowane w CSS może się różnić między przeglądarkami. CSS ułatwia normalizację witryny i zbliżenie jej wyglądu do zamierzonego. Zaletą tej techniki jest również to, że jest tylko jeden arkusz, który zarządza wszystkimi stronami witryny. CSS zapewnia jednorodność w wyglądzie strony. Arkusze tworzą efekt kaskadowy, tzn. komunikują się z przeglądarką w celu stworzenia jednolitego formatu dla użytkownika. Absolutnie nie trzeba się obawiać stosowania CSS, ponieważ nie powodują one błędów w przeglądarkach,​ które ich nie obsługują. Nigdy nie zdarzy się tak, aby strona w ogóle nie została wyświetlona,​ ponieważ korzysta z CSS. Jeżeli przeglądarka nie obsługuje stylów, po prostu je pominie.
 +
 +====  Domena i serwer ====
 +
 +Do umieszczenia strony w internecie będzie potrzebny dobry serwer, który zapewni odpowiedni hosting portalu. Aby uzyskać odpowiedni „prestiż” w sieci będzie również potrzebna reprezentatywna domena. Jako domenę wybraliśmy „.pl”, a hosting zamierzamy rozpocząć na portalu „nazwa.pl”. Roczny koszt utrzymania będzie wynosił ok. 300zł. Na początek jest możliwość wykupienia w promocji serwera za 100zł na pół roku i w razie powodzenia projektu możliwość przedłużenia współpracy
 +
 +==== Koszta utrzymania ====
 +
 +Roczny koszt utrzymania hostingu ​ i domeny będzie wynosił ok. 300zł. Na początek jest możliwość wykupienia w promocji serwera za 100zł na pół roku i w razie powodzenia projektu możliwość ​   przedłużenia współpracy. ​
 +
 +==== Postacie normalne ====
 +
 + ​**Pierwsza postać normalna**  ​
 +Baza danych spełniająca pierwszą postać normalną musi składać się z tabel, które zawierają dane wzajemnie powiązane, musi zawierać unikalne powiązanie pewnych grup danych oraz muszą byc wskazane klucze główne poszczególnych tabel. Nasza baza danych spełnia pierwszą postać normalną ponieważ wszystkie tabele posiadają ściśle ze sobą powiązane dane np. tabela user_table posiada informacje na temat użytkownika takie jak jego imie, nazwisko, adres, adres e-mail. Wszystkie dane w tej tabeli są ze sobą ścisle powiązanie,​ nie ma niepotrzebnych lub powielających się elementów. Po rozdzieleniu danych pomiędzy tabele należało je powiązać ze sobą za pomocą unikalnych wartości zwanych identyfikatorami,​ dlatego każda tabela w naszej bazie posiada klucz główny, np. tabela abstractuser_table posiada identyfikator o nazwie id. Należy pamiętać, że stosowanie dodatkowych identyfikatorów jest korzystne ze względu na wyższą efektywność przeszukiwania danych.
 +
 + ​**Druga postać normalna**  ​
 +Pierwsza postać normalna wymagała wskazania klucza głównego w każdej z tabel bazy danych. Klucz główny może się składać z jednej lub wielu kolumn. Pełni on funkcję unikalnego identyfikatora rekordu. Zgodnie z drugą postacią normalną nie mogą istnieć żadne nawet częściowe zależności pomiędzy jakimikolwiek kolumnami wchodzącymi w skład klucza głównego. Nasza baza danych spełnia drugą postać normalną ponieważ w żadnej tabeli nie wystepuje pola, które by zależały od innego pola tej tabeli. Przykładowo druga postać normalna by nie była spełniona jeżeli np. posiadalibyśmy tabelę w której mielibyśmy dwa klucze główne idUser oraz idWorld. Najlepszym sposobem na rozwiązanie tego problemu byloby rozdzielenie danych na dwie tabele oraz utworzenie trzeciej, która będzie zawierała identyfikatory użytkownika oraz świata.
 +
 + ​**Trzecia postać normalna**  ​
 +Trzecia postać normalna ​ ma charakter opcjonalny a jej stosowanie w znacznej mierze jest uzależnione od okoliczności. Tabele znajdują się w trzeciej postaci normalnej tylko wtedy, gdy spełniają następujące warunki: tablele znajdują się w drugiej postaci normalnej oraz wszystkie pola, które nie należa do klucza głównego są od niego zależne. Zależność pól spoza klucza głównego dotyczy oczywiście zawartych w nim danych. Nasza baza danych spełnia trzecia postać normalna ponieważ tabela address_user zawiera pola takie jak ulica, numer domu, miasto, państwo i idPostcode, który jest identyfikatorem tabeli postcode_table zawierającej kody pocztowe miejscowości. Widać tutaj, że dane dotyczące adresu śa ścisle związane z kodem pocztowym. Kiedy wysyła sie list to nazwa ulicy, numer domu, miejscowość i wlaśnie kod pocztowy wystarczą do odnalezienia własciwego adresu. Zaletą trzeciej postaci normalnej jest spójność danych. Wydobywanie odpowiednich danych z bazy danych zgodnej z trzecia postacią normalną trwa dlużej. W przypadku małych baz różnice są minimalne, jednak z punktu widzenia użytkowników baz danych z tysiącami lub milionami rekordów takaie spowolnienie może mieć olbrzymie znaczenie. ​
 +
 +
 +
 +
 +
 +==== Implementacja ====
 +
 +
 +**pom.xml**
 +<code xml>
 +<project xmlns="​http://​maven.apache.org/​POM/​4.0.0"​ xmlns:​xsi="​http://​www.w3.org/​2001/​XMLSchema-instance"​
 +  xsi:​schemaLocation="​http://​maven.apache.org/​POM/​4.0.0 http://​maven.apache.org/​maven-v4_0_0.xsd">​
 +  <​modelVersion>​4.0.0</​modelVersion>​
 +  <​groupId>​org</​groupId>​
 +  <​artifactId>​gra</​artifactId>​
 +  <​packaging>​war</​packaging>​
 +  <​version>​0.0.1-SNAPSHOT</​version>​
 +  <​name>​gra Maven Webapp</​name>​
 +  <​url>​http://​maven.apache.org</​url>​
 +   <​dependencies>​
 +    <​dependency>​
 +      <​groupId>​junit</​groupId>​
 +      <​artifactId>​junit</​artifactId>​
 +      <​version>​3.8.1</​version>​
 +      <​scope>​test</​scope>​
 +    </​dependency>​
 +    <​dependency>​
 +    <​groupId>​org.hibernate</​groupId>​
 +    <​artifactId>​hibernate</​artifactId>​
 +    <​version>​3.2.6.ga</​version>​
 +    </​dependency>​
 +    <​dependency>​
 +    <​groupId>​javax.transaction</​groupId>​
 +    <​artifactId>​jta</​artifactId>​
 +    <​version>​1.1</​version>​
 +    <​type>​jar</​type>​
 +    <​scope>​compile</​scope>​
 +    </​dependency>​
 +   </​dependencies>​
 +  <​build>​
 +    <​finalName>​strona_hibernate_v1</​finalName>​
 +  </​build>​
 +</​project>​
 +  ​
 +</​code>​
 +
 +**hibernate.cfg.xml**
 +
 +<code xml>
 +<?xml version="​1.0"​ encoding="​UTF-8"?>​
 +<​!DOCTYPE hibernate-configuration PUBLIC
 + "​-//​Hibernate/​Hibernate Configuration DTD 3.0//​EN"​
 + "​http://​hibernate.sourceforge.net/​hibernate-configuration-3.0.dtd">​
 +
 +<​hibernate-configuration>​
 +    <​session-factory>​
 +    ​
 +        <​property name="​hibernate.connection.driver_class">​org.postgresql.Driver</​property>​
 +        <​property name="​hibernate.connection.url">​jdbc:​postgresql://​localhost/​postgres</​property>​
 +        <​property name="​hibernate.connection.username">​postgres</​property>​
 +        <​property name="​connection.password">​passwd</​property>​
 +        ​
 +        <​property name="​hibernate.dialect">​org.hibernate.dialect.PostgreSQLDialect</​property>​
 +        <​property name="​hibernate.connection.pool_size">​0</​property>​
 +        ​
 +        <​property name="​show_sql">​true</​property>​
 +        <​property name="​format_sql">​true</​property>​
 +        <​property name="​hibernate.hbm2ddl.auto">​update</​property>​
 +        ​
 +        <!-- mapping resources -->
 +        <mapping resource="​User.hbm.xml"/>​
 +        <mapping resource="​Address.hbm.xml"/>​
 +        <mapping resource="​World.hbm.xml"/>​
 +        <mapping resource="​Weather.hbm.xml"/>​
 + <​mapping resource="​Artefact.hbm.xml"/>​
 + <​mapping resource="​Account.hbm.xml"/>​
 + <​mapping resource="​Luggage.hbm.xml"/>​
 + <​mapping resource="​Advert.hbm.xml"/>​
 + <​mapping resource="​Battle.hbm.xml"/>​
 +     
 +    </​session-factory>​
 +</​hibernate-configuration>​
 +
 +
 +</​code>​
 +
 +**user.hbm.xml**
 +<code xml>
 +
 +<?xml version="​1.0"?>​
 +<​!DOCTYPE hibernate-mapping PUBLIC
 + "​-//​Hibernate/​Hibernate Mapping DTD 3.0//​EN"​
 + "​http://​hibernate.sourceforge.net/​hibernate-mapping-3.0.dtd">​
 +<​hibernate-mapping package="​org.lukasz.gra.model">​
 +  <class name="​AbstractUser"​ table="​abstractuser_table">​
 +   
 + ​ <​id name="​id">​
 +  <​generator class="​native"/>​
 +  </​id>​
 + 
 +  <​property name="​login"​ type="​string"/>​
 +  <​property name="​password"​ type="​string"/>​
 +  <​joined-subclass name="​User"​ table="​user_table">​
 +  <key column="​id"/>​
 +  <​property name="​name"​ type="​string"/>​
 +  <​property name="​surname"​ type="​string"/>​
 +  <​component name="​email"​ class="​Email">​
 +  <​property name="​addressemail"​ type="​string"/>​
 +  </​component>​
 +  <​many-to-one name="​address"​ class="​org.lukasz.gra.model.Address"​ column="​idAddress"​ cascade="​all"/>​
 + 
 +  <​many-to-one name="​account"​ class="​org.lukasz.gra.model.Account"​ cascade="​all"​ unique="​true"/>​
 +  <​many-to-one name="​luggage"​ class="​org.lukasz.gra.model.Luggage"​ cascade="​all"​ unique="​true"/>​
 +   
 +  <set name="​advertSet"​ table="​advert_user"​ cascade="​all">​
 +            <key column="​idUser"​ />
 +         <​many-to-many column="​idAdvert"​ unique="​true"​ class="​org.lukasz.gra.model.Advert"​ />
 +    </​set>​
 +  </​joined-subclass>​
 +  </​class>​
 +</​hibernate-mapping>​
 +
 +</​code>​
 +
 +**user.java**
 +
 +<code java>
 +package org.lukasz.gra.model;​
 +
 +import java.util.HashSet;​
 +import java.util.Set;​
 +
 +public class User extends AbstractUser{
 + private String name;
 + private String surname;
 + private Address address;
 + private Email email;
 + private Account account;
 + private Luggage luggage;
 +
 + private Set<​Advert>​advertSet = new HashSet<​Advert>​(0);​
 +
 +
 + public Set<​Advert>​ getAdvertSet() {
 + return advertSet;
 + }
 + public void setAdvertSet(Set<​Advert>​ advertSet) {
 + this.advertSet = advertSet;
 + }
 + public Account getAccount() {
 + return account;
 + }
 + public void setAccount(Account account) {
 + this.account = account;
 + }
 + public Luggage getLuggage() {
 + return luggage;
 + }
 + public void setLuggage(Luggage luggage) {
 + this.luggage = luggage;
 + }
 + public String getName(){
 + return name;
 + }
 + public void setName(String name){
 + this.name = name;
 + }
 +
 + public String getSurname(){
 + return surname;
 + }
 + public void setSurname(String surname){
 + this.surname = surname;
 + }
 +
 + public Address getAddress(){
 + return address;
 + }
 + public void setAddress(Address address){
 + this.address = address;
 + }
 +
 + public Email getEmail(){
 + return email;
 + }
 + public void setEmail(Email email){
 + this.email = email;
 + }
 +
 + public User(){
 + super();
 + }
 + public User(String login, String password, String name, String surname, Address address, Email email, Account account, Luggage luggage, Set<​Advert>​ advertSet){
 + super(login,​password);​
 + this.name = name;
 + this.surname = surname;
 + this.address = address;
 + this.email = email;
 + this.account = account;
 + this.luggage = luggage;
 + this.advertSet = advertSet;
 + }
 +}
 +</​code>​
 +
 +**Dao.java**
 +
 +<code java>
 +package org.lukasz.gra.persistence;​
 +import java.util.logging.Level;​
 +import java.util.logging.Logger;​
 +
 +import org.hibernate.HibernateException;​
 +import org.hibernate.Session;​
 +import org.hibernate.SessionFactory;​
 +
 +import org.hibernate.cfg.Configuration;​
 +
 +public class Dao {
 +
 + private static final Logger log = Logger.getAnonymousLogger();​
 + @SuppressWarnings("​unchecked"​)
 + private static final ThreadLocal session = new ThreadLocal();​
 + private static final SessionFactory sessionFactory =
 + new Configuration().configure().buildSessionFactory();​
 +
 + protected Dao () {
 + }
 +
 + @SuppressWarnings("​unchecked"​)
 + public static Session getSession() {
 + Session session = (Session) Dao .session.get();​
 + if (session == null) {
 + session = sessionFactory.openSession();​
 + Dao .session.set(session);​
 + }
 + return session;
 + }
 + protected void begin() {
 + getSession().beginTransaction();​
 + }
 + protected void commit() {
 + getSession().getTransaction().commit();​
 + }
 +
 + @SuppressWarnings("​unchecked"​)
 + protected void rollback() {
 + try {
 + getSession().getTransaction().rollback();​
 + } catch( HibernateException e ) {
 + log.log(Level.WARNING,"​Cannot rollback",​e);​
 + }
 + try {
 + getSession().close();​
 + } catch( HibernateException e ) {
 + log.log(Level.WARNING,"​Cannot close",​e);​
 + }
 + Dao .session.set(null);​
 + }
 + @SuppressWarnings("​unchecked"​)
 + public static void close() {
 + getSession().close();​
 + Dao .session.set(null);​
 + }
 +}
 +</​code>​
 +
 +**userDao.java**
 +
 +<code java>
 +
 +package org.lukasz.gra.persistence;​
 +//import java.util.HashSet;​
 +//import java.util.List;​
 +//import java.util.Set;​
 +import org.hibernate.HibernateException;​
 +import org.hibernate.Query;​
 +import org.lukasz.gra.model.User;​
 +
 +public class UserDao extends Dao{
 + public void add(User user){
 + try {
 + begin();
 + getSession().save(user);​
 + commit();​
 + } catch (HibernateException e) {
 + System.err.println("​Error while adding user: " + e);
 + rollback();​
 + }
 + }
 + public void delete(Integer id){
 + try {
 + begin();
 + getSession().delete((User)getSession().get(User.class,​ id));
 + } catch (HibernateException e) {
 + System.err.println("​Error while getting list of users " + e);
 + rollback();​
 + } finally {
 + commit();​
 + }
 + }
 +
 + public void update(User user){
 + try {
 + begin();
 + getSession().update(user);​
 + } catch (HibernateException e){
 + System.err.println("​Error while updating user " + e);
 + rollback();​
 + } finally {
 + commit();​
 + }
 + }
 + public User get(Integer id){
 + try {
 + begin();
 + User user = (User) getSession().get(User.class,​ id);
 + return user;
 + } catch (HibernateException e) {
 + System.err.println("​Error while getting user " + e);
 + rollback();​
 + return null;
 + } finally {
 + commit();​
 + }
 + }
 +
 + public User get(String login){
 + try {
 + begin();
 + Query q = getSession().createQuery("​from User where login = :​login"​).setString("​login",​ login);
 + User user = (User) q.uniqueResult();​
 + return user;
 + } catch (HibernateException e) {
 + System.err.println("​Error while getting user " + e);
 + rollback();​
 + return null;
 + } finally {
 + commit();​
 + }
 + }
 + public boolean checkPassword(String login, String password){
 +
 + User u = new User();
 + try {
 + begin();
 + Query q = getSession().createQuery("​from User where login= :​login"​).setString("​login",​ login);
 + u = (User) q.uniqueResult();​
 + commit();​
 + } catch (HibernateException e) {
 + System.err.println("​Error while checking password: " + e);
 + rollback();​
 + return false;
 + }
 + if (u==null) return false;
 + if (u.getPassword().equals((password))) ​
 + return true;
 + else return false;
 + }
 +
 +
 +}
 +
 +</​code>​
 +
 +
 +
 +
 +==== Literatura ====
 +
 +  * "Java - tworzenie aplikacji sieciowych za pomocą Springa, Hibernate i Eclipse",​ Anil Hemrajani, Helion 2007
 +  * "Od podstaw SQL", P. Wilton, J. Colby Helion 2006
 +  * "​Hibernate od Nowicjusza do Profesjonalisty",​ D. Minter, J. Linwood, PowerNet 2007
 +  * "JSP, servlety i strony WWW", , Orelly 2006
 +  * Opracowania własne z poprzednich projektów informatycznych
pl/dydaktyka/ztb/2010/projekty/z_impetem/start.1275409515.txt.gz · ostatnio zmienione: 2019/06/27 15:56 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0