От Spring документация JDBC я знаю, как вставить использование блоба JdbcTemplate
final File blobIn = new File("spring2004.jpg");
final InputStream blobIs = new FileInputStream(blobIn);
jdbcTemplate.execute(
"INSERT INTO lob_table (id, a_blob) VALUES (?, ?)",
new AbstractLobCreatingPreparedStatementCallback(lobhandler) {
protected void setValues(PreparedStatement ps, LobCreator lobCreator)
throws SQLException {
ps.setLong(1, 1L);
lobCreator.setBlobAsBinaryStream(ps, 2, blobIs, (int)blobIn.length());
}
}
);
blobIs.close();
И также как получить сгенерированный ключ недавно вставленной строки:
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(
new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps =
connection.prepareStatement(INSERT_SQL, new String[] {"id"});
ps.setString(1, name);
return ps;
}
},
keyHolder);
// keyHolder.getKey() now contains the generated key
Существует ли способ, которым я мог объединить два?
В итоге я просто выполнил два запроса, один для создания строки и один для обновления блоба.
int id = insertRow();
updateBlob(id, blob);
Посмотрев исходный код Spring и выделив нужные части, я пришел к следующему:
final KeyHolder generatedKeyHolder = new GeneratedKeyHolder();
getJdbcTemplate().execute(
"INSERT INTO lob_table (blob) VALUES (?)",
new PreparedStatementCallback() {
public Object doInPreparedStatement(PreparedStatement ps) throws SQLException {
LobCreator lobCreator = lobHandler.getLobCreator();
lobCreator.setBlobAsBinaryStream(ps, 2, blobIs, (int)blobIn.length());
int rows = ps.executeUpdate();
List generatedKeys = generatedKeyHolder.getKeyList();
generatedKeys.clear();
ResultSet keys = ps.getGeneratedKeys();
if (keys != null) {
try {
RowMapper rowMapper = new ColumnMapRowMapper();
RowMapperResultSetExtractor rse = new RowMapperResultSetExtractor(rowMapper, 1);
generatedKeys.addAll((List) rse.extractData(keys));
}
finally {
JdbcUtils.closeResultSet(keys);
}
}
if (logger.isDebugEnabled()) {
logger.debug("SQL update affected " + rows + " rows and returned " + generatedKeys.size() + " keys");
}
return new Integer(rows);
}
}
);
Я не могу сказать, что полностью понимаю, что здесь происходит. Я не уверен, что сложный метод извлечения сгенерированного ключа необходим в этом простом случае, и я не совсем понимаю, зачем вообще использовать JdbcTemplate, когда код становится настолько сложным.
В любом случае, я протестировал приведенный выше код, и он работает. Для моего случая я решил, что это слишком усложнит мой код.
В случае, если ваша базовая база данных - mysql, вы можете автогенерировать первичный ключ. Затем, чтобы вставить запись в базу данных, вы можете использовать следующий синтаксис для вставки:
INSERT INTO lob_table (a_blob) VALUES (?)