Spring JdbcTemplate - Вставляет блоб и возврат сгенерированный ключ

От 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

Существует ли способ, которым я мог объединить два?

20
задан itsadok 5 May 2010 в 05:43
поделиться

2 ответа

В итоге я просто выполнил два запроса, один для создания строки и один для обновления блоба.

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, когда код становится настолько сложным.

В любом случае, я протестировал приведенный выше код, и он работает. Для моего случая я решил, что это слишком усложнит мой код.

2
ответ дан 30 November 2019 в 00:47
поделиться

В случае, если ваша базовая база данных - mysql, вы можете автогенерировать первичный ключ. Затем, чтобы вставить запись в базу данных, вы можете использовать следующий синтаксис для вставки:

INSERT INTO lob_table (a_blob) VALUES (?)
0
ответ дан 30 November 2019 в 00:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: