[JAVA] Insertion des données du dictionnaire d'Eijiro dans Oracle DB part2

Au début

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.

Analyse des informations des fichiers HTML

Chose que tu veux faire

Si vous écrivez simplement ce que vous voulez faire

  1. Utilisez Jsoup pour obtenir les informations textuelles appartenant à l'élément de balise tr
  2. Convertissez les informations textuelles obtenues en 1. en un type (Object []) qui peut être exécuté par la méthode batch de CherryRunner.
  3. Insérez 10 000 listes de List \ <Objects [] > créées en 1. et 2. est

la mise en oeuvre

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

Sentiments divers

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)

Processus d'insertion dans DB

Chose que tu veux faire

Passez simplement la liste de List \ <Ojbect [] > reçue comme argument à OperateDB # insert créé dans Article précédent.

la mise en oeuvre

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

Impressions

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

Insertion des données du dictionnaire d'Eijiro dans Oracle DB part2
Insérez les données du dictionnaire d'Eijiro dans une table Oracle
Insérer des données dans la base de données à l'aide du fichier Yaml
Jusqu'à ce que l'objet S3 soit INSERT dans EC2 DB avec Lambda @ java: Java [Partie 2]
Jusqu'à INSERT S3 objet dans EC2 DB avec Lambda @ java: Java [Partie 1]
Essayez de mettre beaucoup de données dans Cosmos DB
Configurer un conteneur DB2 DB et insérer un peu de données