[JAVA] Comment créer un pilote JDBC

introduction

Je me suis demandé s'il serait possible de réaliser un RDB sans serveur, mais je pense que c'est tout à fait le cas si j'utilise CloudRun. Cependant, CloudRun ne peut pas parler JDBC, j'ai donc pensé que je devrais créer mon propre pilote JDBC et utiliser HTTP à l'arrière, alors j'ai étudié comment le faire.

Étonnamment, il semble que le pilote JDBC puisse être facilement créé, j'ai donc essayé de créer l'implémentation minimale du squelette pour le moment. Comme il n'y a pas de RDB à l'arrière, je vais essentiellement faire ce qui suit qui renvoie simplement un écho.

--Classe principale pour les tests

Processus d'exécution pour les tests

Tout d'abord, créons une classe principale qui teste et exécute à la fois les lapins et les coins. Il s'agit d'un pilote JDBC créé par MyDriver et MyConnection. C'est une implémentation simple qui confirme simplement que la valeur de retour est MyConnection, mais vous pouvez maintenant voir que votre propre pilote JDBC est appelé correctement.

github: https://github.com/koduki/jdbc-skeleton/blob/master/src/main/java/Main.java

var url = "jdbc:myjdbc://localhost:80/testdb";

Class.forName("cn.orz.pascal.jdbc.MyDriver");
try (var con = DriverManager.getConnection(url); var st = con.createStatement()) {
    st.execute("INSERT DUMMY SQL");
    try (var rs = st.executeQuery("SELECT DUMMY SQL")) {
        while (rs.next()) {
            System.out.println("rs[1]=" + rs.getString(1));
        }
    }
}

Le résultat de l'exécution est le suivant.

jdbc uri: jdbc:myjdbc://localhost:80/testdb
execute sql: INSERT DUMMY SQL
execute sql: SELECT DUMMY SQL
rs[1]=a
rs[1]=e
rs[1]=h
MyResultSet close
MyStatement close
MyConnection close

Driver

Vient ensuite le pilote JDBC. Le point est l'initialiseur statique, qui termine l'enregistrement du pilote lorsque la classe est chargée avec Class.forName.

Vous pouvez également obtenir l'URL JDBC ici. Dans l'implémentation réelle, il semble qu'il soit courant d'analyser l'URL à ce moment et d'assembler les informations de destination de connexion.

Dans l'exemple de code, il est implémenté avec ʻUnsupportedOperationException` sauf là où il est décrit. Vous devez le remplacer par le code réel si nécessaire.

github: https://github.com/koduki/jdbc-skeleton/blob/master/src/main/java/cn/orz/pascal/jdbc/MyDriver.java

package cn.orz.pascal.jdbc;

public class MyDriver implements Driver {
    private static final String URI_PREFIX = "jdbc:myjdbc://";

    static {
        try {
            java.sql.DriverManager.registerDriver(new MyDriver());
        } catch (SQLException ex) {
            throw new RuntimeException("Can't register driver!");
        }
    }

    @Override
    public Connection connect(String url, Properties info) throws SQLException {
        if (!url.startsWith(URI_PREFIX)) {
            return null;
        }
        return new MyConnection(url, info);
    }

-Abréviation-

Connection

Connection crée une déclaration. Dans l'implémentation réelle, la connexion est maintenue dans les unités de connexion, donc je pense que vous irez à la connexion avec un constructeur etc.

github: https://github.com/koduki/jdbc-skeleton/blob/master/src/main/java/cn/orz/pascal/jdbc/MyConnection.java

package cn.orz.pascal.jdbc;

public class MyConnection implements Connection {
    public MyConnection(String uri, Properties info) throws SQLException {
        System.out.println("jdbc uri: " + uri);
    }

    @Override
    public void close() throws SQLException {
        System.out.println(this.getClass().getSimpleName() + " close");
    }

    @Override
    public Statement createStatement() throws SQLException {
        return new MyStatement();
    }

-Abréviation-

Statement

La déclaration traite les requêtes. L'analyseur SQL doit être appelé ici. Au fait, comme I / F ne fait que passer une chaîne de caractères, il est possible de passer une requête autre que SQL sans aucun problème.

Le mannequin mappe la liste de liste au ResultSet et le renvoie.

github: https://github.com/koduki/jdbc-skeleton/blob/master/src/main/java/cn/orz/pascal/jdbc/MyStatement.java

package cn.orz.pascal.jdbc;

public class MyStatement implements java.sql.Statement {

    @Override
    public boolean execute(String sql) throws SQLException {
        System.out.println("execute sql: " + sql);

        return true;
    }

    @Override
    public ResultSet executeQuery(String sql) throws SQLException {
        System.out.println("execute sql: " + sql);
        
        var result = new MyResultSet(List.of(
                List.of("a", "b", "c"),
                List.of("e", "f", "g"),
                List.of("h", "i", "j")
        ));
        return result;
    }

