Как мога да използвам следния SQL по мащабируем начин JdbcTemplate работи на mySQL. В този случай мащабируеми означава:
- Само един SQL израз се изпълнява на сървъра
- работи за произволен брой редове.
Ето изявлението:
INSERT INTO myTable (foo, bar) VALUES ("asdf", "asdf"), ("qwer", "qwer")
Да предположим, че имам списък с POJO с foo
и bar
полета. Осъзнавам, че мога просто да прегледам списъка и да изпълня:
jdbcTemplate.update("INSERT INTO myTable(foo, bar) VALUES (?, ?)", paramMap)
но това не постига първия критерий.
Вярвам, че мога да изпълня:
jdbcTemplate.batchUpdate("INSERT INTO myTable(foo, bar) VALUES (?, ?)", paramMapArray)
но от това, което мога да кажа, това просто ще компилира SQL веднъж и ще го изпълни няколко пъти, като отново не успее да изпълни първия критерий.
Крайната възможност, която изглежда да премине и от двата критерия, би била просто да се изгради SQL с a StringBuffer
, но бих искал да избегна това.
Отговори:
4 за отговор № 1Многостранните вложки (използващи "конструктори на стойност на реда") всъщност са част от стандарта SQL-92. виждам http://en.wikipedia.org/wiki/Insert_(SQL)#Multirow_inserts.
Някои бази данни не поддържат този синтаксис, но много. В моя опит Derby / Cloudscape, DB2, Postgresql и по-новите издания Hypersonic 2. * + поддържат това.
Вашата загриженост за това да работите катоPreparedStatement е разбираемо, но съм виждал подобни случаи, при които Spring JDBC автоматично обработва колекция от елементи за определени заявки (например къде в (?)), Но не мога да гарантирам за този случай.
Намерих някаква полезна информация на адрес (не мога да добавя втора връзка към тази публикация) което може да е от полза.
Мога да ви кажа, че вероятно не е възможноВашето второ изискване (работи за произволен брой аргументи), което трябва да бъде изпълнено в най-строгия смисъл: всяка база данни, която използвах, налага ограничения на дължината на заявката, които биха се включили.
28 за отговор № 2
Можеш да използваш BatchPreparedStatementSetter както е показано по-долу.
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();
}
});
}
0 за отговор № 3
Струва ми се, че методът на JdbcTemplate от batchUpdate () може да бъде полезен в този случай (копиран от тук) 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();
}
});
}
-1 за отговор № 4
можете също да опитате с jdbcInsert.executeBatch (sqlParamSourceArray)
// 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);
-4 за отговор № 5
Не можете да правите това в JDBC, период. В MySQL това е само синтактична захар, но ефектът от изявлението ще бъде същият като издаването на няколко INSERT изявления.