13. díl - Diář s databází v Javě

Java Objektově orientované programování Diář s databází v Javě

V minulém dílu našeho seriálu tutoriálů o Javě 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. Dnes 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 nedavno 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:

import java.util.Calendar;

public class Zaznam {
    private Calendar datumCas;
    private String text;

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

    public Calendar getDatumCas() {
        return datumCas;
    }

    public void setDatumCas(Calendar datumCas) {
        this.datumCas = datumCas;
    }

    public String getText() {
        return text;
    }

    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

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:

public class Databaze {

    private ArrayList<Zaznam> zaznamy;

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

}

Třída 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(Calendar 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 den, měsíc a rok (pokud hledáme jen podle data). Naplněný ArrayList s nalezenými záznamy vrátíme.

public ArrayList<Zaznam> najdiZaznamy(Calendar datum, boolean dleCasu)
{
        ArrayList<Zaznam> nalezene = new ArrayList<>();
        for (Zaznam z : zaznamy)
        {
                if (((dleCasu) && (z.getDatumCas().equals(datum))) // dle času a data
                        ||
                ((!dleCasu) && // pouze dle data
                        (z.getDatumCas().get(Calendar.DAY_OF_MONTH) == datum.get(Calendar.DAY_OF_MONTH)) &&
                        (z.getDatumCas().get(Calendar.MONTH) == datum.get(Calendar.MONTH))) &&
                        (z.getDatumCas().get(Calendar.YEAR) == datum.get(Calendar.YEAR))
                )
                   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(Calendar 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 oddě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:

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 příště spolu se zprovozněním celé aplikace.


 

  Aktivity (1)

Článek pro vás napsal David Čápka
Avatar
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 se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (4 hlasů) :
55555


 


Miniatura
Předchozí článek
ArrayList v Javě

 

 

Komentáře

Avatar
Viktor Mikulášek:

Ahoj!
Myslím si, že je malá chyba v metodě

najdiZaznam()

Myslím si, že by tam mělo být:

ArrayList<Zaznam> nalezene = new ArrayList<>(Zaznam);

Doufám, že se nepletu.
Viktor

 
Odpovědět 26.12.2015 11:40
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na Viktor Mikulášek
pocitac770:

"Normální" verze je toto:

ArrayList<Zaznam> nalezene = new ArrayList<Zaznam>();

viz zde: http://www.itnetwork.cz/…zani-polozek
Pokud bys to chtěl psát do kulaté závorky, tak by to musel bát parametr pro konstruktor, a v tu chvíli by to musela být proměnná, nikoliv třída, už jenom z logiky věci, ne?

Toto:

ArrayList<Zaznam> nalezene = new ArrayList<>();

Je novinka (myslím že z javy 8 ), tzv. Diamond interface, které zjednodušuje deklaraci Listu tím, že nemusíme udávat skutečný typ proměnné, načte si ho z aktuálního typu (ve kterém je uložen).

Editováno 26.12.2015 11:48
 
Odpovědět 26.12.2015 11:47
Avatar
Atrament
Člen
Avatar
Odpovídá na pocitac770
Atrament:

Je to Diamond operator a ne interface a je s námi už od Javy 7.

 
Odpovědět 26.12.2015 12:53
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na Atrament
pocitac770:

Tak jsem popletl názvosloví, a zrovna ty verze javy si moc nepamatuju (proto jsem napsal to "myslím").... :/ Ale účel vysvětlení to myslím splnilo, i tak děkuji za opravu :)

 
Odpovědět 26.12.2015 13:41
Avatar
David Tilšer:

Nechápu k čemu je třída Záznam? Když ji do projektu nezahrnu, tak pořád funguje tak jak má. Může mi to někdo prosím vysvětlit?

Odpovědět 17. března 19:02
Odpočinek je pro slabochy.
Avatar
Odpovídá na David Tilšer
David Tilšer:

Otázku ruším, už jsem na to přišel :-)

Odpovědět 17. března 19:59
Odpočinek je pro slabochy.
Avatar
Odpovídá na pocitac770
Viktor Mikulášek:

Ahoj!
Jj, máš pravdu. U mě v programu to mám správně, ale tady jsem se bohužel přepsal.
Díky za opravu.

 
Odpovědět 19. března 22:46
Avatar
Patrik
Člen
Avatar
Patrik:

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. května 20:27
Nikdy nedovolím aby mi škola bránila v ceste za vzdelaním (Mark Twain).
Avatar
Odpovídá na Patrik
Petr Štechmüller:

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. května 20:43
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Patrik
Člen
Avatar
Odpovědět 31. května 15:43
Nikdy nedovolím aby mi škola bránila v ceste za vzdelaním (Mark Twain).
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 10.