Нельзя использовать resultSet.setFetchDirection(ResultSet.TYPE_SCROLL_SENSITIVE) с пружиной jdbc DaoSupport с Oracle
Я хочу использовать прокручиваемый набор результатов, поэтому, когда я использую две строки кода:
rs.setFetchDirection(ResultSet.TYPE_SCROLL_SENSITIVE);
rs.absolute(12);
в моем DAOimpl, я получаю исключение, плз, помогите решить их, заранее спасибо.
import oracle.jdbc.OracleTypes;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Component;
@Component
public class MyDAOimpl extends JdbcDaoSupport implements
MyDAO {
public List<User> getList(final String where) throws Exception {
return (List) getJdbcTemplate().execute(
"{call PKG_USER.getUser(?,?)}",
new CallableStatementCallback() {
public Object doInCallableStatement(CallableStatement cs)
throws SQLException {
cs.setString(1, where);
cs.registerOutParameter(2, OracleTypes.CURSOR);
cs.execute();
ResultSet rs = (ResultSet) cs.getObject(6);
rs.setFetchDirection(ResultSet.TYPE_SCROLL_SENSITIVE);
rs.absolute(12);
List<User> list = new ArrayList<User>();
while (rs.next()) {
User user = new User(
rs.getString(1),
rs.getString(2),
rs.getString(3));
list.add(user);
}
return list;
}
});
}
}
это исключение
java.sql.SQLException: Invalid argument(s) in call: setFetchDirection
oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:199)
oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:263)
oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:271)
oracle.jdbc.driver.BaseResultSet.setFetchDirection(BaseResultSet.java:128)
////////////////////////////////////////////////// ////////////////////////////////////////
где я меняю, как показано ниже, я не получил никакого результата, обычно моя процедура возвращает 100 пользователей:
return (List) getJdbcTemplate().execute(new CallableStatementCreator() {
public CallableStatement createCallableStatement(
Connection connection) throws SQLException {
return connection.prepareCall(
"{call PKG_USER.getUser(?,?)}",
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.TYPE_SCROLL_INSENSITIVE);
}
}, new CallableStatementCallback() {
public Object doInCallableStatement(CallableStatement cs)
throws SQLException, DataAccessException {
cs.setString(1, where);
cs.registerOutParameter(2, OracleTypes.CURSOR);
cs.execute();
ResultSet rs = (ResultSet) cs.getObject(6);
//////not run////
rs.absolute(12);
////////////////
List<User> list = new ArrayList<User>();
while (rs.next())
{
List<User> list = new ArrayList<User>();
while (rs.next()) {
User user = new User(
rs.getString(1),
rs.getString(2),
rs.getString(3));
list.add(user);
}
return list;
}
});
2 ответа
Первый, ResultSet.TYPE_SCROLL_SENSITIVE
является константой, указывающей тип набора результатов, и, конечно, не является допустимым аргументом для setFetchDirection
который ожидает пятого направления. Цитирование раздела параметров Ja vadoc ResultSet#setFetchDirection(int direction)
:
direction
- анint
указание предполагаемого направления выборки; один изResultSet.FETCH_FORWARD
,ResultSet.FETCH_REVERSE
, или жеResultSet.FETCH_UNKNOWN
Отсюда исключение и сообщение "Неверный аргумент (ы) в вызове: setFetchDirection
".
И кстати, согласно Oracle " Руководство и справочник разработчика JDBC " (все версии доступны по http://tahiti.oracle.com/) в разделе "Обработка прокручиваемого результирующего набора":
Предварительная настройка направления выборки
Стандарт JDBC 2.0 позволяет предварительно указывать направление, известное как направление выборки, для использования при обработке набора результатов. Это позволяет драйверу JDBC оптимизировать его обработку. Указаны следующие методы набора результатов:
void setFetchDirection(int direction) throws SQLException
*int getFetchDirection() throws SQLException
Драйверы JDBC Oracle поддерживают только предустановленное значение вперед, которое можно указать, введя
ResultSet.FETCH_FORWARD
значение статической константы.Ценности
ResultSet.FETCH_REVERSE
а такжеResultSet.FETCH_UNKNOWN
не поддерживаются Попытка указать их вызывает предупреждение SQL, а настройки игнорируются.
Это также упоминается в файле readme драйверов базы данных Oracle Database 11g Release 2 (окончательная версия на момент написания этой статьи):
Реализация прокручиваемого результирующего набора имеет следующее ограничение:
- setFetchDirection () на Scrollable Result Set ничего не делает.
Но все это было неким побочным setFetchDiretion
это просто не способ получить прокручиваемый набор результатов.
Чтобы создать прокручиваемый набор результатов с помощью Spring JdbcTemplate
, вы должны использовать метод execute(CallableStatementCreator csc, CallableStatementCallback action)
с обычаем CallableStatementCreator
реализация. В этой реализации используется метод Connection.prepareCall(String sql, int resultSetType, int resultSetConcurrency)
создать CallableStatement
что будет производить ResultSet
объекты с заданным типом и параллелизмом. Наконец, позвоните rs.absolute()
,
ОБНОВЛЕНИЕ: есть проблема в connection.prepareCall()
вызов, третий параметр должен быть типом параллелизма (либо ResultSet.CONCUR_READ_ONLY
или же ResultSet.CONCUR_UPDATABLE
). Попробуй это:
return connection.prepareCall(
"{call PKG_USER.getUser(?,?)}",
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
Чтобы получить пользовательский набор результатов из шаблона jdbc. Spring предоставила PreparedStatementCreatorFactory, из которого вы можете создать PreparedStatementCreator.
PreparedStatementCreatorFactory pc = new PreparedStatementCreatorFactory(sqlQuery, , new int[] {Types.VARCHAR});//query and params Types
pc.setResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE);//TYPE_SCROLL_INSENSITIVE
pc.setUpdatableResults(false);//CONCUR_READ_ONLY
jdbcTemplate.query(pc.newPreparedStatementCreator(listOfParams),
myResultSetExtractor);//perform query with custom psc, process results at ResultSetExtractor