Пакет гибернации с хранимой процедурой - PullRequest
2 голосов
/ 24 ноября 2011

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

public void store(int param1, int param2) {
   Connection con = session.connection();  // obtain JDBC connection from Session object
   CallableStatement stmt = con.prepareCall("{ call changesalary(?,?) }");
   stmt.setInt(1, param1);  // first parameter index start with 1
   stmt.setInt(2, param2); // second parameter
   stmt.execute();  // call stored procedure
   cleanup(con, stmt);
}

Интересно, можно ли повторно использовать эту процедуру хранилища более похожим на пакет способом, не меняя ее?нет возможности добавить новую хранимую процедуру или изменить существующую).Я хочу сделать это:

public void batchStore(int[] params1, int[] params2) {
    for (int i = 0; i < params1.length; i++) {
        store(params1[i], params2[i]);
    }
}

public void store(int param1, int param2) {
   Connection con = session.connection();
   CallableStatement stmt = con.prepareCall("{ call changesalary(?,?) }");
   stmt.setInt(1, param1);
   stmt.setInt(2, param2);
   stmt.execute();
   cleanup(con, stmt);
}

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

public void store(int[] params1, int[] params2) {
   Connection con = session.connection();
   CallableStatement[] stmts = new CallableStatements[params.size];

   for (int i = 0; i < params1.length; i++) {
       CallableStatement stmt = con.prepareCall("{ call changesalary(?,?) }");
       stmt.setInt(1, params1[i]);
       stmt.setInt(2, params2[i]);  
       stmts[i] = stmt;
    }

    con.executeStatements(stmts);
}

Можно ли достичь вышеуказанного псевдокода, и я увеличу производительность за счет этого?

1 Ответ

2 голосов
/ 24 ноября 2011

То, что вы на самом деле делаете, - это использование JDBC для выполнения вашего SQL (даже если вы получаете соединение JDBC из сеанса Hibernate).С JDBC вы можете сделать что-то вроде:

public void store(int[] params1, int[] params2) {
   Connection con = session.connection();
   boolean initialAutocommitSetting = connection con.getAutoCommit();
   //disable autocommit
   con.setAutoCommit(false);
   //you only need one statement object:
   CallableStatement stmt = con.prepareCall("{ call changesalary(?,?) }");

   for (int i = 0; i < params1.length; i++) {       
       stmt.setInt(1, params1[i]);
       stmt.setInt(2, params2[i]);  
       //for each call, add the set of parameters as needed and call addBatch();
       stmt.addBatch();
    }
    //when you're done, execute your (batch) statement and see how many updates you got
    int [] updatesCount=stmt.executeBatch(); 

    //manually commit
    con.commit();

    if(updatesCount!=i) {
        //some updates didn't work
    }

    //return connection to initial autocommit setting:
    connection.setAutoCommit(initialAutocommitSetting );
}

Надеюсь, это поможет.Javadocs: CallableStatement , Заявление

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...