Recherche de site Web

Comment conserver des données dans PostgreSQL en Java


Java est peut-être le langage de programmation le plus utilisé de nos jours. Sa robustesse et sa nature indépendante de la plate-forme permettent aux applications basées sur Java de fonctionner sur presque n’importe quoi. Comme c’est le cas pour toute application, nous devons stocker nos données d’une manière fiable – ce besoin appelé bases de données à la vie.

En Java, les connexions aux bases de données sont implémentées par JDBC (Java Database Connectivity API), qui permet au programmeur de gérer différents types de bases de données presque de la même manière, ce qui nous facilite grandement la vie lorsque nous devons enregistrer ou lire des données à partir d’une base de données.

Dans ce tutoriel, nous allons créer un exemple d’application Java qui sera capable de se connecter à une instance de base de données PostgreSQL et d’y écrire des données. Pour vérifier que l’insertion de nos données est réussie, nous allons également implémenter la relecture et imprimer la table dans laquelle nous avons inséré les données.

Dans ce tutoriel, vous allez apprendre :

  • Comment configurer la base de données de l’application
  • Comment importer le pilote JDBC PostgreSQL dans votre projet
  • Comment insérer des données dans la base de données
  • Comment exécuter une requête simple pour lire le contenu d’une table de base de données
  • Comment imprimer les données récupérées

Résultats de l’exécution de l’application.

Configuration logicielle requise et conventions utilisées

La configuration

Pour les besoins de ce tutoriel, nous n’avons besoin que d’un seul poste de travail (de bureau ou portable) pour installer tous les composants nécessaires. Nous ne couvrirons pas l’installation de JDK, de l’IDE Netbeans ou de l’installation de la base de données PostgreSQL sur la machine de laboratoire. Nous supposons que la base de données appelée exampledb est opérationnelle et que nous pouvons nous connecter, lire et écrire à l’aide de l’authentification par mot de passe, avec les informations d’identification suivantes :

Nom d’utilisateur:exempleutilisateur
Mot de passe:ExamplePass

Il s’agit d’un exemple de configuration, utilisez des mots de passe forts dans un scénario réel ! La base de données est configurée pour écouter sur localhost, ce qui sera nécessaire lorsque nous construisons l’URL de connexion JDBC.

L’objectif principal de notre application est de montrer comment écrire et lire à partir de la base de données, donc pour les informations précieuses que nous sommes si impatients de persister, nous choisirons simplement un nombre aléatoire entre 1 et 1000, et stockerons ces informations avec un ID unique du calcul, et l’heure exacte à laquelle les données sont enregistrées dans la base de données.

L’ID et l’heure d’enregistrement seront fournis par la base de données, qui permet à notre application de travailler uniquement sur le problème réel (en fournissant un nombre aléatoire dans ce cas). C’est intentionnel, et nous couvrirons les possibilités de cette architecture à la fin de ce tutoriel.

Configuration de la base de données de l’application

Nous avons un service de base de données en cours d’exécution, et une base de données appelée exampledb sur laquelle nous avons les droits pour travailler avec les informations d’identification mentionnées ci-dessus. Pour avoir un endroit où nous pouvons stocker nos précieuses données (aléatoires), nous devons créer une table, ainsi qu’une séquence qui fournira des identifiants uniques de manière pratique. Considérez le script SQL suivant :

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;

Ces instructions doivent parler d’elles-mêmes. Nous créons une séquence, définissons le propriétaire à exampleuser, créons une table appelée calc_results (pour « résultats de calcul »), définissons resid pour qu’il soit rempli automatiquement avec la valeur suivante de notre séquence à chaque insertion, et définissons result_of_calculation et record_date colonnes qui stockeront nos données. Enfin, le propriétaire de la table est également défini sur exampleuser.

Pour créer ces objets de base de données, nous passons à l’utilisateur postgres :

$sudo su - postgres

Et exécutez le script (stocké dans un fichier texte appelé table_for_java.sql) sur la base de données exampledb :

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

Avec cela, notre base de données est prête.

Importation du pilote JDBC PostgreSQL dans le projet

Pour construire l’application, nous allons utiliser NetBeans IDE 8.2. Les premières étapes sont un travail manuel. Nous choisissons le menu Fichier, créons un nouveau projet. Nous laisserons les valeurs par défaut sur la page suivante de l’assistant, avec la catégorie « Java » et le projet sur « Application Java ». Nous allons appuyer sur ensuite. Nous donnons un nom à l’application (et définissons éventuellement un emplacement autre que celui par défaut). Dans notre cas, il s’appellera persistToPostgres. Cela permettra à l’IDE de créer un projet Java de base pour nous.

Dans le volet Projets, nous cliquons avec le bouton droit de la souris sur « Bibliothèques » et sélectionnons « Ajouter une bibliothèque... ». Une nouvelle fenêtre apparaîtra, dans laquelle nous rechercherons et sélectionnerons le pilote JDBC PostgreSQL, et l’ajouterons en tant que bibliothèque.

Ajout du pilote JDBC PostgreSQL au projet.

Comprendre le code source

Nous ajoutons maintenant le code source suivant à la classe principale de notre application, PersistToPostgres :

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!");
        }
    }
}
  • À ligne 12, nous calculons un nombre aléatoire et le stockons dans la variable de résultat. Ce nombre représente le résultat d’un calcul lourd que
    nous devons stocker dans la base de données.
  • À ligne 15, nous essayons d’enregistrer le pilote JDBC PostgreSQL. Cela entraînera une erreur si l’application ne trouve pas le pilote au moment de l’exécution.
  • À ligne 26, nous construisons la chaîne de connexion JDBC en utilisant le nom d’hôte sur lequel la base de données s’exécute (localhost), le port sur lequel la base de données écoute (5432, le port par défaut pour PostgreSQL), le nom de la base de données (exampledb) et les informations d’identification mentionnées au début.
  • À ligne 37, nous exécutons l’instruction insert into SQL qui insère la valeur de la variable de résultat dans la colonne result_of_calculation de la table calc_results. Nous spécifions uniquement la valeur de ces colonnes uniques, donc les valeurs par défaut s’appliquent : resid est récupéré à partir de la séquence we
    définie, et record_date par défaut à now(), qui est l’heure de la base de données au moment de la transaction.
  • À ligne 38, nous construisons une requête qui renverra toutes les données contenues dans la table, y compris notre insertion à l’étape précédente.
  • À partir de ligne 39, nous présentons les données récupérées en les imprimant à la manière d’un tableau, libérons des ressources et quittons.

Exécution de l’application

Nous pouvons maintenant nettoyer, compiler et exécuter l’application persistToPostgres, à partir de l’IDE lui-même ou de la ligne de commande. Pour exécuter à partir de l’IDE, nous pouvons utiliser le bouton « Exécuter le projet » en haut. Pour l’exécuter à partir de la ligne de commande, nous devons naviguer jusqu’au répertoire dist du projet, et appeler la JVM avec le package JAR comme argument :

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

Les exécutions en ligne de commande fourniront le même résultat que la console de l’IDE, mais ce qui est plus important ici, c’est que chaque exécution (que ce soit à partir de l’IDE ou de la ligne de commande) insérera une autre ligne dans notre table de base de données avec le nombre aléatoire donné calculé à chaque exécution.

C’est pourquoi nous verrons également un nombre croissant d’enregistrements dans la sortie de l’application : chaque exécution agrandit la table d’une ligne. Après quelques exécutions, nous verrons une longue liste de lignes de résultats dans le tableau.

La sortie de la base de données affiche les résultats de chaque exécution de l’application.

Conclusion

Bien que cette application simple n’ait guère d’utilisation dans le monde réel, elle est parfaite pour démontrer certains aspects vraiment importants. Dans ce tutoriel, nous avons dit que nous faisions un calcul important avec l’application, et que nous avions inséré un nombre aléatoire à chaque fois, car le but de ce tutoriel est de montrer comment conserver les données. Nous avons atteint cet objectif : à chaque exécution, l’application se ferme et les résultats des calculs internes sont perdus, mais la base de données préserve les données.

Nous avons exécuté l’application à partir d’un seul poste de travail, mais si nous avions vraiment besoin de résoudre un calcul compliqué, il nous suffisait de modifier l’URL de connexion à la base de données pour qu’elle pointe vers une machine distante exécutant la base de données, et nous pourrions démarrer le calcul sur plusieurs ordinateurs en même temps, créant des centaines ou des milliers d’instances de cette application. peut-être en résolvant de petites pièces d’un puzzle plus grand, et en stockant les résultats de manière persistante, ce qui nous permet d’augmenter notre puissance de calcul avec quelques lignes de code et un peu de planification.

Pourquoi la planification est-elle nécessaire ? Pour rester avec cet exemple : si nous n’avions pas laissé l’attribution d’identifiants de ligne ou l’horodatage à la base de données, notre application aurait été beaucoup plus grande, beaucoup plus lente et beaucoup plus pleine de bogues – certains d’entre eux n’apparaissent que lorsque nous exécutons deux instances de l’application au même moment.

Articles connexes: