IT rekvalifikace s podporou uplatnění. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 6 - Databázový wrapper v Javě - Tvorba třídy Query

V minulém dílu, Programování databázového Wrapperu v Javě - Příprava, jsme započali tvorbu databázového wrapperu, který nám zjednoduší práci s databází.

Dnešní tutoriál bude hlavně o programování. Ještě než začneme programovat samotnou třídu Database, tak si připravíme kód třídy Query, která bude znázorňovat samotný SQL dotaz.

Třída Query

V balíčku DB máme z dřívějška připravené prázdné třídy Database a Query. Ve třídě Query budeme nyní pomocí metod postupně sestavovat SQL dotazy. Celá struktura našeho projektu vypadá takto:

Diagram JDBC wrapperu v Javě - Databáze v Javě - JDBC

Metody pro vyhledávání a mazání

Ve třídě Query si vytvoříme metodu delete() a metodu where(), kterou budeme používat velmi často:

public class Query {

    private StringBuilder query;

    /**
     * @param table (Db table)
     * @return SQL query DELETE
     */
    public Query delete(String table) {
        query = new StringBuilder();
        query.append("DELETE FROM ");
        query.append(table);
        return this;
    }

    /**
     * Adds condition forSQL query
     *
     * @param requirement condition
     * @return SQL query WHERE
     */
    public Query where(String requirement) {
        query.append(" WHERE ");
        query.append(requirement);
        return this;
    }

    /**
     * @param table (Db table)
     * @return SQL query FROM
     */
    public Query from(String table) {
        query.append(" FROM ");
        query.append(table);
        return this;
    }
}

Díky třídě StringBuilder můžeme snadněji poskládat naše SQL dotazy a uložit je do instanční proměnné query. Metoda append() k ní jednoduše přidá část textu, znak, nebo proměnou. Proměnná může být jakéhokoli datového typu (Object, String, char, boolean, double, int, float, atd.).

Instanci třídy StringBuilder můžeme poté přeměnit na textový řetězec pomocí metody toString().

Důležitá pro nás je metoda where(), protože tu využijeme nejčastěji.

Metody update() a set()

Podobně přidáme i metody update() a set():

public class Query {

    // ...

     /**
     * @param table (Db table)
     * @return SQL query UPDATE
     */
    public Query update(String table) {
        query = new StringBuilder();
        query.append("UPDATE ");
        query.append(table);
        query.append(" SET ");
        return this;
    }

    /**
     * Fills Db columns into the query
     *
     * @param columns (array of Db columns)
     */
    public Query set(String[] columns) {
        int count = columns.length;
        if (count == 0) {
            throw new IllegalArgumentException("Neplatný počet parametrů.");
        }

        for (String column : columns) {
            query.append(column);
            query.append(" = ");
            query.append("?");
            query.append(",");
        }
        query.deleteCharAt(query.lastIndexOf(","));
        return this;
    }
}

Teď si řekneme, proč máme na konci každé metody return this;. Je to jednoduché. Každá metoda ve třídě Query je datového typu Query. To znamená, že vrací instancí dané třídy. Má to tu výhodu, že můžeme zefektivnít kód. A místo takového kódu:

query.update(table);
query.set(columns);
query.where(requirement);

Můžeme efektivně napsat toto:

query.update(table).set(columns).where(requirement);

Takovému zápisu se říká plynulé rozhraní (Fluent Interface). Pomáhá nám to vytvářet aplikační rozhraní, které je velmi čitelné a pochopitelné. Plynulé rozhraní vytvořil Martin Fowler a je to technika objektové orientovaného programování, kde jak jsme si již výše ukázali, řetězíme po sobě jdoucí volání metod téhož objektu.

Dále stojí za povšimnutí, že v metodě set() testujeme, zda neposíláme prázdný parametr. V případě, že pošleme neplatný parametr, tak se vyvolá výjimka IllegalArgumentException. Nakonec jen zmíníme, že metoda deleteCharAt() nám odebere poslední nežádoucí čárku, ale vnitřní logiku metod si i s příklady probereme v jiné části tohoto tutoriálu.

Metody insert() a values()

Přidejme metody insert() a values():

public class Query {

    // ...

    /**
     * @param table (Db table)
     * @return SQL query INSERT
     */
    public Query insert(String table) {
        query = new StringBuilder();
        query.append("INSERT INTO ");
        query.append(table);
        return this;
    }

    /**
     * @param params (array of VALUES)
     * @return VALUES for INSERT
     */
    public Query values(Object[] params) {
        query.append(" VALUES(");

        int count = params.length;

        if (count == 0) {
            throw new IllegalArgumentException("Neplatný počet parametrů.");
        }

        for (int i = 0; i < count; i++) {
            query.append("?,");
        }
        query.deleteCharAt(query.lastIndexOf(","));
        query.append(");");
        return this;
    }
}

V metodě insert() není nic nového. Metoda values() bere jako parametr pole objektů a za každý prvek dosadí do SQL dotazu ?. Nakonec se odstraní poslední čárka a vrátí instance třídy Query. Pokud bude počet parametrů roven nule, vyvolá se výjimka IllegalArgumentException.

Metoda select()

Do třídy doplníme také metodu select() s tímto kódem:

public class Query {

    // ...

    /**
     * @param columns (array of Db columns)
     * @return SQL query SELECT
     */
    public Query select(Object[] columns) {
        query = new StringBuilder();
        query.append("SELECT ");
        if (columns != null) {
            for (Object column : columns) {
                query.append(column);
                query.append(",");
            }

            query.deleteCharAt(query.lastIndexOf(","));
        } else {
            query.append("*");
        }
        return this;
    }
}

Metoda select() bere jako parametr pole objektů, které reprezentují jednotlivé sloupce. Pokud dáme metodě select() jako parametr hodnotu null, dosadí do SQL dotazu znak *, který vrací všechny sloupce z databázové tabulky.

Metoda getQuery()

Nakonec doplníme metodu, která nám vrátí daný SQL dotaz:

public class Query {

    // ...

     /**
     *
     * @return complete sql query
     */
    public String getQuery() {
        return query.toString();
    }
}

V metodě getQuery() jsme zavolali metodu toString() na instanci query a vrátili předtím sestavený dotaz jako textový řetězec. Pokračovat budeme příště :)

V dalším díle, Programování databázového Wrapperu v Javě - Třída Database, si třídu Query otestujeme a vytvoříme si třídu Database.


 

Předchozí článek
Programování databázového Wrapperu v Javě - Příprava
Všechny články v sekci
Databáze v Javě - JDBC
Přeskočit článek
(nedoporučujeme)
Programování databázového Wrapperu v Javě - Třída Database
Článek pro vás napsal Milan Gallas
Avatar
Uživatelské hodnocení:
52 hlasů
Autor se věnuje programování, hardwaru a počítačovým sítím.
Aktivity