Website-Suche

So speichern Sie Daten in PostgreSQL in Java


Java ist heutzutage vielleicht die am weitesten verbreitete Programmiersprache. Seine Robustheit und Plattformunabhängigkeit ermöglicht es Java-basierten Anwendungen, auf fast allem zu laufen. Wie bei jeder Anwendung müssen wir unsere Daten auf eine Art und Weise zuverlässig speichern – dieses Bedürfnis, das als Datenbanken zum Leben erweckt wird.

In Java werden Datenbankverbindungen durch JDBC (Java Database Connectivity API) implementiert, die es dem Programmierer ermöglicht, verschiedene Arten von Datenbanken auf fast die gleiche Weise zu handhaben, was unser Leben viel einfacher macht, wenn wir Daten aus einer Datenbank speichern oder lesen müssen.

In diesem Tutorial erstellen wir eine Java-Beispielanwendung, die in der Lage ist, eine Verbindung zu einer PostgreSQL-Datenbankinstanz herzustellen und Daten in diese zu schreiben. Um zu überprüfen, ob das Einfügen von Daten erfolgreich ist, implementieren wir auch das Zurücklesen und Drucken der Tabelle, in die wir Daten eingefügt haben.

In diesem Tutorial lernen Sie:

  • Einrichten der Datenbank für die Anwendung
  • So importieren Sie den PostgreSQL JDBC-Treiber in Ihr Projekt
  • So fügen Sie Daten in die Datenbank ein
  • Ausführen einer einfachen Abfrage zum Lesen des Inhalts einer Datenbanktabelle
  • So drucken Sie abgerufene Daten

Ergebnisse der Ausführung der Anwendung.

Verwendete Softwareanforderungen und Konventionen

Die Einrichtung

Für die Zwecke dieses Tutorials benötigen wir nur eine Workstation (Desktop oder Laptop), um alle benötigten Komponenten zu installieren. Die Installation des JDK, der Netbeans-IDE oder der Installation der PostgreSQL-Datenbank auf dem Laborcomputer wird nicht behandelt. Wir gehen davon aus, dass die Datenbank mit dem Namen exampledb aktiv ist und wir mit den folgenden Anmeldeinformationen eine Verbindung herstellen, lesen und schreiben können, indem wir die Kennwortauthentifizierung verwenden:

Nutzername:BeispielBenutzer
Passwort:ExamplePass

Dies ist ein Beispiel-Setup, verwenden Sie sichere Passwörter in einem realen Szenario! Die Datenbank ist so eingestellt, dass sie auf localhost lauscht, was beim Erstellen der JDBC-Verbindungs-URL erforderlich ist.

Der Hauptzweck unserer Anwendung besteht darin, zu zeigen, wie in die Datenbank geschrieben und aus ihr gelesen wird. Für die wertvollen Informationen, die wir so gerne beibehalten möchten, wählen wir einfach eine Zufallszahl zwischen 1 und 1000 aus und speichern diese Informationen mit einer eindeutigen ID der Berechnung und dem genauen Zeitpunkt, zu dem die Daten in der Datenbank aufgezeichnet werden.

Die ID und der Zeitpunkt der Aufzeichnung werden von der Datenbank bereitgestellt, so dass unsere Anwendung nur mit dem eigentlichen Problem arbeiten kann (in diesem Fall mit einer Zufallszahl). Dies ist beabsichtigt, und wir werden die Möglichkeiten dieser Architektur am Ende dieses Tutorials behandeln.

Einrichten der Datenbank für die Anwendung

Wir haben einen laufenden Datenbankdienst und eine Datenbank namens exampledb, an der wir mit den oben genannten Anmeldeinformationen arbeiten können. Um einen Ort zu haben, an dem wir unsere wertvollen (zufälligen) Daten speichern können, müssen wir eine Tabelle und auch eine Sequenz erstellen, die auf bequeme Weise eindeutige Identifikatoren bereitstellt. Betrachten Sie das folgende SQL-Skript:

create sequence resultid_seq start with 0 increment by 1 no maxvalue minvalue 0 cache 1;
alter sequence resultid_seq owner to exampleuser;
create table calc_results (
        resid numeric primary key default nextval('resultid_seq'::regclass),
        result_of_calculation numeric not null,
        record_date timestamp default now()
);
alter table calc_results owner to exampleuser;

