मुख्य सामग्री पर जाएँ
CrossFly 100% ओपन सोर्सGitHub पर फ़ॉलो करें
CrossFlyCrossFly
शुरू करें

यह पृष्ठ पुर्तगाली से मशीन-अनुवादित है और इसमें त्रुटियाँ हो सकती हैं। पुर्तगाली संस्करण प्रामाणिक है।

ट्रांज़ैक्शन और bulkInsert के साथ बड़े पैमाने पर कैसे लिखें

उद्देश्य. उच्च प्रदर्शन के साथ कई पंक्तियाँ डालना/अपडेट करना। ट्रांज़ैक्शन के बिना, प्रत्येक INSERT डिस्क पर एक commit बन जाता है (धीमा)। तीन स्तर हैं: (1) सबकुछ transaction(...) में लपेटना, (2) reset() के साथ एक SqliteStmt पुनः उपयोग करना, (3) bulkInsert उपयोग करना, जो bind/step/reset लूप को नेटिव कोड में करता है (सबसे तेज़)।

उपयोग किए गए APIs

  • SqliteDb.transaction(Runnable body) — body को BEGIN/COMMIT के भीतर चलाता है; यदि body एक RuntimeException फेंके तो स्वचालित ROLLBACK करता है (और पुनः फेंकता है)। परमाणुता के लिए अनुशंसित तरीका।
  • SqliteDb.begin() / commit() / rollback() — ट्रांज़ैक्शन का मैनुअल नियंत्रण (exec("BEGIN"/"COMMIT"/"ROLLBACK") के समतुल्य)। rollback न भूलने के लिए transaction(...) को प्राथमिकता दें।
  • SqliteDb.prepare(String sql) — एक पुनः उपयोग योग्य SqliteStmt तैयार करता है (एक बार कंपाइल करता है)। आपको इसे बंद करना चाहिए (try-with-resources)।
  • SqliteStmt.bindInt/bindLong/bindDouble/bindString/bindBlob/bindNull(idx, v) और bindAll(Object...) — bind 1-based; this लौटाते हैं (fluent)। step() निष्पादित करता है; reset() अगले निष्पादन के लिए तैयार करता है (binds बनाए रखता है; यदि शून्य करना चाहें तो clearBindings() उपयोग करें)।
  • SqliteDb.bulkInsert(String sql, List<Object[]> rows) — sql को एक बार तैयार करता है और प्रत्येक Object[] के लिए एक ही ट्रांज़ैक्शन के भीतर, नेटिव लूप में निष्पादित करता है। संसाधित पंक्तियों की संख्या लौटाता है। प्रत्येक Object[] में प्रत्येक ? पैरामीटर के लिए एक तत्व होता है; स्वीकृत प्रकार: Long/Integer, Double/Float, String, byte[], null। कॉलम के प्रकार पहली पंक्ति से अनुमानित किए जाते हैं — पंक्तियों को समरूप रखें। उपनाम: bulkUpdate, bulkDelete।

statement को पुनः उपयोग क्यों करें? prepare SQL को कंपाइल करता है; प्रत्येक पंक्ति पर prepare दोहराने से पुनः कंपाइल होता है। reset() के साथ पुनः उपयोग करने से एक बार कंपाइल होता है और केवल पुनः bind होता है — बड़े लूप में बहुत तेज़।

पूरा उदाहरण (कॉपी करें, पेस्ट करें और चलाएँ)

package com.exemplo;

import java.util.*;                          // List, ArrayList

import dev.crossfly.ui.*;                     // Window
import dev.crossfly.ui.layout.*;             // VerticalLayout
import dev.crossfly.sqlite.*;                // SqliteDb, SqliteStmt

/** चलाने योग्य मुख्य स्क्रीन। launcher (classname) की ओर संकेत करें और चलाएँ: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      try (SqliteDb db = SqliteDb.open("app.db"))
      {
         db.exec("CREATE TABLE IF NOT EXISTS t(a INTEGER, b TEXT)");

         // विकल्प A — लेन-देन + पुनः उपयोग किया गया statement (निष्पादनों के बीच reset)
         db.transaction(() ->
         {
            try (SqliteStmt st = db.prepare("INSERT INTO t(a, b) VALUES(?, ?)"))
            {
               for (int i = 0; i < 10_000; i++)
               {
                  st.bindInt(1, i)            // idx 1-based
                    .bindString(2, "row" + i)
                    .step();
                  st.reset();                 // अगली पंक्ति के लिए तैयार
               }
            }
         }); // स्वचालित commit; अपवाद होने पर स्वचालित rollback

         // विकल्प B — नेटिव bulkInsert (बड़े वॉल्यूम के लिए सबसे तेज़)
         List<Object[]> rows = new ArrayList<>();
         for (int i = 0; i < 10_000; i++)
            rows.add(new Object[]{ i, "row" + i });   // पहली पंक्ति से अनुमानित प्रकार
         int n = db.bulkInsert("INSERT INTO t(a, b) VALUES(?, ?)", rows);
         System.out.println(n + " linhas inseridas");
      }
   }
}

नीचे दिया गया अंश केवल मुख्य भाग दिखाता है। इसे चलाने के लिए, इसे ऊपर दिए गए MainWindow कंकाल में रखें।

न्यूनतम अंश

// स्रोत में सत्यापित: transaction, prepare + bind (1-based) + step + reset, bulkInsert
import dev.crossfly.sqlite.*;
import java.util.*;

try (SqliteDb db = SqliteDb.open("app.db"))
{
   db.exec("CREATE TABLE IF NOT EXISTS t(a INTEGER, b TEXT)");

   // विकल्प A — लेन-देन + पुनः उपयोग किया गया statement (निष्पादनों के बीच reset)
   db.transaction(() ->
   {
      try (SqliteStmt st = db.prepare("INSERT INTO t(a, b) VALUES(?, ?)"))
      {
         for (int i = 0; i < 10_000; i++)
         {
            st.bindInt(1, i)            // idx 1-based
              .bindString(2, "row" + i)
              .step();
            st.reset();                 // अगली पंक्ति के लिए तैयार
         }
      }
   }); // स्वचालित commit; अपवाद होने पर स्वचालित rollback

   // विकल्प B — नेटिव bulkInsert (बड़े वॉल्यूम के लिए सबसे तेज़)
   List<Object[]> rows = new ArrayList<>();
   for (int i = 0; i < 10_000; i++)
      rows.add(new Object[]{ i, "row" + i });   // पहली पंक्ति से अनुमानित प्रकार
   int n = db.bulkInsert("INSERT INTO t(a, b) VALUES(?, ?)", rows);
   System.out.println(n + " linhas inseridas");
}

और गहराई से जानें

क्या यह पृष्ठ उपयोगी था?