C/C++ week November Black Friday
Black Friday je tu! Využij jedinečnou příležitost a získej až 80 % znalostí navíc zdarma! Více zde
Pouze tento týden sleva až 80 % na e-learning týkající se C/C++

Lekce 15 - Diář s databází v Javě

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Datum a čas v Javě 8 - Parsování a porovnávání, jsme si představili ArrayList. Víme, že nám oproti poli umožňuje přidávat nové prvky za běhu programu a nemusíme se starat o jeho velikost. V dnešním tutoriálu si do ArrayListu zkusíme uložit objekty.

Prvně jsem chtěl udělat databázi uživatelů, ale uživatele jsme tu již několikrát měli. Jelikož jsme se nedávno naučili datum a čas, naprogramujeme si diář. Do databáze budeme ukládat jednotlivé záznamy a vždy vypíšeme ten dnešní a zítřejší. Databáze to nebude samozřejmě ta v tom pravém slova smyslu (na to ještě nemáme zkušenosti), ale bude se jednat právě o ArrayList v operační paměti počítače. Bude umožňovat záznamy přidávat, hledat je podle data a mazat podle data a času. Založte si nový projekt, který nepojmenujeme Diar (budeme toto jméno potřebovat pro třídu) ale např. Poznamkovac, to bude jméno naší výsledné aplikace.

Záznam

Prvně si udělejme třídu, jejíž instance budeme ukládat. Nazvěme ji Zaznam. Záznam v diáři se bude vázat k nějakému datu a času. Také bude obsahovat nějaký text. Např.: 12. ledna 2013 - Vyvenčit psa. To je asi vše, třída může vypadat takto:

public class Zaznam {

    private LocalDateTime datumCas;
    private String text;


    public Zaznam(LocalDateTime datumCas, String text) {
        this.datumCas = datumCas;
        this.text = text;
    }

    /**
     * @return the datumCas
     */
    public LocalDateTime getDatumCas() {
        return datumCas;
    }

    /**
     * @param datumCas the datumCas to set
     */
    public void setDatumCas(LocalDateTime datumCas) {
        this.datumCas = datumCas;
    }

    /**
     * @return the text
     */
    public String getText() {
        return text;
    }

    /**
     * @param text the text to set
     */
    public void setText(String text) {
        this.text = text;
    }

    @Override
    public String toString() {
        return datumCas + " " + text;
    }
}

Třída v podstatě slouží jen k záznamu dat a nemá žádné metody (až na konstruktor a toString() a nějaké ty gettery/settery). Funkcionalitu jako takovou ale nenabízí. Bystřejší si jistě všimli, že metoda toString() nijak neformátuje datum a čas. K tomu se později ještě vrátíme.

Databáze

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Protože program bude o něco složitější, rozdělíme ho do více objektů (vrstev). Záznam máme, nyní si vytvoříme objekt Databaze, ve které budou záznamy uloženy. Opět bude mít privátní ArrayList, jako měl Losovac. Ten bude nyní typu Zaznam. Diář bude umožňovat záznamy přidávat, mazat a vyhledávat podle data. K projektu tedy přidáme třídu Databaze. Bude velmi podobná minulému Losovači:

import java.util.ArrayList;

public class Databaze {

    private ArrayList<Zaznam> zaznamy;

    public Databaze() {
        zaznamy = new ArrayList<>();
    }

}

Všimněte si použití "diamond operátoru" při vytváření nové instance ArrayListu. Od Javy 7 nemusíme generický typ uvádět 2x, ale stačí ho uvést pouze při deklaraci proměnné a špičaté závorky můžeme podruhé již ponechat prázdné. Také si řekněme, že kdybychom špičaté závorky nenapsali vůbec a ArrayList deklarovali i inicializovali bez uvedení generického typu, položky by se ukládaly jako typ Object. Museli bychom je vždy na naše Záznamy ručně převádět, dále v seriálu si ukážeme jak by se to dělalo a listy ještě potom potkáte u kolekcí.

Třída Zaznam tedy slouží pouze pro manipulaci s daty. Obsahuje vnitřní kolekci zaznamy, ta se inicializuje v konstruktoru. Mohli bychom použít i inicializaci bez konstruktoru přímo u deklarace ve formě:

private ArrayList<Zaznam> zaznamy = new ArrayList<>();

Dodejme třídě metody pro přidání, vymazání a vyhledání záznamu.

Přidání záznamu by mělo být jasné:

public void pridejZaznam(LocalDateTime datumCas, String text) {
    zaznamy.add(new Zaznam(datumCas, text));
}

Jako druhou metodu přidejme nalezení záznamů v daný den. Metoda bude vracet ArrayList nalezených záznamů, protože jich pro ten den může být v databázi více. Záznamy budeme moci vyhledávat podle data i času nebo jen podle data. Můžeme tak najít záznamy v konkrétní den bez ohledu na to, v jakou jsou hodinu. Podle čeho budeme chtít vyhledávat bude udávat parametr dleCasu typu boolean. Pokud bude false, hledáme jen podle data bez ohledu na čas. ArrayList si nejprve vytvoříme a poté do něj přidáváme záznamy, které odpovídají hledanému datu. Odpovídat musí buď celé datum a čas (pokud hledáme i podle času) nebo jen datum (pokud hledáme jen podle data). Naplněný ArrayList s nalezenými záznamy vrátíme.

public ArrayList<Zaznam> najdiZaznamy(LocalDateTime datum, boolean dleCasu) {
    ArrayList<Zaznam> nalezene = new ArrayList<>();
    for (Zaznam z : zaznamy) {
        if ((dleCasu && z.getDatumCas().equals(datum)) ||
            (!dleCasu && z.getDatumCas().toLocalDate().equals(datum.toLocalDate()))) {
            nalezene.add(z);
        }
    }
    return nalezene;
}

