Ausführen des Postgresql-Kopierbefehls mit Spalteninformationen in Java

Einführung

Ich finde, dass es als Thema zu genau und zu schwach ist, aber ich habe es geschrieben.

Der PostgreSQL-Kopierbefehl lautet Sie können mit hoher Geschwindigkeit verarbeiten, wenn Sie die Datei in der Tabelle speichern. Obwohl CSV so registriert werden kann, wie es ist, Wenn Sie den Wert vervollständigen möchten

  1. Lesen Sie die CSV-Datei.
  2. Erstellen Sie eine CSV-Datei mit Spalten.
  3. Führen Sie den Kopierbefehl mit CopyManager aus, um die CSV zu laden.

Wenn Sie also in der richtigen Reihenfolge arbeiten, Da das Schreiben in den Speicher zweimal ausgeführt wird (Datei und DB), Ich denke, es ist besser, es zu vereinheitlichen und umzusetzen.

So führen Sie den Kopierbefehl in Java naiv aus

Es sieht so aus in einfachem Schreiben,

  public static long copy(Connection conn, String filePath, String tableName) throws Exception {
    CopyManager copyManager = new CopyManager((BaseConnection) conn);
    Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "UTF8"));
    String sql = "copy " + tableName + " FROM STDIN WITH DELIMITER ','";
    long result = copyManager.copyIn(sql, reader);
    reader.close();
    return result;    
  }

Übergeben Sie die Verbindung an CopyManager Erstellen Sie eine Instanz der CSV Reader-Klassenschnittstelle Übergeben Sie es an copyIn und gießen Sie es ein. Zu diesem Zeitpunkt wird davon ausgegangen, dass die CSV die Spaltenstruktur der Tabelle unverändert hat.

Wo soll ich es geben?

Erstellen Sie Ihren eigenen Reader und Ich dachte, ich würde zum Zeitpunkt des Lesens eine Systemspalte hinzufügen. Erstellen Sie eine Reader-Klasse, die die folgende Read-Methode implementiert.

public class CsvFileWithSysColReader extends Reader {
  /**Warteschlange zum Speichern von Zeichenketten mit Spalten*/
  private final Queue<Character> csvBuffer;
  /**Ich werde es mit einem Argument im Reader-Konstruktor von CSV setzen*/
  private final BufferedReader reader = new ArrayDeque<>();
//~~ Abkürzung ~~
  /**
   *Konstrukteur
   * 
   * @param reader Buffered Reader zum Umschließen
   * @throws IOException
   */
  public CsvFileWithSysColReader(final BufferedReader reader)
      throws IOException {
    //Es kann gut sein, einen Booleschen Wert wie skipPeader im Argument zu haben, um eine Header-Sprungfunktion zu haben.
    this.reader = reader;
  }

  @Override
  public int read(final char[] cbuf, final int off, final int len) throws IOException {
    int readCount = len;
    //Wenn die Größe des CSV-Lesepuffers geringer ist als die Anzahl der vom Befehl Kopieren gelesenen Stellen, lesen Sie aus der Datei.
    while (this.csvBuffer.size() < len) {
      //Wenn es der letzte Teil der Datei ist, beenden Sie und geben Sie nur die aktuelle Anzahl von Ziffern zurück.
      if (loadLine() == 0) {
        readCount = this.csvBuffer.size();
        break;
      }
    }
    //Bei einem Lesevorgang wird die Anzahl der Ziffern zurückgegeben.
    if (readCount != 0) {
      for (int i = off; i < readCount; i++) {
        cbuf[i] = this.csvBuffer.poll();
      }
      return readCount;
    } else {
      //Wenn nicht, am Ende-Rückgabe 1.
      return -1;
    }
  }

  /**
   *Zeilenlast
   * 
   * @return Lade Ergebnis Anzahl der Zeichen
   * @throws IOException
   */
  private int loadLine() throws IOException {
    final String line = this.reader.readLine();
    if (line == null) {
      //Wenn keine Erfassungszeile vorhanden ist, wird 0 zurückgegeben und der Prozess beendet.
      return 0;
    } else {
      //addSysCol: Eine Funktion, die Systemspalten hinzufügt und nach Belieben bearbeitet.
      //Es ist auch möglich, eine Fehlerspalte hinzuzufügen, indem Sie hier nachsehen
      final String lineWithSysCol= addSysCol(line);
      for (int i = 0; i < lineWithSysCol.length(); i++) {
        this.csvBuffer.add(lineWithSysCol.charAt(i));
      }
      return lineWithSysCol.length();
    }
  }
//~~ Abkürzung ~~
}

Und so ausführen.

  public static long copy(final Connection conn, final String filePath, final String tableName) throws Exception {
    final CopyManager copyManager = new CopyManager((BaseConnection) conn);
    final Reader reader = new CsvFileWithSysColReader(new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "UTF8")));
    final String sql = "copy " + tableName + " FROM STDIN WITH DELIMITER ','";
    final long result = copyManager.copyIn(sql, reader);
    reader.close();
    return result;    
  }

