Frage

Wie kann ich die folgende SQL in einer skalierbaren Art und Weise ausführen mit JdbcTemplate auf mySQL läuft. In diesem Fall skalierbare Mittel:

  1. Nur eine SQL-Anweisung wird auf dem Server ausgeführt
  2. es funktioniert für eine beliebige Anzahl von Zeilen.

Hier ist die Aussage:

INSERT INTO myTable (foo, bar) VALUES ("asdf", "asdf"), ("qwer", "qwer")

Nehmen wir an, ich eine Liste von POJO ist mit foo und bar Felder haben. Ich weiß, dass ich konnte nur Iterierte über die Liste und ausführen:

jdbcTemplate.update("INSERT INTO myTable(foo, bar) VALUES (?, ?)", paramMap)

, aber das nicht nicht das erste Kriterium erfüllen.

Ich glaube, ich könnte auch ausführen:

jdbcTemplate.batchUpdate("INSERT INTO myTable(foo, bar) VALUES (?, ?)", paramMapArray)

aber von dem, was ich sagen kann, das wird nur die SQL einmal kompilieren und es mehrmals ausführen, das erste Kriterium versagt erneut.

Die letzte Möglichkeit, die beiden Kriterien zu passieren scheint, wäre, einfach die SQL mich mit einem StringBuffer zu bauen, aber ich mag, dass vermeiden.

War es hilfreich?

Lösung

Multirow Einsätze ( "Zeilenwert Konstruktoren" verwendet wird) sind in der Tat ein Teil des SQL-92-Standard. Sehen http://en.wikipedia.org/wiki/Insert_(SQL)#Multirow_inserts.

Einige Datenbanken unterstützen diese Syntax nicht, aber viele tun. Nach meiner Erfahrung Derby / Wolkengebilde, DB2, PostgreSQL und die neueren Hypersonic 2. * + Gibt diese unterstützen.

Ihre Besorgnis über diese als PreparedStatement an der Arbeit ist verständlich, aber ich habe Ähnliche Fälle gesehen, wo Frühling JDBC automatisch eine Sammlung von Produkten für bestimmte Abfragen umgehen kann (wie in dem in (?)), Aber ich kann nicht bürgen dieser Fall.

Ich fand einige möglicherweise hilfreiche Informationen an (kann nicht zweiten Link zu diesem Beitrag hinzufügen) die eine Hilfe sein könnte.

Ich kann Ihnen sagen, dass es wahrscheinlich nicht möglich, Ihre zweite Anforderung (Arbeiten für eine beliebige Anzahl von Argumenten) im strengsten Sinne erfüllt sein: jede Datenbank, die ich verwendet habe, tut Abfrage Längenbeschränkungen auferlegen, die ins Spiel kommen würden.

Andere Tipps

Sie können mit BatchPreparedStatementSetter wie unten.

public void insertListOfPojos(final List<MyPojo> myPojoList) {

    String sql = "INSERT INTO "
        + "MY_TABLE "
        + "(FIELD_1,FIELD_2,FIELD_3) "
        + "VALUES " + "(?,?,?)";

    getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {

        @Override
        public void setValues(PreparedStatement ps, int i)
            throws SQLException {

            MyPojo myPojo = myPojoList.get(i);
            ps.setString(1, myPojo.getField1());
            ps.setString(2, myPojo.getField2());
            ps.setString(3, myPojo.getField3());

        }

        @Override
        public int getBatchSize() {
            return myPojoList.size();
        }
    });

}

Sie können auch mit jdbcInsert.executeBatch (sqlParamSourceArray)

versuchen
   // define parameters
jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
jdbcInsert.withTableName("TABlE_NAME");
SqlParameterSource[] sqlParamSourceArray = new SqlParameterSource[apiConsumer
        .getApiRoleIds().size()];
for (int i = 0; i < myCollection.size(); i++) 
    {
  sqlParamSourceArray[i] = new MapSqlParameterSource().addValue("COL1");
      ......................
}
// execute insert
int[] keys = jdbcInsert.executeBatch(sqlParamSourceArray);

Es scheint mir, dass batchupdate () -Methode von JdbcTemplate in diesem Fall hilfreich sein könnte (kopiert von hier http://www.mkyong.com/spring/spring-jdbctemplate-batchupdate-example/ ):

//insert batch example
public void insertBatch(final List<Customer> customers){

  String sql = "INSERT INTO CUSTOMER " +
    "(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";

  getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {

@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
    Customer customer = customers.get(i);
    ps.setLong(1, customer.getCustId());
    ps.setString(2, customer.getName());
    ps.setInt(3, customer.getAge() );
}

@Override
public int getBatchSize() {
    return customers.size();
}

  });
 }

Sie können dies in JDBC nicht tun, period. In MySQL ist es nur syntaktischer Zucker, aber die Wirkung der Erklärung wird das gleiche wie die Ausgabe mehr INSERT-Anweisungen sein. So Sie batchupdate verwenden können, und es wird die gleiche Wirkung haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top