Avatar billede dennism Nybegynder
27. marts 2009 - 00:10 Der er 4 kommentarer og
1 løsning

Java: mySQL VALUES

I mit Java program laver jeg en INSERT til min mySQL database med flere VALUES, f.eks.:

INSERT INTO tasks (colum1, colum2) VALUES (1,2),(1,2),(1,2);

Som det er nu, har jeg en forløkke til at lave dette disse values:
        String taskValues = "";
        for (Task task : this.tasks) {
            taskValues += "(1,2),";
        }
        taskValues = taskValues.substring(0, (taskValues.length()-1));

Værdierne 1,2 er selvfølgelig dynamiske i mit program. I den sidste linie fjerner jeg den sidste char i stringen, så det sidste komma ikke kommer med.

Jeg synes det er en ret grim måde at skulle lave disse sæt af values på. Kan man ikke gøre det smartere?
Avatar billede arne_v Ekspert
27. marts 2009 - 00:48 #1
Der er ikke nogen superløsning.

Jeg kan se to rimelige løsninger:

A)  konkataner som du gør, men brug StringBuilder append fremfor String + og brug prepared statement

B)  indsæt en række ad gangen men bruge transaction/batch til at bundte flere inserts med og brug prepared statement
Avatar billede dennism Nybegynder
27. marts 2009 - 08:21 #2
Kan du prøve at forklare løsning b lidt mere detaljeret - evt. med noget kodeeksempel?
Avatar billede dennism Nybegynder
30. marts 2009 - 17:39 #3
Vil du smide et svar?
Avatar billede arne_v Ekspert
31. marts 2009 - 04:58 #4
gerne
Avatar billede arne_v Ekspert
31. marts 2009 - 04:58 #5
Men et eksempel som viser lidt forskelligt:

package march;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class MySQL {
    private final static int NREC = 10000;
    public static void normal() throws SQLException {
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost/Test", "", "");
        Statement stmt = con.createStatement();
        stmt.executeUpdate("CREATE TABLE t (f1 INTEGER NOT NULL, f2 VARCHAR(50), PRIMARY KEY(f1))");
        long t1 = System.currentTimeMillis();
        PreparedStatement pstmt = con.prepareStatement("INSERT INTO t VALUES(?,?)");
        for (int i = 0; i < NREC; i++) {
            pstmt.setInt(1, i + 1);
            pstmt.setString(2, "Dette er en test !");
            pstmt.executeUpdate();
        }
        pstmt.close();
        long t2 = System.currentTimeMillis();
        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM t");
        rs.next();
        System.out.println("Normal: " + rs.getInt(1) + " records inserted in " + (t2 - t1) + " milliseconds");
        stmt.executeUpdate("DROP TABLE t");
        stmt.close();
        con.close();
    }
    public static void transaction() throws SQLException {
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost/Test", "", "");
        Statement stmt = con.createStatement();
        stmt.executeUpdate("CREATE TABLE t (f1 INTEGER NOT NULL, f2 VARCHAR(50), PRIMARY KEY(f1))");
        long t1 = System.currentTimeMillis();
        con.setAutoCommit(false);
        PreparedStatement pstmt = con.prepareStatement("INSERT INTO t VALUES(?,?)");
        for (int i = 0; i < NREC; i++) {
            pstmt.setInt(1, i + 1);
            pstmt.setString(2, "Dette er en test !");
            pstmt.executeUpdate();
        }
        con.commit();
        pstmt.close();
        long t2 = System.currentTimeMillis();
        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM t");
        rs.next();
        System.out.println("Transaction: " + rs.getInt(1) + " records inserted in " + (t2 - t1) + " milliseconds");
        stmt.executeUpdate("DROP TABLE t");
        stmt.close();
        con.close();
    }
    public static void batch() throws SQLException {
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost/Test", "", "");
        Statement stmt = con.createStatement();
        stmt.executeUpdate("CREATE TABLE t (f1 INTEGER NOT NULL, f2 VARCHAR(50), PRIMARY KEY(f1))");
        long t1 = System.currentTimeMillis();
        con.setAutoCommit(false);
        PreparedStatement pstmt = con.prepareStatement("INSERT INTO t VALUES(?,?)");
        for (int i = 0; i < NREC; i++) {
            pstmt.setInt(1, i + 1);
            pstmt.setString(2, "Dette er en test !");
            pstmt.addBatch();
        }
        pstmt.executeBatch();
        con.commit();
        pstmt.close();
        long t2 = System.currentTimeMillis();
        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM t");
        rs.next();
        System.out.println("Batch: " + rs.getInt(1) + " records inserted in " + (t2 - t1) + " milliseconds");
        stmt.executeUpdate("DROP TABLE t");
        stmt.close();
        con.close();
    }
    public static void dirtyMyISAMHack() throws SQLException {
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost/Test", "", "");
        Statement stmt = con.createStatement();
        stmt.executeUpdate("CREATE TABLE t (f1 INTEGER NOT NULL, f2 VARCHAR(50), PRIMARY KEY(f1)) DELAY_KEY_WRITE=1");
        long t1 = System.currentTimeMillis();
        PreparedStatement pstmt = con.prepareStatement("INSERT INTO t VALUES(?,?)");
        for (int i = 0; i < NREC; i++) {
            pstmt.setInt(1, i + 1);
            pstmt.setString(2, "Dette er en test !");
            pstmt.executeUpdate();
        }
        pstmt.close();
        long t2 = System.currentTimeMillis();
        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM t");
        rs.next();
        System.out.println("Dirty MyISAM hack: " + rs.getInt(1) + " records inserted in " + (t2 - t1) + " milliseconds");
        stmt.executeUpdate("DROP TABLE t");
        stmt.close();
        con.close();
    }
    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        for(int i = 0; i < 3; i++) {
            normal();
            transaction();
            batch();
            dirtyMyISAMHack();
        }
    }
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester