Ciele

  1. Oboznámiť sa s tvorbou aplikácií komunikujúcich s databázovým systémom.
  2. Oboznámiť sa so základmi jazyka SQL.
  3. Implementovať funkčnosť pre prácu so zoznamom najlepších výsledkov uložených v databáze.

Úvod

    Hlavným cieľom dnešného cvičenia je rozšírenie projektu o prácu s databázovým systémom. Pre naše potreby bol zvolený jednoduchý databázový systém Derby (Java DB), ktorý je implementovaný v jazyku Java. Napriek tomu nie je implementácia hry viazaná na tento systém a je možné použiť aj iný databázový systém (PostgreSQL, MySQL, HSQL a podobne).

Postup

  1. Pre realizáciu cieľov dnešného cvičenia bude potrebné rozšíriť implementovaný systém podľa nasledujúceho modelu.
    Obr.: : Diagram tried aplikácie Minesweeper (na konci cvičenia 12)
    Úloha: Pridajte súbor DatabaseSetting.java do projektu hry Minesweeper. Uvedená trieda má definované konštanty obsahujúce konfiguračné údaje pre vytvorenie spojenia na databázový systém Derby ako aj údaje potrebné pre prácu s databázou (SQL príkazy).
  2. V tomto kroku je potrebné rozšíriť triedu BestTimes tak, aby ukladala najlepšie skóre do databázy v prípade úspešného ukončenia hry a získavala toto skóre z databázy v prípade požiadavky na jeho zobrazenie.
    Úloha: V triede BestTimes definujte súkromnú metódu void insertToDB(PlayerTime playerTime), ktorá uloží objekt triedy PlayerTime do databázy.
    Realizácia tejto metódy bude pozostávať z nasledujúcich krokov:
    • Vytvorenie spojenia na databázový server so získaním objektu typu Connection. Trieda ovládača pre pripojenie na databázový server je určená hodnotou konštanty DatabaseSetting.DRIVER_CLASS. URL pre pripojenie na databázu je uvedené v hodnote konštanty DatabaseSetting.URL, meno a heslo v konštantách DatabaseSetting.USER a DatabaseSetting.PASSWORD.
      
      Class.forName(DatabaseSetting.DRIVER_CLASS);
      Connection connection = DriverManager.getConnection(DatabaseSetting.URL,
                                     DatabaseSetting.USER, DatabaseSetting.PASSWORD);
      
    • Vytvorenie databázovej tabuľky player_time v prípade, že ešte takáto tabuľka nie je vytvorená. Ak použijeme SQL príkaz CREATE TABLE nad tabuľkou, ktorá už existuje, vznikne výnimka. Za tohto predpokladu môže byť implementácia nasledovná:
      
      Statement stm = connection.createStatement();
      try {
          stm.executeUpdate(DatabaseSetting.QUERY_CREATE_BEST_TIMES);
      } catch (Exception e) {
          //do not propagate exception, table may already exist
      }
      stm.close();
      
      Pre vytvorenie tabuľky je použitý nasledujúci príkaz jazyka SQL (Trieda DatabaseSetting, konštanta QUERY_CREATE_BEST_TIMES).
      
      CREATE TABLE player_time (name VARCHAR(128) NOT NULL, best_time INT NOT NULL)
      
    • Zápis mena hráča a jeho času do databázy. Pre realizáciu tejto úlohy je možné použiť objekt typu PreparedStatement nasledovne:
      
      PreparedStatement pstm = connection.prepareStatement(DatabaseSetting.QUERY_ADD_BEST_TIME);
      pstm.setString(1, playerTime.getName());
      pstm.setInt(2, playerTime.getTime());
      pstm.execute();
      pstm.close();
      
      SQL príkaz pre uloženie mena a času hráča do tabuľky je nasledovný (trieda DatabaseSetting, konštanta QUERY_ADD_BEST_TIME):
      
      INSERT INTO player_time (name, best_time) VALUES (?, ?)
      
    • Uzatvorenie spojenia na databázu connection.close().
    • Ošetrenie vzniku výnimky v prípade práce s databázovým serverom. Pri vzniku výnimky nech je na konzolu vypísaný text obsahujúci aj opis chyby poskytnutý ovládačom databázového systému. Text bude v tvare (premenná e je objektom výnimky):
      
      "Exception occured during saving high score to database: " + e.getMessage()
      
    Úloha: V triede BestTimes definujte súkromnú metódu void selectFromDB(), ktorá zabezpečí vytvorenie objektov typu PlayerTime s údajmi získanými z databázy a ich uloženie do zoznamu v členskej premennej playerTimes.
    Realizácia metódy bude pozostávať z nasledujúcich krokov:
    • Získanie objektu typu Connection , ktorý reprezentuje spojenie na databázový server.
      
      Class.forName(DatabaseSetting.DRIVER_CLASS);
      Connection connection = DriverManager.getConnection(DatabaseSetting.URL,
      DatabaseSetting.USER, DatabaseSetting.PASSWORD);
      
    • Vykonanie SQL príkazu SELECT nad databázovým serverom. Výsledkom je objekt typu ResultSet umožňujúci prechod v zozname získaných záznamov z databázy. Realizácia bude nasledujúca:
      
      Statement stm = connection.createStatement();
      ResultSet rs = stm.executeQuery(DatabaseSetting.QUERY_SELECT_BEST_TIMES);
      
      SQL príkaz pre získanie mien a časov hráčov je nasledovný (trieda DatabaseSetting, konštanta QUERY_SELECT_BEST_TIMES):
      
      SELECT name, best_time FROM player_time
      
    • Vymazanie zoznamu objektov z členskej premennej playerTimes použitím metódy clear(), aby sme mohli aktualizovať tento zoznam aktuálnymi údajmi.
    • Spracovanie získaných záznamov z databázového servera. Pre každý získaný záznam z databázy bude vytvorený objekt typu PlayerTime s nastavením príslušných údajov. Tento objekt bude pridaný do vytváraného zoznamu playerTimes.
      
      while(rs.next()) {
          PlayerTime pt = new PlayerTime(rs.getString(1), rs.getInt(2));
          playerTimes.add(pt);
      }
      stm.close();
      
    • Uzatvorenie spojenia na databázu connection.close().
    • Ošetrenie vzniku výnimky v prípade práce s databázovým serverom. Pri vzniku výnimky nech je na konzolu vypísaný text obsahujúci aj opis chyby poskytnutý ovládačom databázového servera. Text bude v tvare (premenná e je objektom výnimky):
      
      "Exception occured during loading high score from database: " + e.getMessage()
      
    • Zotrieďte údaje získané z databázy aby zodpovedali poradiu hráčov. Použite statickú metódu sort(List list) triedy java.util.Collections.
    Úloha: Upravte metódu void addPlayerTime(String name, int time) tak, aby bol vytvorený objekt typu PlayerTime uložený do databázy použitím metódy void insertToDB(PlayerTime playerTime).
    Úloha: Upravte metódu String toString() tak, aby sa aktualizoval zoznam časov hráčov PlayerTime v členskej premennej playerTimes podľa stavu v databáze použitím metódy void selectFromDB().
  3. Posledným krokom pre overenie realizovaných úloh je konfigurácia databázového servera Derby a nastavenie a vytvorenie databázy. Databázový systém Derby je súčasťou inštalácie JDK 6.
    Úloha: Nakonfigurujte databázový systém Derby v prostredí Netbeans.
    Zvoľte v menu „Window > Services”. V strome služieb zvoľte uzol „Java DB”. Otvorte kontextové menu a skontrolujte nastavenie pre DB (položka „Properties”). Nastavte adresár inštalácie Derby a adresár kde budú ukladané databázové súbory.
    Úloha: Vytvorte databázu pre hru Minesweeper.
    Vytvorte databázu zvolením položky „Create Database” v kontextovom menu. Napíšte názov databázy, meno používateľa, heslo používateľa.
    Poznámka: Názov databázy, meno a heslo používateľa musí zodpovedať hodnotám uvedeným v triede DatabaseSetting.
    Úloha: Spustite databázový systém.
    Zvoľte v kontextovom menu „Start Server” ak sa tak už nestalo.
    Úloha: Pridajte do classpath ovládač pre prístup k databáze.
    Zvoľte v kontextovom menu nad projektom v záložke „Projects” položku „Properties” a v dialógu „Libraries > Run” pridajte jar súbor s ovládačom derbyclient.jar, ktorý sa nachádza v inštalácii databázového servera Derby.
    Úloha: Spustite hru Minesweeper a otestujte implementovanú funkčnosť.

Zdroje

  1. Zdrojové kódy:

Doplňujúce úlohy

    Úloha: Rozšírte ukladanie časov hráčov o úroveň, v ktorej bol výsledok dosiahnutý (BEGINNER, INTERMEDIATE, EXPERT). Modifikujte triedu BestTimes ako aj databázovú tabuľku player_time.
comments powered by Disqus