Diese Anweisungen sollten für sich selbst sprechen. Wir erstellen eine Sequenz, setzen den Besitzer auf exampleuser, erstellen eine Tabelle mit dem Namen calc_results (steht für "calculation results"), setzen resid so, dass es bei jeder Einfügung automatisch mit dem nächsten Wert unserer Sequenz gefüllt wird, und definieren result_of_calculation und record_date Spalten, in denen unsere Daten gespeichert werden. Schließlich wird der Eigentümer der Tabelle ebenfalls auf exampleuser festgelegt.

Um diese Datenbankobjekte zu erstellen, wechseln wir zum postgres-Benutzer:

$sudo su - postgres

Führen Sie das Skript (gespeichert in einer Textdatei namens table_for_java.sql) für die exampledb-Datenbank aus:

psql -d exampledb < table_for_java.sql 
CREATE SEQUENCE
ALTER SEQUENCE
CREATE TABLE
ALTER TABLE

Damit ist unsere Datenbank fertig.

Importieren des PostgreSQL JDBC-Treibers in das Projekt

Zum Erstellen der Anwendung verwenden wir NetBeans IDE 8.2. Die ersten Schritte sind Handarbeit. Wir wählen das Menü Datei und erstellen ein neues Projekt. Wir belassen die Standardeinstellungen auf der nächsten Seite des Assistenten, mit der Kategorie "Java" und dem Projekt "Java-Anwendung". Wir drücken auf "Nächstes". Wir geben der Anwendung einen Namen (und definieren optional einen nicht standardmäßigen Speicherort). In unserem Fall wird es persistToPostgres heißen. Dadurch wird die IDE ein Basis-Java-Projekt für uns erstellen.

Im Bereich "Projekte" klicken wir mit der rechten Maustaste auf "Bibliotheken" und wählen "Bibliothek hinzufügen...". Es erscheint ein neues Fenster, in dem wir den PostgreSQL JDBC-Treiber suchen, auswählen und ihn als Bibliothek hinzufügen.

Hinzufügen des PostgreSQL JDBC-Treibers zum Projekt.

Den Quellcode verstehen

Wir fügen nun der Hauptklasse unserer Anwendung, PersistToPostgres, den folgenden Quellcode hinzu:

package persisttopostgres;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.ThreadLocalRandom;

public class PersistToPostgres {
    public static void main(String[] args) {
        int result = ThreadLocalRandom.current().nextInt(1, 1000 + 1);
        System.out.println("Result of the hard-to-solve calculation is: " + result);
        System.out.println("-----PostgreSQL JDBC Connection testing------");
        try {
            Class.forName("org.postgresql.Driver");
        } catch (ClassNotFoundException cnfe) {
            System.out.println("No PostgreSQL JDBC Driver in library path!");
            cnfe.printStackTrace();
            return;
        }
        System.out.println("PostgreSQL JDBC Driver registered!");
        Connection conn = null;
        
        try {            
            conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/exampledb", "exampleuser", "ExamplePass");
        } catch (SQLException sqle) {
            System.out.println("Connection failed! Check output console");
            sqle.printStackTrace();
            return;
        }
        if (conn != null) {
            System.out.println("Database connection established");
            // building query
            try {
                Statement st = conn.createStatement();
                st.executeUpdate("Insert into calc_results (result_of_calculation) values(" + result + ")" );
                ResultSet rs = st.executeQuery("select resid, result_of_calculation, record_date from calc_results");
                System.out.println ("Results recorded in exampledb follows:\n-----------------------\n");
                while (rs.next()) {
                    System.out.println (rs.getString("resid") + "\t" + rs.getString("result_of_calculation") + "\t" + rs.getString("record_date"));
                }
                // clean on exit
                st.close();
                conn.close();
            } catch (SQLException sqle2) {
                System.out.println ("Error on query");
                sqle2.printStackTrace();
            }
        } else {
            System.out.println("Failed to make connection!");
        }
    }
}
  • Bei Zeile 12 berechnen wir eine Zufallszahl und speichern sie in der Ergebnisvariablen. Diese Zahl stellt das Ergebnis einer umfangreichen Berechnung dar, die wir
    in der Datenbank speichern müssen.
  • Bei Zeile 15 versuchen wir, den PostgreSQL JDBC-Treiber zu registrieren. Dies führt zu einem Fehler, wenn die Anwendung den Treiber zur Laufzeit nicht findet.
  • In Zeile 26 erstellen wir die JDBC-Verbindungszeichenfolge mit dem Hostnamen, auf dem die Datenbank läuft (localhost), dem Port, auf dem die Datenbank lauscht (5432, der Standardport für PostgreSQL), dem Datenbanknamen (exampledb) und den eingangs erwähnten Anmeldeinformationen.
  • Bei Zeile 37 führen wir die Anweisung insert into SQL aus, die den Wert der Ergebnisvariablen in die result_of_calculation Spalte der calc_results Tabelle einfügt. Wir geben nur den Wert dieser einzelnen Spalte an, so dass die Standardwerte gelten: resid wird aus der Sequenz abgerufen, die we
    festgelegt hat, und record_date ist standardmäßig now(), was der Datenbankzeit zum Zeitpunkt der Transaktion entspricht.
  • Bei Zeile 38 erstellen wir eine Abfrage, die alle in der Tabelle enthaltenen Daten zurückgibt, einschließlich unserer Einfügung im vorherigen Schritt.
  • In Zeile 39 von Zeile 39 präsentieren wir die abgerufenen Daten, indem wir sie tabellenartig ausdrucken, Ressourcen freigeben und beenden.

