Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.143.212.121] |
|
Сообщ.
#1
,
|
|
|
проблема в следующем.
Есть некая функция public ResultSet fun(){ ResultSet rs = statement.executeQuery(sql); ResultSet rs2 = rs; rs.close(); return rs2; } После вызова данной функции java выдаст ошибку мол ресалт сет зокрыт, потому что объек rs2 ссылается на объект созданный rs (так называемая дублирующая сылка ) Как мне создать копию объекта rs и передать ее в rs2? Метод clone() не доступен. |
Сообщ.
#2
,
|
|
|
Используй метод clone()
т.е. Создай свой класс унаследованный от ResultSet только добавиш implements Cloneable. Почитай про этот интерфейс, есть много примеров по созданию копии объекта. |
Сообщ.
#3
,
|
|
|
Цитата Используй метод clone() Я бы рад, но ... Может кто нибудь еще потскадет? |
Сообщ.
#4
,
|
|
|
В своем РезалСете допиши метод clone()
public Object clone() { //shallow copy try { return super.clone(); } catch (CloneNotSupportedException e) { return null; } } Таким образом ты получишь не ссылку на объект, а его копию. |
Сообщ.
#5
,
|
|
|
[/QUOTE]т.е. Создай свой класс унаследованный от ResultSet только добавиш implements Cloneable. Почитай про этот интерфейс, есть много примеров по созданию копии объекта.
[QUOTE] Я уже пытался так сделать и вот что мне говорит eclipse "The type ResultSet cannot be the superclass of MyResultSet; a superclass must be a class" Я выяснил что ResultSet это интерфейс а не класс и еще больше зашел в тупик. Нужна компетентная помощь |
Сообщ.
#6
,
|
|
|
ResultSet - это, действительно, интерфейс. Релизацию для него предоставляет конкретный драйвер, и влезать в него не больно-то хорошо.
marlborist, а вчем, собственно, состоит задача? Если более общо смотреть. Может, можно обойтись и без клонирования? |
Сообщ.
#7
,
|
|
|
А что мешает хранить копию данных, которые содержит этот интерфейс?
|
Сообщ.
#8
,
|
|
|
Привет Alien.
Цитата marlborist, а вчем, собственно, состоит задача? Если более общо смотреть. Может, можно обойтись и без клонирования? Вот что конкретно делает моя функция: 1) имя функции: public ResultSet executeStoredProcedure(Param1 param1, Param2 param2, ...){...} 2)В ней создается хранимая процедура c именем "proc" которой передаются параметры из функции 3)Затем процедура с именем proc экзекьютится: proc.execute(). 4)Затем берется его ResultSet . ResultSet rs = proc.getResultSet(); то есть rs это ссылка. 5)Закрывается процедура proc.close(); 6)Возвращается rs. так вот этот rs который является ссылкой после закрытия процедуры тоже закрывается. Как я понял если после шага 4 создать копию объекта а не ссылку на объект то можно смело закрывать процедуру. Толька как мне это зделать? А может есть другой выход? |
Сообщ.
#9
,
|
|
|
marlborist, мне кажется, что ваш подход изначально неверен. Использование ссылок на фукнции - достаточно мощный инструмент в C++, но в Java можно найти другой путь.
Мне немного непонятно ваше объяснение. Что значит proc.execute()? Если proc - это Method, то там нет такого метода Может proc - объект PreparedStatement? Опишите подробнее зачем вообще нужна executeStoredProcedure() |
Сообщ.
#10
,
|
|
|
Цитата Опишите подробнее зачем вообще нужна executeStoredProcedure() public Object executeStoredProcedure(String proc_name, ArrayList params,ArrayList modifics, boolean has_return_value) { Object return_value = null; String body = ""; // Count how many parameters procedure body have. for (Iterator it = params.iterator(); it.hasNext(); it.next()) { body += "?,"; } if(!params.isEmpty()) { body=body.substring(0, body.length()-1); } try { String sql_statement = ((has_return_value) ? "{?=" : "{") + "call "+ proc_name + "(" + body + ")}"; proc = connection.prepareCall(sql_statement); int sqlType; Object curr_param; Object curr_modific; int j = 1; // If procedure have return value?, ther return value must register. if (has_return_value) { proc.registerOutParameter(j++, Types.INTEGER); } Iterator iter = modifics.iterator(); sqlType = Types.OTHER; for (Iterator it = params.iterator(); it.hasNext(); ++j) { curr_param = it.next(); curr_modific = iter.next(); proc.setObject(j, curr_param); // Check if output param. if (((Integer) curr_modific).intValue() == OUT) { proc.registerOutParameter(j, sqlType); } } // Execute stored procedure on server. proc.execute(); // Parsing output params. j = ((has_return_value) ? 2 : 1); int i = 0; // Set return value. if (has_return_value) { return_value = proc.getObject(1); } else { return_value=proc.getResultSet(); } ResultSet rs ; // Output parameters in ArrayList params must be replaced by // modified value after stored procedure executed. for (iter = modifics.iterator();(has_return_value) ? j <= params.size() + 1 : j <= params.size();j++, i++) { curr_modific = iter.next(); if (((Integer)curr_modific).intValue() == OUT) { curr_param = proc.getObject(j); params.set(i, curr_param); } } } catch (Exception e) { e.printStackTrace(); } return return_value; } ---------------------------------------------------- Вот она сама канкретная функция. Как вы можете заметить я не вызывал метод close() для объекта proc, то есть proc.close(). Есть ли какая то возможность закрыть хранимую процедуру при этом не потеряв данные, а именно ResaltSet? Все еще жду решения своей проблемы! |
Сообщ.
#11
,
|
|
|
Прошу прощения: с утра пораньше неправильно понял что значит "хранимая процедура"
В вашем случае я бы поступил следующим образом (хотя конечно это ИМХО, возможно кто-то предложит вариант получше ): - если размер возвращаемых данных невелик - кидаем все в коллекцию и возвращаем ее - если размер данных достаточно большой, то используем слушателей Поясню: если я правильно понял, то executeStoredProcedure() - универсальный "запускатель" SQL-процедур. В таком случае создаем какой-нибудь интерфейс типа StoredProcedureCallingListener, в котором объявляем метод procedureExecuted(String procedureName, ResultSet rs), который и будет заниматься обработкой данных. В классе, где лежит executeStoredProcedure() добавляем публичные методы addStoredProcedureCallingListener(StoredProcedureCallingListener listener) (регистрация слушателя) и removeStoredProcedureCallingListener(StoredProcedureCallingListener listener) (снятие с учета ). Соотвественно этих слушателей где-то нужно хранить. При вызове executeStoredProcedure() нужно вызвать у всех зарегистрированных слушателей метод procedureExecuted(String procedureName, ResultSet rs) с соответствующим параметром. После вызова благополучно все закрываем. Ну а регистрировать слушателя нужно для каждой используемой хранимой процедуры. Хотелось бы еще отметить: Цитата String body = ""; // Count how many parameters procedure body have. for (Iterator it = params.iterator(); it.hasNext(); it.next()) { body += "?,"; } Во-первых, в комментариях подправить на has Во-вторых, использовать не String, а StringBuilder, т.к. String - немутабельный объект. |
Сообщ.
#12
,
|
|
|
На счет коллекций: если я не найду другого выхода то придется использовать этот как запасной вариант.
На счет добавления слушателей: тоже можно использовать как запасной вариант, во первых я не очень понял что вы имели ввиду, но я понял что в коде где вызывался метод executeStoredProcedure() нужно делать допалнительные приседания вызывая различные методы, это тоже проблемно ковыряться во всем проекте(а он не малеький) и искать где вызывался метод executeStoredProcedure (). Мне на много будет легче если я как нибудь передам копию объекта а процедуру закрою. Тогда мне ни чего не придется изменять, в классах где я вызывал этот метод. |