    @Override
    public void close() throws SQLException {
        System.out.println(this.getClass().getSimpleName() + " close");
    }

-Abréviation-

ResultSet

ResultSet est le résultat de l'exécution de la requête. Dans le mannequin, il est implémenté en enveloppant l'itérateur.

Dans le code actuel, les données réelles seront traitées ici, mais comme la base de données est généralement volumineuse, il sera nécessaire de l'implémenter comme un itérateur plutôt que comme une liste.

github: https://github.com/koduki/jdbc-skeleton/blob/master/src/main/java/cn/orz/pascal/jdbc/MyResultSet.java

package cn.orz.pascal.jdbc;

public class MyResultSet implements java.sql.ResultSet {

    private final Iterator<List<String>> itr;
    private List<String> current;

    public MyResultSet(List<List<String>> source) {
        this.itr = source.iterator();
    }

    @Override
    public String getString(int index) throws SQLException {
        return current.get(index - 1);
    }

    @Override
    public boolean next() throws SQLException {
        var result = itr.hasNext();

        if (result) {
            current = itr.next();
        }
        return result;
    }

-Abréviation-

Résumé

Eh bien, quand je l'ai essayé, j'ai pu implémenter le pilote JDBC plus facilement que prévu. Je pensais que ce serait plus difficile, donc je suis un peu désaccordé, mais cela signifie que l'I / F est bien implémenté.

Si vous pouvez pirater le pilote JDBC, vous pouvez raccorder SQL et le sortir dans le journal, le convertir en Proxy et l'ignorer dans une autre base de données, ou le connecter à KVS ou à une autre implémentation de base de données sans difficulté, y compris ORM tel que JPA.

Comme il existe de nombreuses API, il semble qu'il faudra un peu de patience pour l'implémenter sérieusement, mais s'il s'agit d'un type qui encapsule le JDBC réel, cela semble relativement facile à faire.

Cela semble utile, il semble donc bon de le mettre dans la boîte à outils.

Alors bon piratage!

référence

Recommended Posts

Comment créer un pilote JDBC
Comment créer un conteneur Java
Comment créer un écran de démarrage
Comment créer un plug-in Jenkins
Comment faire un projet Maven
Comment créer un tableau Java
Comment créer un robot Discord (Java)
Comment faire un pot ombré
Comment créer un JRE léger pour la distribution
Comment laisser un commentaire
[Rails] Comment faire des graines
Comment insérer une vidéo
Comment créer une méthode
Comment créer une URL JDBC (Oracle Database, Thin)
Comment faire fonctionner JavaScript sur une page spécifique
Comment faire un cache sans trop réfléchir
Comment faire un MOD pour Slay the Spire
Essayez de faire un simple rappel
Remarques sur l'utilisation de Spring Data JDBC
Comment signer Minecraft MOD
Apprendre Ruby avec AtCoder 13 Comment créer un tableau à deux dimensions
[Swift] Comment envoyer une notification
Essayez de créer un itérateur qui puisse être vu
[Android] Comment créer un fragment de dialogue
Comment créer un hinadan pour un projet Spring Boot à l'aide de SPRING INITIALIZR
Comment créer un fichier jar sans dépendances dans Maven
Comment identifier le chemin sur lequel il est facile de se tromper
Comment faire un diamant révolutionnaire en utilisant Java pour déclaration wwww
Comment exécuter un contrat avec web3j
Comment trier une liste à l'aide du comparateur
[Basique] Comment écrire un auto-apprentissage Dockerfile ②
Comment insérer une vidéo dans Rails
Comment ajouter un nouveau hachage / tableau
[Introduction à Java] Comment écrire un programme Java
Comment créer un référentiel Maven pour 2020
[Swift5] Comment créer un écran de démarrage
[rails] Comment créer un modèle partiel
Comment publier une bibliothèque dans jCenter
[SpringBoot] Comment écrire un test de contrôleur
Réglage des performances JVM: qu'est-ce que le réglage et comment élaborer un bon plan
Comment créer une application avec un mécanisme de plug-in [C # et Java]
Rails: comment bien écrire une tâche de râteau
Comment créer une base de données H2 n'importe où
[Rails] Comment écrire lors de la création d'une sous-requête
[Rails] Comment créer un graphique à l'aide de lazy_high_charts
[Android] Comment convertir une chaîne de caractères en resourceId
Faire une marge à gauche du TextField
Comment obtenir un heapdump à partir d'un conteneur Docker
Comment afficher une page Web en Java
Comment réduire l'image de Spring Boot Docker
Comment supprimer un contrôleur, etc. à l'aide d'une commande
[Ethereum] Comment exécuter un contrat en utilisant web3j-Part 2-