Chcemy umieścić w bazie danych Derby i odczytać z bazy danych Derby tablicę elementów dowolnego typu.

Przygotowanie klas

Przygotowujemy klasę AriaArray.

package aderby.types;

import java.io.*;

public class AriaArray implements Externalizable {
    private T[] array;

    public AriaArray() {
        this(null);
    }

    public AriaArray(T[] array) {
        this.array = array;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void readExternal(ObjectInput in)
            throws IOException, ClassNotFoundException {
        int len = in.readInt();
        T[] objs = (T[]) new Object[len];
        for (int i = 0; i < len; i++) {
            objs[i] = (T) in.readObject();
        }
        setArray(objs);
    }

    @Override
    public void writeExternal(ObjectOutput out) 
              throws IOException {
        out.writeInt(array.length);
        for (T t : array) {
            out.writeObject(t);
        }
    }

    public T[] getArray() {
        return this.array;
    }

    public void setArray(T[] array) {
        this.array = array;
    }
}

Przygotowujemy klasę testującą R066.

package aderby.types;

import aderby.DerbyUtil;

import java.sql.*;
import java.util.Objects;

public class R066 {
    //Polecenie SQl tworzące typ 'Tablica'
    public static final String createTypeTablica = "CREATE TYPE ariaarray "
            + "EXTERNAL NAME 'aderby.types.AriaArray' LANGUAGE JAVA";
    //Polecenie SQl tworzące tabelę 'typy' z dwiema kolumnami:
    //kolumna 'id' typu Integer, automatycznie inkrementowana
    //kolumna 'tabl' przechowująca tablicę danych
    public static final String createTable = "CREATE TABLE typy("
            + "id INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS "
            + "IDENTITY(START WITH 1, INCREMENT BY 1),  tabl ARIAARRAY)";

    public static void main(String[] args) {
        //startujemy silnik Derby
        DerbyUtil.startDerbyEngine("EmbeddedDriver");
        //Tworzymy połączenie z bazą 'baza_testowa'. Jeśli baza nie 
        //istnieje zostanie utworzona. Jeśli istnieje zostanie użyta.
        Connection con = DerbyUtil.connectEmbeddedDB("C:/Przyklady/r066",
                ";create=true");
        //Tworzymy polecenie;
        Statement stat = null;
        try {
            //nadajemy mu wartość
            stat = con.createStatement();
            //dodajemy polecenie wsadowe tworzące tabelę bazy danych
            stat.addBatch(createTypeTablica);
            //dodajemy polecenie wsadowe tworzące typ 'Tablica'
            stat.addBatch(createTable);
            //wykonujemy polecenia wsadowe
            stat.executeBatch();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //Tworzymy polecenie przygotowywane
        PreparedStatement stmt = null;
        //Polecenie SQL wstawiające dane do tabeli 'typy'
        //'id' jest wstawiane automatycznie
        //'tabl' jest wstawiane ręcznie
        String insertSQL = "INSERT INTO typy (id,  tabl) values 
              (DEFAULT,?)";
        //Tablica do wstawienia
        String[] tabl = {"Jacek", "Mirka", "Ula"};
        try {
            //przygotowujemy polecenie
            stmt = con.prepareStatement(insertSQL);
            //wstawiamy tablice 'tabl'
            stmt.setObject(1, new AriaArray<>(tabl));
            //wykonujemy polecenie
            stmt.executeUpdate();
            //usuwamy parametry co przygotowuje 'stms' do 
            //przyjęcia następnych danych, gdyby były dodawane 
            //w pętli. W tym przypadku nie jest to konieczne
            stmt.clearParameters();
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
        //Polecenie SQL pobierające dane z tabeli typy
        String selectSQL = "SELECT  * FROM typy";
        //tworzymy polecenie przygotowywane i zbiór wynikowy
        PreparedStatement pstm = null;
        ResultSet rs = null;
        //przygotowujemy zmienne pomocnicze
        int id = -1;
        Object[] tab = null;
        String[] tabli;
        try {
            //przygotowujemy polecenie
            pstm = con.prepareStatement(selectSQL);
            //wykonujemy polecenie
            rs = pstm.executeQuery();
            //pobieramy dane ze zbioru wynikowego az do skutku
            while (rs.next()) {
                //pobieramy identyfikator
                id = rs.getInt("id");
                //pobieramy tablice obiektów
                tab = ((AriaArray) rs.getObject("tabl")).getArray();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //tworzymy tablice stringów
        tabli = new String[Objects.requireNonNull(tab).length];
        //przepisujemy dane z tablicy obiektów do tablicy 
        //stringów
        //rzutując je do typu String
        for (int j = 0; j < tab.length; j++) {
            tabli[j] = (String) tab[j];
        }
        //drukujemy na konsoli identyfikator
        System.out.println("id: " + id);
        //drukujemy tablice na konsoli
        DerbyUtil.print(tabli);
        //zamykamy polecenia i zbiór wynikowy
        DerbyUtil.close(stat);
        DerbyUtil.close(stmt);
        DerbyUtil.close(pstm);
        DerbyUtil.close(rs);
        //zamykamy połączenie
        DerbyUtil.close(con);
        //zatrzymujemy silnik Derby co zamyka 
        //również wszystkie bazy danych
        DerbyUtil.shutdownDerbyEngine();
    }
}

Po uruchomieniu klasy na konsoli zobaczymy:

Wynik
id: 1
[Jacek, Mirka, Ula]

Pliki do ściągnięcia

Plik R066.zip (klasa)
Plik AriaArray.zip (klasa)
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.