J'avais l'habitude de sauvegarder la collecte de données de tweet dans sqlite en utilisant python, Un mémo que j'ai recherché de différentes manières car je voulais le faire à grande vitesse tout en multi-threading avec java.
Lorsque vous traitez avec sqlite Utiliser sqlite-jdbc est facile, alors prenez-le de maven et utilisez-le.
Au départ, je collectais des données sur le disque dur,
Je me suis demandé pourquoi c'était si lent et qu'il fallait beaucoup de temps pour ajouter des bases de données plutôt que de les collecter.
J'ai cherché la cause.
Résolvez un par un
prepareStatement
prenne beaucoup de temps, alors changez-le en ʻINSERT OR IGNORE
.journal_mode
sur MEMORY
et définissez sync_mode
sur ʻOFF`.Exemple d'enregistrement du tweet qui a été dit en premier
DataBase.java
/**
*Enregistrement du conducteur
*/
public static void dbInit() {
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
*paramètres pragma
*Ici 3.Jornal_mode et synchronisation_le mode est défini
*/
public static Properties getProperties() {
Properties prop = new Properties();
prop.put("journal_mode", "MEMORY");
prop.put("sync_mode", "OFF");
return prop;
}
/**
*Traitement à ajouter à la base de données
*Si vous ne mettez pas synchronisé, un verrou mort se produira lors de l'écriture dure avec multi-thread
*/
public static synchronized void putTweet2SQL(File dbFile, List<Status> tweet) {
Statement stmt;
String dbHeader = "jdbc:sqlite:" + dbFile.getAbsolutePath();
PreparedStatement pstmt;
dbInit();
try (Connection conn = DriverManager.getConnection(dbHeader, getProperties())) { //try-with-resources
conn.setAutoCommit(false);
stmt = conn.createStatement();
//Créez si vous n'avez pas de base de données
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS tweets (tweet_id INTEGER PRIMARY KEY, user_id INTEGER, user_screen_name TEXT,tweet_text TEXT)");
//ID Tweet, ID utilisateur, nom d'écran, texte tweet
//2.Se préparer à ajouter des données en masse
pstmt = conn.prepareStatement("INSERT OR IGNORE INTO tweets VALUES (?, ?, ?, ?)");
for (Status status : tweet) {
place = status.getPlace().getFullName();
pstmt.setLong(1, status.getId());
pstmt.setLong(2, status.getUser().getId());
pstmt.setString(3, status.getUser().getScreenName());
pstmt.setString(4, status.getText());
pstmt.addBatch();//1.Ajouter au traitement
}
pstmt.executeBatch();//1.Le processus d'ajout de base de données réel se fait ici
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
Même lors de la lecture à partir de la base de données, setFetchSize
appellera le numéro spécifié à la fois, donc il sera confortable dans une certaine mesure.
DataBase.java
/**
*Recevez des tweets
*Si vous extrayez d'énormes données, le tas sera insuffisant, donc dans ce cas, réécrivez correctement
* @retourner la liste de Tweet
*/
public static List<Status> getTweetsFromSQL(File dbFile) {
String dbHeader = "jdbc:sqlite:" + dbFile.getAbsolutePath();
PreparedStatement pstmt;
List<Status> userDetails = new ArrayList<>();//Liste appropriée
dbInit();
try (Connection conn = DriverManager.getConnection(dbHeader, getProperties())) {
pstmt = conn.prepareStatement("SELECT * FROM tweets");
pstmt.setFetchSize(1000);//Si vous définissez 5000 billions ou quelque chose du genre, vous obtiendrez tout en même temps
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {//ID Tweet, ID utilisateur, nom d'écran, texte tweet
Status status = new status();
status.setId(rs.getLong(1));
status.setUserId(rs.getLong(2));
status.setScreenName(rs.getString(3));
status.setTweetText(rs.getString(4));
}
} catch (SQLException e) {
e.printStackTrace();
}
return userDetails;
}
C'est beaucoup plus rapide et je suis content car je pourrais acheter plus de SSD
Recommended Posts