[JAVA] So erstellen Sie einen JDBC-Treiber

Einführung

Ich habe mich gefragt, ob es möglich ist, eine serverlose RDB zu realisieren, aber ich denke, dass es ganz so ist, wenn ich CloudRun verwende. CloudRun kann jedoch kein JDBC sprechen, daher dachte ich, ich sollte meinen eigenen JDBC-Treiber erstellen und HTTP auf der Rückseite verwenden, also habe ich untersucht, wie es gemacht wird.

Überraschenderweise scheint es, dass der JDBC-Treiber einfach erstellt werden kann, daher habe ich vorerst versucht, die minimale Skeleton-Implementierung zu erstellen. Da es auf der Rückseite keine RDB gibt, werde ich im Grunde Folgendes machen, das nur ein Echo zurückgibt.

Ausführungsprozess zum Testen

Lassen Sie uns zunächst eine Hauptklasse erstellen, die sowohl Kaninchen als auch Ecken testet und ausführt. Dies ist ein JDBC-Treiber, der von MyDriver und MyConnection erstellt wurde. Es ist eine einfache Implementierung, die nur bestätigt, dass der Rückgabewert MyConnection ist. Jetzt können Sie jedoch sehen, dass Ihr eigener JDBC-Treiber ordnungsgemäß aufgerufen wird.

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));
        }
    }
}

Das Ausführungsergebnis ist wie folgt.

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

Als nächstes kommt der JDBC-Treiber. Der Punkt ist der "statische" Initialisierer, der die Treiberregistrierung abschließt, wenn die Klasse mit "Class.forName" geladen wird.

Hier können Sie auch die JDBC-URL abrufen. In der tatsächlichen Implementierung scheint es üblich zu sein, die URL zu diesem Zeitpunkt zu analysieren und die Verbindungszielinformationen zusammenzustellen.

Im Beispielcode wird es mit "UnsupportedOperationException" implementiert, sofern nicht anders beschrieben. Sie müssen es bei Bedarf durch den tatsächlichen Code ersetzen.

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);
    }

-Abkürzung-

Connection

Verbindung erstellt eine Anweisung. In der eigentlichen Implementierung wird die Verbindung in der Verbindungseinheit beibehalten, daher denke ich, dass Sie mit einem Konstruktor usw. zur Verbindung gehen werden.

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();
    }

-Abkürzung-

Statement

Anweisung verarbeitet Abfragen. Der SQL-Parser sollte hier aufgerufen werden. Da I / F nur eine Zeichenfolge übergibt, ist es übrigens möglich, problemlos eine andere Abfrage als SQL zu übergeben.

Der Dummy ordnet die Liste der Liste dem ResultSet zu und gibt sie zurück.

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");
    }

-Abkürzung-

ResultSet

ResultSet ist das Ergebnis der Abfrageausführung. Im Dummy wird es durch Umschließen des Iterators implementiert.

Im eigentlichen Code werden die eigentlichen Daten hier behandelt. Da die Datenbank jedoch im Allgemeinen groß ist, muss sie wie ein Iterator und nicht wie eine Liste implementiert werden.

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;
    }

-Abkürzung-

Zusammenfassung

Als ich es ausprobierte, konnte ich den JDBC-Treiber einfacher implementieren als erwartet. Ich dachte, es wäre schwieriger, also bin ich ein bisschen verstimmt, aber es bedeutet, dass das I / F ordentlich implementiert ist.

Wenn Sie den JDBC-Treiber hacken können, können Sie SQL einbinden und in das Protokoll ausgeben, in Proxy konvertieren und in eine andere Datenbank überspringen oder ihn problemlos mit KVS oder einer anderen DB-Implementierung verbinden, einschließlich ORM wie JPA.

Da es viele APIs gibt, scheint es etwas Geduld zu erfordern, sie ernsthaft zu implementieren, aber wenn es sich um einen Typ handelt, der den eigentlichen JDBC umschließt, scheint es relativ einfach zu sein, ihn zu erstellen.

Dies scheint nützlich zu sein, daher scheint es gut, es in den Werkzeugkasten zu legen.

Dann viel Spaß beim Hacken!

Referenz

Recommended Posts

So erstellen Sie einen JDBC-Treiber
So erstellen Sie einen Java-Container
So erstellen Sie einen Begrüßungsbildschirm
So erstellen Sie ein Jenkins-Plug-In
Wie erstelle ich ein Maven-Projekt?
So erstellen Sie ein Java-Array
Wie erstelle ich einen Discord Bot (Java)
Wie man ein schattiertes Glas macht
So erstellen Sie eine leichte JRE für den Vertrieb
Wie hinterlasse ich einen Kommentar?
[Schienen] Wie man Samen macht
So fügen Sie ein Video ein
So erstellen Sie eine Methode
So erstellen Sie eine JDBC-URL (Oracle Database, Thin)
So funktioniert JavaScript auf einer bestimmten Seite
Wie man einen Cache erstellt, ohne zu viel nachzudenken
Wie erstelle ich einen MOD für Slay the Spire?
Versuchen Sie, einen einfachen Rückruf zu tätigen
Hinweise zur Verwendung von Spring Data JDBC
Wie unterschreibe ich Minecraft MOD?
Ruby mit AtCoder lernen 13 So erstellen Sie ein zweidimensionales Array
[Swift] So senden Sie eine Benachrichtigung
Versuchen Sie, einen Iterator zu erstellen, der einen Blick darauf werfen kann
[Android] So erstellen Sie ein Dialogfragment
So erstellen Sie mit SPRING INITIALIZR einen Hinadan für ein Spring Boot-Projekt
So erstellen Sie eine JAR-Datei ohne Abhängigkeiten in Maven
So identifizieren Sie den Pfad, auf dem leicht Fehler gemacht werden können
Wie man einen revolutionären Diamanten mit Java für Aussage macht wwww
So führen Sie einen Vertrag mit web3j aus
So sortieren Sie eine Liste mit Comparator
[Basic] So schreiben Sie ein Dockerfile Selbstlernend ②
So fügen Sie ein Video in Rails ein
So fügen Sie einen neuen Hash / Array hinzu
[Einführung in Java] So schreiben Sie ein Java-Programm
So erstellen Sie ein Maven-Repository für 2020
[Swift5] So erstellen Sie einen Begrüßungsbildschirm
[Rails] So erstellen Sie eine Teilvorlage
So veröffentlichen Sie eine Bibliothek in jCenter
[SpringBoot] So schreiben Sie einen Controller-Test
JVM-Leistungsoptimierung: Was ist Optimierung und wie erstellt man einen guten Plan?
So erstellen Sie eine App mit einem Plug-In-Mechanismus [C # und Java]
Schienen: Wie man eine Rechenaufgabe schön schreibt
So erstellen Sie überall eine H2-Datenbank
[Rails] Wie schreibe ich, wenn ich eine Unterabfrage mache?
[Rails] So erstellen Sie ein Diagramm mit lazy_high_charts
[Android] So konvertieren Sie eine Zeichenfolge in resourceId
Machen Sie einen Rand links vom TextField
So erhalten Sie einen Heapdump aus einem Docker-Container
So zeigen Sie eine Webseite in Java an
So verkleinern Sie das Spring Boot Docker-Image
So löschen Sie einen Controller usw. mit einem Befehl
[Ethereum] So führen Sie einen Vertrag mit web3j-Teil 2 aus