Nakonec přidáme vymazání záznamů v určitou dobu. To provedeme pomocí metody najdiZaznamy() a nalezené záznamy jednoduše proiterujeme a z ArrayListu odstraníme. Budeme mazat podle přesného data i času, 2. parametr u metody najdiZaznamy() bude tedy true:

public void vymazZaznamy(LocalDateTime datum) {
    ArrayList<Zaznam> nalezeno = najdiZaznamy(datum, true);
    for (Zaznam z : nalezeno) {
        zaznamy.remove(z);
    }
}

Diář

Nyní si přidáme k projektu poslední třídu, bude to samotný diář. Nazvěme ji Diar. Ten již bude obsahovat metody pro komunikaci s uživatelem. Všimněte si, jak aplikaci rozdělujeme a jednotlivé její části zapouzdřujeme. ArrayList je zapouzdřen v databázi, která nad ním postavila další metody pro bezpečnou manipulaci s jeho obsahem. Samotnou databázi nyní vložíme do diáře. Tím oddělíme logiku a práci s daty od komunikace s uživatelem a dalšími vstupy/výstupy programu. Třída Diar tedy bude komunikovat s uživatelem a data od něj předá databázi.

Přidejme si privátní instanci databáze, kterou si vytvoříme v konstruktoru. Podobně přidejme i instanci Scanneru, kterou budeme ve třídě potřebovat:

import java.util.Scanner;

public class Diar {

    private Databaze databaze;
    private Scanner sc = new Scanner(System.in, "Windows-1250");

    public Diar() {
        databaze = new Databaze();
    }
}

Třídu Diar dokončíme v příští lekci, Diář s databází v Javě (dokončení), spolu se zprovozněním celé aplikace.


 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
11 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Předchozí článek
Datum a čas v Javě 8 - Parsování a porovnávání
Všechny články v sekci
Objektově orientované programování v Javě
Miniatura
Následující článek
Diář s databází v Javě (dokončení)
Aktivity (10)

 

 

Komentáře
Zobrazit starší komentáře (7)

Avatar
Patrik
Člen
Avatar
Patrik:30.5.2016 20:27

Ahojte :)
Rozumiem tomu správne ??
Ked je :
ArrayList<> x = new ArrayList<>();
Tak medzi <> dosadíme dátový typ primitívny/re­ferenčný.
x = názov premennej.
A čo môže ísť medzi () ???
Prepáčte ak to bolo v článku vysvetlené...

 
Odpovědět
30.5.2016 20:27
Avatar
Petr Štechmüller
Překladatel
Avatar
Odpovídá na Patrik
Petr Štechmüller:30.5.2016 20:43

Ahoj, zkoušel jsi se podívat do dokumentace? Do těch kulatých závorek lze vložit buď:

  • očekávaný počet prvků
  • jiná kolekce, ze které se nakopírují prvky do nové (kopírují se pouze reference)

Více v obrázku:

Odpovědět
30.5.2016 20:43
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Patrik
Člen
Avatar
 
Odpovědět
31.5.2016 15:43
Avatar
Miroslav Bejlek:21.3.2017 16:35

Ahoj, udělal jsi úpravu v části řešení datumů a časů. Teď nedoporučuješ používat třídu Calendar, ale doporučuješ používat třídy LocalDate, LocalTime a LocalDateTime, uopravíš i tento článek?

 
Odpovědět
21.3.2017 16:35
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Miroslav Bejlek
David Čápka:23.3.2017 16:59

Určitě, dostanu se k tomu. Mám dojem, že anglicky to už je - https://www.ict.social/…n-java-curse

Odpovědět
23.3.2017 16:59
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Branislav David:26.10.2017 12:49

Ahojte, chcel som si zakupit nejake premiove clanky ale zaujimalo by ma ako je to s aktualizaciou clankov. Nechcel by som platit za neaktualne clanky.Ako tu vyssie kolega pisal ze triedu Calendar uz neodporucas v predchadzajucom clanku a odpovedal si mu 23. brezna ze sa ku tomu dostanes.Tak by ma zaujimalo ako to je, ci sa o to este niekto stara a tak. Dik za info :)

 
Odpovědět
26.10.2017 12:49
Avatar
Jakub Bómíček Bohm:19.11.2017 17:13

Třída Zaznam tedy slouží pouze pro manipulaci s daty. Obsahuje vnitřní kolekci zaznamy, ta se inicializuje v konstruktoru. Mohli bychom použít i inicializaci bez konstruktoru přímo u deklarace ve formě:

Mám dojem, že by zde místo Zaznam měla být Databaze.

 
Odpovědět
19.11.2017 17:13
Avatar
MICHAL ZAJAC
Člen
Avatar
MICHAL ZAJAC:8. ledna 21:03

Prečo v cvičeniach k 12lekcii OOP a aj tu v diari použivate Calendar ked na začiatku vyuky dátumu a času je písane že Calendar nemame v novych projektoch pouzivat lebo od Javy 8 je tu LocalDateTime?

 
Odpovědět
8. ledna 21:03
Avatar
zitekv
Člen
Avatar
Odpovídá na MICHAL ZAJAC
zitekv:8. ledna 23:32

Protože v době psaní článků pravděpodobně ještě nebyla Java8 k dispozici... viz. datumy u komentářů nebo odkaz Aktivity pod článkem.
A pro procvičení používání LocalDateTime je pro tebe výborná příležitost k ověření vstřebaných znalostí.

Editováno 8. ledna 23:32
 
Odpovědět
8. ledna 23:32
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na MICHAL ZAJAC
David Čápka:12. června 15:32

Aktualizováno pro nové datetime API.

Odpovědět
12. června 15:32
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 17. Zobrazit vše