Zunächst werden drei JDBC -Batch -Insertion -Programmiermethoden eingeführt, um sie zu vergleichen. Der spezifische Inhalt ist wie folgt
Das Einfügen von JDBC -Stapeln wird hauptsächlich für den Datenimport und Protokollieren verwendet, da Protokolle im Allgemeinen zuerst in der Datei geschrieben sind.
Ich habe den JDBC -Treiber von MySQL 5.1.5 verwendet, um drei häufig verwendete Methoden zu testen
Methode 1: Verwenden Sie vorbereitete Stellungen zum Hinzufügen von Stapeln
try {class.forname ("com.mysql.jdbc.driver"); conn = driverManager.getConnection (O_url, Benutzername, Passwort); conn.setAutocommit (false); String SQL = "Adlogs (IP, Website, Yyyymmdd, Stunde, Object_id) Werte (?,?,?,?,?)"; PrepectStatement past = conn.preparestatement (SQL, resultset.type_scroll_sensitive, resultset.concur_read_only); für (int x = 0; x <size; x ++) {prest.setString (1, "192.168.1.1"); prest.setstring (2, "localhost"); Prest.SetString (3, "20081009"); Prest.Setint (4, 8); Prest.SetString (5, "11111111"); prest.addbatch (); } prest.executebatch (); conn.commit (); conn.close (); } catch (SQLEXception ex) {logger.getLogger (myLogger.class.getName ()). log (Level.Severe, null, ex); } catch (classNotFoundException ex) {logger.getLogger (myLogger.class.getName ()). log (Level.Severe, null, ex); } Erläutern Sie die Bedeutung der folgenden zwei Parameter beim Erstellen einer Anweisung:
Der erste Parameter gibt den Typ des Ergebnissets an. Die Optionen sind:
Type_forward_only: Standardtyp. Der Vorwärtszugriff ist nur einmal zulässig und wird nicht durch Änderungen anderer Benutzer in der Datenbank beeinflusst.
Type_scroll_inemsitiv: Ermöglicht die Vorwärts- oder Rückwärtsbewegung in der Liste und sogar eine spezifische Positionierung, z. Es wird nicht durch Änderungen anderer Benutzer in der Datenbank beeinflusst.
Type_scroll_sensitive: wie type_scroll_insensitive ist die Positionierung in Datensätzen zulässig. Dieser Typ wird durch Änderungen anderer Benutzer beeinflusst. Wenn der Benutzer nach der Ausführung der Abfrage einen Datensatz löscht, verschwindet dieser Datensatz aus dem Ergebnis. In ähnlicher Weise werden Änderungen der Datenwerte im Ergebnissensatz widerspiegelt.
Der zweite Parameter legt die Parallelität des Ergebnisses fest, wodurch festgelegt wird, ob das Ergebnis aktualisiert werden kann. Die Optionen sind:
Concur_read_only: Dies ist der Standardwert, angegeben, dass er nicht aktualisiert werden kann
Ergebnisset Concur_UpDatable: Gibt an, dass das Ergebnis set aktualisiert werden kann
Methode 2: Verwenden Sie die Anweisung, um die Stapelmethode hinzuzufügen
conn.setAutocommit (false); Anweisung STMT = Conn.CreateStatement (resultSet.type_scroll_sensitive, resultset.concur_read_only); für (int x = 0; x <size; x ++) {stmt.addbatch ("in Adlogs (IP, Website, Yyyymmdd, Stunde, Object_id) Werte ('192.168.1.3', 'localhost', '20081009', 8, 23123 ')") "); } stmt.executebatch (); conn.commit ();Methode 3: Verwenden Sie die Anweisung direkt
conn.setAutocommit (false); Anweisung STMT = Conn.CreateStatement (resultSet.type_scroll_sensitive, resultset.concur_read_only); für (int x = 0; x <size; x ++) {stmt.execute ("in adlogs (ip, Website, yyyymmdd, stunde, Object_id) Werte ('192.168.1.3', 'localhost', '20081009', 8, 23123 ')") "); } conn.commit (); Die durchschnittliche Testzeit für das Einfügen von 100.000 Datenstücken unter Verwendung der obigen Methode ist:
Methode 1: 17.844s
Methode 2: 18.421s
Methode 3: 16.359s
Es ist ersichtlich, dass die Einführung von JDBC -Batch -Anweisungen nicht nur die Leistung verbessert, sondern auch langsamer ist, als wenn keine Stapel verwendet wird. Dies kann natürlich mit der Implementierungsmethode der spezifischen Treiber von JDBC zusammenhängen. Der Anhang ist mein Testcode, mit dem auf meinem Computer ausgeführt werden kann.
Bei der Durchführung der Stapelinsertion ist das Wichtigste, die Einreichung automatisch zu stornieren. Daher sollte es keine Rolle spielen, ob die Stapel -Syntax von JDBC verwendet wird oder nicht.
Conn.SetAutoCommit (Falsch)
Ich persönlich denke, die erste Methode ist die bequemste und praktischste.
Beispiel Erläuterung von JDBC -Stapel -Einfügungsdaten :
Kürzlich, als ich an einem Programm arbeitete, um Excel -Daten in eine Datenbank zu importieren, bereitete ich mich auf die Verwendung von JDBC -Batch -Einfügen aufgrund der großen Datenmenge vor. So wird vorbereitungen.addbatch () verwendet; Wenn 1W -Datenstücke hinzugefügt werden, wird der Einfügungsvorgang durchgeführt, präpariert. EXECUTEBATCH () wird verwendet. Ich dachte, das wäre schnell, aber ich brauchte mehr als 30 Minuten, um 65.536 Datenstücke einzufügen, was meinen Erwartungen völlig übereinstimmte. Also fragte ich meine Kollegen, wie sie diese Art von Daten im großen Maßstab verarbeitet hätten. Ich stellte fest, dass sie auch die Verarbeitung von JDBC -Stapelinsertion verwendeten, aber im Gegensatz zu mir haben sie Con.SetAutocommit (False) verwendet. dann preparedStatement.executebatch () und dann con.commit () ausgeführt; Also habe ich es erneut versucht, was ist ein Wunder? Es dauerte nur eine halbe Stunde, um diese Daten zu importieren, und nachdem diese beiden Sätze hinzugefügt wurden, dauerte es nur 15 Sekunden, um sie zu vervollständigen. Also habe ich den Grund überprüft und die folgende Erklärung online gefunden:
* Stellen Sie beim Importieren von Daten in InnoDB sicher, dass MySQL keinen automatischen Modus aktiviert hat
Benötigt für jeden Einsatz eine Protokollspülung, um die Festplatte zu diskutieren. Um das AutoCommit während Ihres Importbetriebs zu deaktivieren, umgeben Sie sie mit
Setzen Sie autocommit und begehen Sie Aussagen:
Setzen Sie AutoCommit = 0;
... SQL Import -Anweisungen ...
BEGEHEN;
Das erste Mal liegt genau daran, dass es kein SetAutocommit (Falsch) gibt; Für jede Einfügungsanweisung wird ein Protokoll auf die Festplatte generiert. Obwohl der Batch -Einsatz eingestellt ist, ist sein Effekt wie ein einzelner Einsatz, was zu einer sehr langsamen Einfügung führt.
Einige der Codes sind wie folgt:
String SQL = "In Tabelle *****"; con.setAutoCommit (False); // einmal 1W -Datensätze einfügen if (i % 10000 == 0) {ps.executebatch (); con.commit (); }} // weniger als 1W Daten ps.Executebatch () einfügen; con.commit ();Das obige ist nur eine Beilage, und dann folgt "servieren": folgt:
1. Testen Sie das Schreiben von Stapeldaten
Long start = system.currentTimemillis (); DaoreCord DaoreCord = new DaoreCord (); Liste <T> list = new ArrayList <T> (); für (int i = 1; i <= 1000; i ++) {für (int j = 1; j <= 1000; j ++) {t t = new t (); T.Seti (i); T.Setj (j); list.add (t); }} daoreCord.insertBatch (Liste); System.out.println ("zeitaufwändig:" + (System.currentTimemillis ()-Start) + "MS"); 2. Batch -Schreibdatentest
public void InsertBatch (Liste <T> Liste) {String sql = "In t (go, zurück) Werte (?,?)" einfügen; Dbhelper dbh = new dbhelper (SQL); Verbindung conn = dbh.returnconn (); Versuchen Sie {conn.setAutocommit (false); // Beachten Sie, dass dieser Satz falsch sein muss. Siehe die erste Referenz, die vorbereitet wurde. für (int i = 0; i <list.size (); i ++) {ps.setint (1, list.get (i) .geti ()); ps.Setint (2, list.get (i) .getJ ()); ps.addbatch (); if (i % 10000 == 0) {ps.executebatch (); conn.commit (); }} ps.executebatch (); conn.commit (); conn.close (); } catch (SQLEXception e) {// Todo automatisch erzeugt Catch Block e.printstacktrace (); }}Datentabelle:
Experimentelle Ergebnisse:
Das Obige dreht sich alles um diesen Artikel, ich hoffe, es wird für das Lernen aller hilfreich sein.