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

Программирование на Java - Spring и JDBCTemplate - используйте запрос, queryForList или queryForRowSet?

В проекте My Java (JDK6) используется Spring и JDBCTemplate для всего доступа к базе данных. Недавно мы обновили от Spring от 2,5 до Spring 3 (RC1). Проект не использует ORM, например Hibernate, а EJB.

Если мне нужно прочитать кучу записей и сделать с ними внутреннюю обработку, кажется, что существует несколько (перегруженных) методов: query, queryForList и queryForRowSet

Какими должны быть критерии использования одного вместо другого? Существуют ли различия в производительности? Лучшие практики?

Можете ли вы порекомендовать некоторые внешние ссылки для дальнейших исследований по этой теме?

4b9b3361

Ответ 1

Я обнаружил, что стандартный способ доступа к списку - это методы query(), а не любые другие подходы. Основное различие между query и другими методами заключается в том, что вам нужно будет реализовать один из интерфейсов обратного вызова (либо RowMapper, RowCallbackHandler, либо ResultSetExtractor) для обработки вашего набора результатов.

A RowMapper, скорее всего, вы будете использовать большую часть времени. Он используется, когда каждая строка результирующего набора соответствует одному объекту в вашем списке. Вам нужно реализовать только один метод mapRow, в котором вы заполняете тип объекта, который входит в вашу строку, и возвращайте его. Spring также имеет BeanPropertyRowMapper, который может заполнять объекты в списке, сопоставляя имена свойств bean с именами столбцов (NB этот класс предназначен для удобства не производительности).

A RowCallbackHandler более полезен, когда вам нужны ваши результаты, чтобы быть более чем простым списком. Вам придется управлять объектом возврата самостоятельно, используя этот подход. Обычно я использую это, когда мне нужна структура карты как мой тип возврата (т.е. Для сгруппированных данных для древовидной таблицы или если я создаю собственный кеш на основе первичного ключа).

A ResultSetExtractor используется, когда вы хотите контролировать итерацию результатов. Вы внедряете единственный метод extractData, который будет возвратным значением вызова query. Я только использую это, если мне нужно создать некоторую структуру данных, которая сложнее строить с использованием любого из других интерфейсов обратного вызова.

Методы queryForList() ценны тем, что вам не нужно реализовывать эти методы обратного вызова. Существует два способа использования queryForList. Во-первых, если вы запрашиваете только один столбец из базы данных (например, список строк), вы можете использовать версии метода, который принимает класс в качестве аргумента, чтобы автоматически предоставлять вам список только объектов этих классов,

При вызове других реализаций queryForList() вы получите список с каждой записью, являющейся картой для каждого столбца. Хотя это хорошо, что вы сохранили расходы на запись методов обратного вызова, обработка этой структуры данных довольно громоздка. Вы обнаружите, что делаете много кастинга, поскольку значения карты имеют тип Object.

Я никогда не видел методы queryForRowSet, используемые в дикой природе. Это приведет к загрузке всего результата запроса в объект CachedRowSet, разбитый на Spring SqlRowSet. Я вижу большой недостаток в использовании этого объекта в том, что если вы передаете SqlRowSet на другие уровни вашего приложения, вы связываете эти слои с реализацией доступа к данным.

Вы не должны видеть огромные различия в производительности между любыми этими вызовами, за исключением тех случаев, когда я упоминал BeanPropertyRowMapper. Если вы работаете с некоторыми сложными манипуляциями с большим набором результатов, вы можете получить некоторую прибыль от написания оптимизированного ResultSetExtractor для вашего конкретного случая.

Если вы хотите узнать больше, я бы посоветовал Spring документацию JDBC и JavaDoc для классов, о которых я упомянул. Вы также можете взглянуть на некоторые из книг на Spring Framework. Хотя он немного устарел от Java Development с Spring Framework имеет очень хороший раздел по работе с инфраструктурой JDBC. Прежде всего, я бы сказал, просто попробуйте написать код с каждым методом и посмотреть, что лучше всего подходит для вас.

Ответ 2

Поскольку вы находитесь в прекрасной земле Generics, то, что вы действительно хотите сделать, это использовать SimpleJdbcTemplate и использовать ее query() методы для Lists объектов и queryForObject() для отдельных объектов. Рассуждение для этого просто в том, что они еще проще в использовании, чем в JdbcTemplate.

Ответ 3

Одно небольшое дополнение к превосходным ответам выше: дополнительные методы, такие как queryForInt, queryForLong, queryForMap, queryForObject и т.д. иногда могут показаться хорошими вариантами, если вы используете простой запрос и ожидаете одну строку.

Однако, если вы можете получить 0 или 1 строки назад, метод queryForList, как правило, проще, иначе вам придется поймать IncorrectResultSizeDataAccessException. Я узнал, что это трудный путь.