Die obige Implementierung von CsvFileWithSysColReader.addSysCol (String line) erweitert den Bereich wie folgt.

  1. Geben Sie Informationen, die nicht in CSV enthalten sind, von außen weiter.
  2. Überprüfen Sie die Tabellenspalte und legen Sie sie fest, um die Ergebnisse zu laden
  3. Schneiden Sie den Überlauf der Ziffern entsprechend der Anzahl der Ziffern in der Tabellenspalte
  4. Seriennummern nummerieren
  5. etc...

abschließend

In der Anwendungsentwicklung E / A ist also oft behoben Wenn Sie mit Interface eine Wrap-Klasse erstellen und dort die Verarbeitung übernehmen Es gibt viele Dinge, die getan werden können.

Apropos Eigentlich habe ich es mit verschiedenen Funktionen implementiert, Ich ließ die Funktion von dort fallen und schrieb nur die Hauptpunkte, Es tut mir leid, wenn es eine Auslassung gibt. .. ..

Recommended Posts

Ausführen des Postgresql-Kopierbefehls mit Spalteninformationen in Java
[Java] Wie man Aufgaben regelmäßig ausführt
So wechseln Sie die Java-Version mit direnv im Terminal auf dem Mac
So überprüfen Sie, ob Java auf einem Mac installiert ist
So kompilieren Sie Java mit VsCode & Ant
[Java] Fassen Sie zusammen, wie Sie mit der Methode equals vergleichen können
So wechseln Sie Java-Versionen auf dem Mac
[Java] So testen Sie, ob es in JUnit null ist
Verwendung des Java-Frameworks mit AWS Lambda! ??
Verwendung der Java-API mit Lambda-Ausdrücken
[Java] Memo zum Schreiben der Quelle
Aufrufen von Funktionen in großen Mengen mit Java Reflection
Wie man javafx mit Raspeye ausführt veröffentlicht am 12.07.2020
[Java 11] Ich habe versucht, Java auszuführen, ohne mit Javac zu kompilieren
[Java] So lassen Sie die Federkonstruktorinjektion mit Lombok weg
So stellen Sie Java mit Serverless Framework für AWS Lambda bereit
Verwendung der nicht standardmäßigen Java-Bibliothek in IntelliJ IDEA
[Ruby on Rails] So ändern Sie den Spaltennamen
[Java] Verschlüsselung mit AES-Verschlüsselung mit Standardbibliothek
Führen Sie PostgreSQL unter Java aus
Stand April 2018 So installieren Sie Java 8 auf einem Mac
Verbinden von Java-Anwendung und PostgreSQL mit JDBC ohne Verwendung von Eclipse (wird an der Eingabeaufforderung ausgeführt)
So erstellen Sie eine Java-Entwicklungsumgebung mit VS Code
So führen Sie Java EE Tutial auf Github unter Eclipse aus
Einführung in den Java-Befehl
Ausführen des WebCamCapture-Beispiels von NyARToolkit für Java
[Java] So unterbrechen Sie eine Zeile mit StringBuilder
Hinweise zur Verwendung regulärer Ausdrücke in Java
Was tun, wenn Sie den Befehl "Java-Paketname / Klassenname" nicht ausführen können?
So entwickeln Sie eine App mit der Jersey Java RESTful API auf einer Alibaba Cloud ECS-Instanz
So reduzieren Sie die Programmlast ein wenig, wenn Sie Zeichen mit JAVA kombinieren
So kehren Sie die Kompilierung der Apk-Datei in Java-Quellcode mit MAC um
Verwendung des mit Tensorflow 2.0 trainierten Modells mit Kotlin / Java
So behandeln Sie Ausnahmen mit Java 8 Stream oder Optional kühl
So stellen Sie eine einfache Java-Servlet-App auf Heroku bereit
So stellen Sie eine Kotlin (Java) -App auf AWS fargate bereit
So installieren Sie Java9 unter ElementaryOS Freya oder Ubuntu 14.04 LTS
So wechseln Sie Java in der OpenJDK-Ära auf dem Mac
Erste Schritte mit JDBC mit PostgresSQL unter MacOS
Untersucht, wie Dienste mit Watson SDK für Java aufgerufen werden
So senken Sie die Java-Version
[Java] Verwendung von Map
So deinstallieren Sie Java 8 (Mac)
Java zum Spielen mit Function
Java - So erstellen Sie JTable
Verwendung von Java Optional
Wie man mit Heroku einsetzt
So minimieren Sie Java-Images
Externe Befehlsausführung mit Swift
Wie schreibe ich einen Java-Kommentar
Verwendung der Java-Klasse
Stellen Sie eine Verbindung von Java zu PostgreSQL her
[Java] Verwendung von removeAll ()
[Java] So zeigen Sie Wingdings an
Wie man mit html.erb nummeriert (nummeriert)
Verwendung von Java Map
So aktualisieren Sie mit activerecord-import