Ausführen der Anwendung

Wir können jetzt die persistToPostgres-Anwendung über die IDE selbst oder über die Befehlszeile bereinigen, erstellen und ausführen. Um von der IDE aus auszuführen, können wir die Schaltfläche "Projekt ausführen" oben verwenden. Um es von der Befehlszeile aus auszuführen, müssen wir zum dist-Verzeichnis des Projekts navigieren und die JVM mit dem JAR-Paket als Argument aufrufen:

java -jar persistToPostgres.jar 
Result of the hard-to-solve calculation is: 173
-----PostgreSQL JDBC Connection testing------
Database connection established
Results recorded in exampledb follows:
-----------------------

0       145     2020-05-31 17:40:30.974246

Befehlszeilenläufe liefern die gleiche Ausgabe wie die IDE-Konsole, aber was hier wichtiger ist, ist, dass jeder Lauf (sei es von der IDE oder der Befehlszeile) eine weitere Zeile in unsere Datenbanktabelle einfügt, wobei die angegebene Zufallszahl bei jedem Lauf berechnet wird.

Aus diesem Grund werden wir auch eine wachsende Anzahl von Datensätzen in der Ausgabe der Anwendung sehen: Bei jedem Durchlauf wird die Tabelle um eine Zeile erweitert. Nach ein paar Durchläufen sehen wir eine lange Liste von Ergebniszeilen in der Tabelle.

Die Datenbankausgabe zeigt die Ergebnisse jeder Ausführung der Anwendung an.

Schlussfolgerung

Obwohl diese einfache Anwendung kaum in der realen Welt verwendet wird, ist sie perfekt, um einige wirklich wichtige Aspekte zu demonstrieren. In diesem Tutorial haben wir gesagt, dass wir eine wichtige Berechnung mit der Anwendung durchführen und jedes Mal eine Zufallszahl eingefügt haben, da der Zweck dieses Tutorials darin besteht, zu zeigen, wie die Daten beibehalten werden. Dieses Ziel haben wir erreicht: Bei jedem Durchlauf wird die Anwendung beendet und die Ergebnisse der internen Berechnungen gehen verloren, aber die Datenbank behält die Daten bei.

Wir haben die Anwendung von einer einzigen Workstation aus ausgeführt, aber wenn wir wirklich eine komplizierte Berechnung durchführen müssten, müssten wir nur die URL der Datenbankverbindung so ändern, dass sie auf einen Remote-Computer verweist, auf dem die Datenbank ausgeführt wird, und wir könnten die Berechnung auf mehreren Computern gleichzeitig starten und gleichzeitig Hunderte oder Tausende von Instanzen dieser Anwendung erstellen. Vielleicht lösen wir kleine Teile eines größeren Puzzles und speichern die Ergebnisse auf eine dauerhafte Weise, die es uns ermöglicht, unsere Rechenleistung mit ein paar Zeilen Code und ein wenig Planung zu skalieren.

Warum ist eine Planung erforderlich? Um bei diesem Beispiel zu bleiben: Wenn wir die Zuweisung von Zeilenkennungen oder Zeitstempeln nicht der Datenbank überlassen würden, wäre unsere Anwendung viel größer, viel langsamer und viel voller Fehler gewesen – einige von ihnen tauchen nur auf, wenn wir zwei Instanzen der Anwendung gleichzeitig ausführen.

Verwandte Artikel: