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

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

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

Что должно быть критерии использования одного вместо другого? Есть ли различия в производительности? Передовая практика?

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

3 ответов


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

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

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

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

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

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

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

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

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


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


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

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