Je pense que c'est un sujet trop précis et faible, mais je l'ai écrit.
La commande de copie PostgreSQL est Vous pouvez traiter à grande vitesse lors du stockage du fichier dans la table. Cependant, bien que le CSV puisse être enregistré tel quel, Si vous souhaitez compléter la valeur
Donc, si vous traitez dans l'ordre, Comme l'écriture dans le stockage s'exécute deux fois (fichier et base de données), Je pense qu'il vaut mieux l'unifier et le mettre en œuvre.
Cela ressemble à ceci dans une écriture simple,
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;
}
Passer la connexion à CopyManager Créer une instance de l'interface de classe CSV Reader Passez-le à CopyIn et versez-le. À ce stade, on suppose que le CSV a la structure de colonne de la table telle quelle.
Créez votre propre lecteur et J'ai pensé ajouter une colonne système au moment de la lecture, Créez une classe Reader qui implémente la méthode Read suivante.
public class CsvFileWithSysColReader extends Reader {
/**File d'attente pour stocker des chaînes de caractères avec des colonnes*/
private final Queue<Character> csvBuffer;
/**Je vais le définir avec un argument dans le constructeur Reader de CSV*/
private final BufferedReader reader = new ArrayDeque<>();
//~~ Abréviation ~~
/**
*constructeur
*
* @lecteur de paramètres Lecteur tamponné
* @throws IOException
*/
public CsvFileWithSysColReader(final BufferedReader reader)
throws IOException {
//Il peut être bon d'avoir un booléen tel que skipPeader dans l'argument pour avoir une fonction de saut d'en-tête.
this.reader = reader;
}
@Override
public int read(final char[] cbuf, final int off, final int len) throws IOException {
int readCount = len;
//Si la taille du tampon de lecture CSV est inférieure au nombre de chiffres lus par la commande Copier, lisez le fichier.
while (this.csvBuffer.size() < len) {
//S'il s'agit du dernier du fichier, quittez et renvoyez uniquement le nombre actuel de chiffres.
if (loadLine() == 0) {
readCount = this.csvBuffer.size();
break;
}
}
//S'il y a une lecture, le nombre de chiffres est renvoyé.
if (readCount != 0) {
for (int i = off; i < readCount; i++) {
cbuf[i] = this.csvBuffer.poll();
}
return readCount;
} else {
//Sinon, à la fin-Retour 1.
return -1;
}
}
/**
*Charge de ligne
*
* @return Load result nombre de caractères
* @throws IOException
*/
private int loadLine() throws IOException {
final String line = this.reader.readLine();
if (line == null) {
//S'il n'y a pas de ligne d'acquisition, 0 est renvoyé et le processus se termine.
return 0;
} else {
//addSysCol: une fonction qui ajoute des colonnes système, modifiez-les comme vous le souhaitez.
//Il est également possible d'ajouter une colonne d'erreur en vérifiant ici
final String lineWithSysCol= addSysCol(line);
for (int i = 0; i < lineWithSysCol.length(); i++) {
this.csvBuffer.add(lineWithSysCol.charAt(i));
}
return lineWithSysCol.length();
}
}
//~~ Abréviation ~~
}
Et exécutez comme ça.
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;
}
L'implémentation ci-dessus de CsvFileWithSysColReader.addSysCol (ligne de chaîne) étend la plage comme suit.
Dans le développement d'applications Les E / S sont souvent fixes, donc Si vous créez une classe d'habillage avec Interface et absorbez le traitement là-bas Il y a beaucoup de choses à faire.
Au fait En fait, je l'ai implémenté avec diverses fonctions, J'ai abandonné la fonction à partir de là et n'ai écrit que les points principaux, Je suis désolé s'il y a une omission. .. ..