La procédure lors de l'insertion des données de dictionnaire d'Eijiro dans une table Oracle est décrite. Cette fois, je vais extraire le mot information du fichier HTML créé la dernière fois et l'insérer dans la base de données.
Si vous écrivez simplement ce que vous voulez faire
WordInserter.java
package word;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jsoup.Jsoup;
import word.sql.WordDictionarySql;
public class WordInserter {
private static String WORD_DICTIONARY =
"C:/Users/*****/Desktop/puisan_102.txt";
private static int LIMMIT = 10000;
public static void main(String args[])throws Exception{
long start = System.currentTimeMillis();
System.out.println("Le processus de création de liste démarre");
List <Object[]>list =getDictionarySource()
.stream().collect(Collectors.toList());
long end = System.currentTimeMillis();
System.out.println("Le processus de création de la liste est terminé");
System.out.println(String.format("temps de traitement%d secondes",(end-start)/1000));
start = System.currentTimeMillis();
System.out.println("Démarrer le traitement de la base de données");
OperateDB.createConnection();
operateList(list);
end = System.currentTimeMillis();
System.out.println("Le processus de création de base de données est terminé");
System.out.println(String.format("temps de traitement%d secondes",(end-start)/1000));
OperateDB.closeConnection();
}
//Une fonction qui utilise Jsoup pour analyser les balises HTML et lister les résultats
public static List<Object[]> getDictionarySource(){
try{
return Jsoup.parse(new File(WORD_DICTIONARY),"UTF-8")
//Récupère tous les éléments enfants appartenant à la balise tr
.getElementsByTag("tr")
.stream()
//Obtient le texte de l'élément enfant appartenant à la balise tr et
//Structure de données pouvant être insérée dans le DB à l'aide de la fonction de carte
//(Dans ce cas, Object[])Convertir en
.map(s->new DictionaryWord(
s.getAllElements().eachText()).params)
//Liste afin qu'elle puisse être insérée avec un lot de QueryLinner<Object[]>
//Agréger à
.collect(Collectors.toList());
}catch(Exception e){
e.printStackTrace();
return new ArrayList<Object[]>();
}
}
//Exécuter le traitement d'insertion par unités de 10000 pour la liste passée en argument
public static void operateList(List<Object[]> word){
Stream.iterate(1, s->s+1)
.limit((int)Math.ceil(word.size()/LIMMIT))
.forEach(i->executeSQL(word,i));
}
public static void executeSQL(List<Object[]>list,int from){
if(list.size()<((from+1)*LIMMIT))
WordDictionarySql.insertToWordDictionary(
list.subList(from*LIMMIT, list.size()));
else
WordDictionarySql.insertToWordDictionary(
list.subList((from-1)*LIMMIT, from*LIMMIT));
}
public static class DictionaryWord{
public long wordIndex;
public int wordLevel;
public String word;
public String searchWord;
public String meaning;
public String shortVer;
public Object[] params=new Object[6];
public DictionaryWord(List<String>list){
this.wordIndex = Long.parseLong(list.get(1));
params[0] = this.wordIndex;
this.wordLevel = Integer.parseInt(list.get(3).replaceAll("■", ""));
params[1] = this.wordLevel;
this.word = list.get(2);
params[2] = this.word;
this.searchWord = list.get(2).toLowerCase();
params[3] = this.word;
this.meaning = list.get(4);
params[4] = this.meaning;
this.shortVer = list.get(4).length()>1000?
list.get(4).substring(0,1000):list.get(4);
params[5] = this.shortVer;
}
public String toString(){
String format = "wordIndex=%d wordLevel=%d "
+ "word=%s meaning=%s shortVer=%s ";
return String.format(format,this.wordIndex,this.wordLevel,
this.word,this.meaning,this.shortVer);
}
}
}
Je suis surpris que le DOM créé à la suite de l'analyse de Jsoup et la fonction Java 8 Stream soient trop compatibles. Ce ne serait pas génial sans la fonction Stream, mais peut-être que je ne pensais pas l'implémenter en Java (Dans ce cas, je pense que j'utilisais du rubis)
Passez simplement la liste de List \ <Ojbect [] > reçue comme argument à OperateDB # insert créé dans Article précédent.
WordDictionarySql.java
package word.sql;
import java.util.List;
import word.OperateDB;
public class WordDictionarySql {
public static String INSERT_SQL = "insert into WORD_DICTIONAY "
+ "(WORD_INDEX,WORD_LEVEL,WORD,SEARCH_WORD,MEANING,SHORT_VER) values(?,?,?,?,?,?)";
public static void insertToWordDictionary(List<Object[]> word){
try{
OperateDB.insert(word,INSERT_SQL);
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException("Une erreur s'est produite lors du traitement de l'insertion de DB");
}
}
}
J'ai mis environ 330 000 données dans la table Oracle, mais le temps d'exécution était d'environ 102 secondes. À propos, lorsque l'autocommit était activé, le temps d'exécution était environ deux fois plus long que 230 secondes. J'ai pu me rendre compte du haut des chiffres que l'activation de l'autocommit réduirait les performances.
Recommended Posts