Подтвердить что ты не робот

Использование подготовленных инструкций с помощью JDBCTemplate

Я использую шаблон JDBC и хочу читать из базы данных с помощью подготовленных операторов. Я повторяю много строк в CSV файле, и в каждой строке я выполняю некоторые запросы на выборку SQL с соответствующими значениями.

Я хочу ускорить чтение из базы данных, но я не знаю, как заставить шаблон JDBC работать с подготовленными операторами.

Существует PreparedStatementCreator и PreparedStatementSetter. Как в в этом примере оба они создаются с анонимными внутренними классами. Но внутри класса PreparedStatementSetter у меня нет доступа к значениям, которые я хочу установить в подготовленном операторе.

Так как я выполняю итерацию через CSV файл, я не могу скомпоновать их как строку, потому что я их не знаю. Я также не могу передать их в PreparedStatementSetter, потому что для конструктора нет аргументов. И установка моих значений в final тоже была бы немой.

Я был использован для создания подготовленных утверждений довольно просто. Что-то вроде

PreparedStatement updateSales = con.prepareStatement(
    "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? ");
updateSales.setInt(1, 75); 
updateSales.setString(2, "Colombian"); 
updateSales.executeUpdate():

как в этом учебнике по Java.

4b9b3361

Ответ 1

Я попробовал select select теперь с PeparedStatement, но оказалось, что он был не быстрее, чем шаблон Jdbc, Возможно, как предположил мезмо, он автоматически создает подготовленные заявления.

Во всяком случае, причина, по которой мой sql SELECT был настолько медленным, был другим. В предложении WHERE я всегда использовал оператор LIKE, когда все, что я хотел сделать, это найти точное совпадение. Поскольку я обнаружил, что LIKE выполняет поиск шаблона и, следовательно, довольно медленный.

Теперь я использую оператор =, и он намного быстрее.

Ответ 2

По умолчанию JDBCTemplate делает свой собственный PreparedStatement внутренне, если вы просто используете форму .update(String sql, Object ... args). Spring и ваша база данных будут обрабатывать скомпилированный запрос для вас, поэтому вам не нужно беспокоиться об открытии, закрытии, защите ресурсов и т.д. Одно из преимуществ сохранения Spring. Ссылка на Spring 2.5 документацию по этому вопросу. Надеюсь, что это станет проще. Кроме того, кэширование выводов может выполняться на уровне JDBC, как в случае по крайней мере некоторых драйверов JDBC от Oracle. Это будет намного более подробно, чем я могу грамотно.

Ответ 3

class Main {
    public static void main(String args[]) throws Exception {
        ApplicationContext ac = new
          ClassPathXmlApplicationContext("context.xml", Main.class);
        DataSource dataSource = (DataSource) ac.getBean("dataSource");
// DataSource mysqlDataSource = (DataSource) ac.getBean("mysqlDataSource");

        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        String prasobhName = 
        jdbcTemplate.query(
           "select first_name from customer where last_name like ?",
            new PreparedStatementSetter() {
              public void setValues(PreparedStatement preparedStatement) throws
                SQLException {
                  preparedStatement.setString(1, "nair%");
              }
            }, 
            new ResultSetExtractor<Long>() {
              public Long extractData(ResultSet resultSet) throws SQLException,
                DataAccessException {
                  if (resultSet.next()) {
                      return resultSet.getLong(1);
                  }
                  return null;
              }
            }
        );
        System.out.println(machaceksName);
    }
}

Ответ 4

Попробуйте следующее:

PreparedStatementCreator creator = new PreparedStatementCreator() {
    @Override
    public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
        PreparedStatement updateSales = con.prepareStatement(
        "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? ");
        updateSales.setInt(1, 75); 
        updateSales.setString(2, "Colombian"); 
        return updateSales;
    }
};

Ответ 5

Я бы обработал обработанную инструкцию обработчиком хотя бы одним методом. В этом случае, поскольку результатов нет, это довольно просто (и предполагая, что соединение является переменной экземпляра, которая не изменяется):

private PreparedStatement updateSales;
public void updateSales(int sales, String cof_name) throws SQLException {
    if (updateSales == null) {
        updateSales = con.prepareStatement(
            "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ?");
    }
    updateSales.setInt(1, sales);
    updateSales.setString(2, cof_name);
    updateSales.executeUpdate();
}

В этот момент это просто вопрос вызова:

updateSales(75, "Colombian");

Что довольно просто интегрировать с другими вещами, да? И если вы вызовете метод много раз, обновление будет построено только один раз, и это сделает вещи намного быстрее. Ну, предполагая, что вы не делаете сумасшедших вещей, таких как выполнение каждого обновления в своей собственной транзакции...

Обратите внимание, что типы фиксированы. Это связано с тем, что для любого конкретного запроса/обновления они должны быть исправлены, чтобы база данных могла эффективно выполнять свою работу. Если вы просто вытаскиваете произвольные строки из файла CSV, передайте их в виде строк. Там также нет блокировки; гораздо лучше сохранить отдельные соединения для использования из одного потока.