Использование DataSource
Spring получает соединение с базой данных через DataSource
. DataSource
является частью спецификации JDBC и представляет собой обобщенную фабрику соединений. Он позволяет контейнеру или фреймворку скрывать проблемы объединения соединений в пул и управления транзакциями от кода приложения. Как разработчику, вам не требуется подробно знать о том, как подключиться к базе данных. За это отвечает администратор, который устанавливает источник данных. Скорее всего, вы выполняете обе роли, поскольку разрабатываете и тестируете код, но вам не обязательно знать, как настроен производственный источник данных.
Если вы используете JDBC-уровень в Spring, то можете получить источник данных из JNDI или настроить свой собственный с помощью реализации пула соединений, предоставленного третьей стороной. Традиционными вариантами являются Apache Commons DBCP и C3P0 с классами DataSource
на основе бина; для современного пула соединений JDBC рассмотрите HikariCP с его API-интерфейсом на основе конструктора.
DriverManagerDataSource
и SimpleDriverDataSource
(входящие в дистрибутив Spring) следует использовать только в целях тестирования! Эти варианты не обеспечивают объединение в пул и плохо работают, когда выполняется несколько запросов на соединение.В следующем разделе используется реализация DriverManagerDataSource
из Spring. Несколько других вариантов DataSource
будут рассмотрены позже.
Чтобы сконфигурировать DriverManagerDataSource
:
-
Установите соединение с
DriverManagerDataSource
так же, как вы обычно устанавливаете соединение для JDBC. -
Укажите полное имя класса драйвера JDBC, чтобы
DriverManager
мог загрузить класс драйвера. -
Укажите URL-адрес, который различается для разных драйверов JDBC. (Правильное значение см. в документации к вашему драйверу).
-
Укажите имя пользователя и пароль для подключения к базе данных.
В следующем примере показано, как сконфигурировать DriverManagerDataSource
в Java:
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
dataSource.setUrl("jdbc:hsqldb:hsql://localhost:");
dataSource.setUsername("sa");
dataSource.setPassword("");
val dataSource = DriverManagerDataSource().apply {
setDriverClassName("org.hsqldb.jdbcDriver")
url = "jdbc:hsqldb:hsql://localhost:"
username = "sa"
password = ""
}
В следующем примере показана соответствующая XML-конфигурация:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<context:property-placeholder location="jdbc.properties"/>
В следующих двух примерах показано базовое подключение и конфигурация для DBCP и C3P0. Чтобы узнать о других опциях, которые помогают управлять функциями пула, обратитесь к документации по продуктам для соответствующих реализаций пула соединений.
В следующем примере показана конфигурация DBCP:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<context:property-placeholder location="jdbc.properties"/>
В следующем примере показана конфигурация C3P0:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<context:property-placeholder location="jdbc.properties"/>
Использование DataSourceUtils
Класс DataSourceUtils
– это удобный и полнофункциональный вспомогательный класс, который предоставляет статические методы для установления соединений из JNDI и закрытия соединений при необходимости. Он поддерживает потоковые соединения, например, с DataSourceTransactionManager
.
Реализация SmartDataSource
Интерфейс SmartDataSource
должен быть реализован классами, которые могут обеспечить подключение к реляционной базе данных. Он расширяет интерфейс DataSource
, позволяя классам, использующим его, делать запрос относительно того, следует ли закрывать соединение после определенной операции. Такое использование эффективно, если вы знаете, что вам нужно повторно использовать соединение.
Расширение AbstractDataSource
AbstractDataSource
– это abstract
базовый класс для реализаций DataSource
из Spring. Он реализует код, который является общим для всех реализаций DataSource.
Вам следует расширять класс AbstractDataSource,
если вы пишете свою собственную реализацию DataSource
.
Использование SingleConnectionDataSource
Класс SingleConnectionDataSource
является реализацией интерфейса SmartDataSource
, который оборачивает одно Connection
, которое не закрывается после каждого использования. Он не поддерживает многопоточность.
Если какой-либо клиентский код вызывает close
, исходя из предположения, что существует пул соединений (как при использовании инструментов поддержки постоянного хранения данных), следует установить свойство suppressClose
в true
. Этот параметр возвращает прокси, подавляющий закрытие, который обертывает физическое соединение. Обратите внимание, что больше нельзя преобразовать его в собственный Connection
из Oracle или аналогичный объект.
SingleConnectionDataSource
– это в первую очередь тестовый класс. Как правило, он позволяет легко тестировать код вне сервера приложений в сочетании с простым окружением JNDI. В отличие от DriverManagerDataSource
, он постоянно использует одно и то же соединение, избегая чрезмерного создания физических соединений.
Использование DriverManagerDataSource
Класс DriverManagerDataSource
является реализацией стандартного интерфейса DataSource
, который конфигурирует обычный драйвер JDBC через свойства бина и каждый раз возвращает новое Connection
.
Эта реализация полезна для тестовых и автономных окружений вне контейнера Java EE, как в качестве бина DataSource
в IoC-контейнере Spring, так и в сочетании с простым окружением JNDI. Вызовы Connection.close()
закрывают соединение, поэтому любой код постоянного хранения данных, совместимый с DataSource
, должен работать. Однако использовать пулы соединений на основе JavaBean (таких как commons-dbcp
) настолько просто, даже в тестовом окружении, что почти всегда такой пул соединений более предпочтителен, чем DriverManagerDataSource
.
Использование TransactionAwareDataSourceProxy
TransactionAwareDataSourceProxy
– это прокси для целевого DataSource
. Прокси обертывает целевой DataSource,
чтобы повысить уровень совместимости с транзакциями, управляемыми Spring. В этом отношении он похож на транзакционный DataSource
из JNDI, предоставляемый сервером Java EE.
DataSource
из JDBC. В этом случае можно сохранить возможность использования этого кода и, в то же время, обеспечить участие этого кода в транзакциях, управляемых Spring. Обычно предпочтительнее писать свой собственный новый код, используя абстракции более высокого уровня для управления ресурсами, такие как JdbcTemplate
или DataSourceUtils
.Более подробную информацию см. в javadoc по TransactionAwareDataSourceProxy
.
Использование DataSourceTransactionManager
Класс DataSourceTransactionManager
– это реализация PlatformTransactionManager
для отдельных источников данных JDBC. Он привязывает JDBC-соединение из указанного источника данных к текущему выполняемому потоку, что потенциально позволяет использовать одно потоковое соединение для каждого источника данных.
Код приложения должен получать JDBC-соединение через DataSourceUtils.getConnection(DataSource)
вместо стандартного DataSource.getConnection
в Java EE. Он генерирует непроверяемые исключения org.springframework.dao
вместо проверяемых SQLExceptions
. Все классы фреймворка (например, JdbcTemplate
) используют эту стратегию неявно. Если стратегия поиска не используется с этим менеджером транзакций, то она ведет себя точно так же, как и обычная. Таким образом, в любом случае её можно использовать.
Класс DataSourceTransactionManager
поддерживает кастомные уровни изоляции и значения времени ожидания, которые применяются как соответствующие значения времени ожидания запросов JDBC-инструкций. Чтобы обеспечить поддержку последнего варианта, код приложения должен либо использовать JdbcTemplate
, либо вызывать метод DataSourceUtils.applyTransactionTimeout(..)
для каждой созданной инструкции.
Можно использовать эту реализацию вместо JtaTransactionManager
в случае использования единственного ресурса, поскольку она не требует от контейнера поддержки JTA. Переключение между ними – это просто вопрос конфигурации, при условии, что вы придерживаетесь требуемого шаблона поиска соединений. JTA не поддерживает кастомно созданные уровни изоляции.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