Zielony Smok - logo witryny

Apache Derby: własny typ danych AriaEnum

Własny typ wyliczeniowy AriaEnum

Nasz nowy typ będzie pozwalał na utworzenie kolumny, w której będą przechowywane poszczególne elementy wyliczenia.

Tworzymy klasę Java dla nowego typu. Klasa musi implementować interfejs Externalizable, który wymaga przygotowania co najmniej 2 metod:

  • readExternal(Object Input)
  • writeExternal(ObjectOutput)
Klasa AriaEnum.java
package aderby.types;

import java.io.*;

public class AriaEnum<T extends Enum<T>> implements Externalizable {
    private T enumElement;
    private Class<T> klasa;

    public AriaEnum() {
    }

    public AriaEnum(T enumElement) {
        this.enumElement = enumElement;
        klasa = enumElement.getDeclaringClass();
    }

    @SuppressWarnings("unchecked")
    @Override
    public void readExternal(ObjectInput in)
            throws IOException, ClassNotFoundException {
        String zal = in.readUTF();
        Class<T> kl = (Class<T>) in.readObject();
        enumElement = Enum.valueOf(kl, zal);
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        String zal = enumElement.toString();
        out.writeUTF(zal);
        out.writeObject(klasa);
    }

    public T getEnumElement() {
        return this.enumElement;
    }

    public void setEnumElement(T enumElement) {
        this.enumElement = enumElement;
        klasa = enumElement.getDeclaringClass();
    }

    public Class<?> getKlasa() {
        return this.klasa;
    }

    @Override
    public String toString() {
        return enumElement.toString();
    }
}

Klasa R063_ARIAENUM.java

package aderby.types;

import aderby.DerbyUtil;

import java.sql.*;

public class R063_ARIAENUM {
    /**
     * Polecenie SQL tworzące typ AriaEnum
     */
    public static final String createTypeEnumer = "CREATE TYPE ariaenum "
            + "EXTERNAL NAME 'aderby.types.AriaEnum' LANGUAGE JAVA";
    /**
     * Tworzy tabelę 'typy'
     * Tabela zawiera kolumnę 'id' z automatycznym inkrementowaniem
     * oraz kolumnę 'wyliczenie' przechowującą jeden element
     * typu 'AriaEnum'.
     */
    public static final String createTable = "CREATE TABLE typy("
            + "id INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS "
            + "IDENTITY(START WITH 1, INCREMENT BY 1), wyliczenie ARIAENUM)";

    /**
     * Wyliczenie, którego element będzie dodany do bazy danych
     */
    enum Lights {
        RED, GREEN, YELLOW
    }

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        //startujemy Derby
        DerbyUtil.startDerbyEngine("EmbeddedDriver");
        //tworzymy połączenie do bazy danych. jeśli bazy nie ma - zostanie
        //utworzona. Jeśli jest - zostanie użyta.
        Connection con = DerbyUtil.connectEmbeddedDB("C:/Przyklady/R063",
                ";create=true");
        //Tworzymy polecenie
        Statement stat = null;
        try {
            stat = con.createStatement();
            //dodajemy polecenie wsadowe tworzące typ 'Enumer'
            stat.addBatch(createTypeEnumer);
            //dodajemy polecenie wsadowe tworzące tabelę 'typy'
            stat.addBatch(createTable);
            //wykonujemy polecenia
            stat.executeBatch();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //Tworzymy polecenie przechowywane
        PreparedStatement stmt = null;
        //tworzymy komendę SQL wstawiająca dane do tabeli typy.
        //wartość 'id' jest wstawiana automatycznie
        //wartość 'enumer' będzie wstawiane ręcznie
        String insertSQL = "INSERT INTO typy (id,  wyliczenie) values (DEFAULT,?)";
        try {
            //przygotowujemy polecenie
            //'id' został wstawiony automatycznie
            stmt = con.prepareStatement(insertSQL);
            //wstawiamy wartość wyliczeniową
            stmt.setObject(1, new AriaEnum<>(Lights.RED));
            //wykonujemy polecenie
            stmt.executeUpdate();
            //czyścimy parametry, aby przygotować polecenie na przyjęcie
            //następnych wartości, gdybyśmy wstawiali je w petli. W tym
            //przypadku nie jest konieczne
            stmt.clearParameters();
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
        //Polecenie SQL do pobierania danych z tabeli 'typy'
        String selectSQL = "SELECT  * FROM typy";
        //Tworzymy polecenie przygotowywane
        PreparedStatement pstm = null;
        //tworzymy zbiór wynikowy
        ResultSet rs = null;
        //przygotowujemy inne zmienne
        int id = -1;
        Lights en = null;
        try {
            //przygotowuje polecenie
            pstm = con.prepareStatement(selectSQL);
            //wykonujemy polecenie
            rs = pstm.executeQuery();
            //przeglądamy zbiór wynikowy dopóki ma jakieś wartości
            while (rs.next()) {
                //pobieramy wartość 'id'
                id = rs.getInt("id");
                //pobieramy wartosc wyliczeniowa
                en = ((AriaEnum<Lights>) rs.getObject("wyliczenie"))
                        .getEnumElement();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //drukujemy wyniki na konsoli
        System.out.println("id: " + id);
        System.out.println(en);
        //zamykamy polecenia i połączenia
        DerbyUtil.close(rs);
        DerbyUtil.close(stat);
        DerbyUtil.close(stmt);
        DerbyUtil.close(pstm);
        DerbyUtil.close(con);
        //zamykamy Derby, a wraz z nim wszystkie bazy danych
        DerbyUtil.shutdownDerbyEngine();
    }
}

Po uruchomieniu na konsoli zobaczymy:

id: 1
RED

Pliki do ściągnięcia

Aktualny (tworzony narastająco) plik module-info.java

Aktualny (tworzony narastająco) plik DerbyUtil.java

Pliki tworzone narastająco zastępują poprzednie pliki o tej samej nazwie i działają dla wszystkich wcześniej opublikowanych przykładów we wszystkich wpisach w projekcie. W przypadku pliku module-info.java może być potrzebne skreślenie niepotrzebnych wpisów.