WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
Spring Framework это Java-окружение, разработанное для помощи в
проектировании приложений, обеспечивая способ формировать компоненты.
Техника, используемая в Spring, является известным шаблоном разработки под
названием Dependency Injection (см.
Inversion of Control Containers and the Dependency Injection pattern).
Эта статья сосредоточится на ориентированном на Java доступе к базам данных
MySQL с Spring 2.0. Есть также .NET-порт Spring под названием Spring.NET. Spring не только система для формирования компонентов, но также
включает поддержку аспектно-ориентированного программирования (AOP). Это одни
из главных преимуществ для управления ресурсами Spring и
управления транзакциями. Spring также обеспечивает утилиты для интеграции
управления ресурсами с JDBC и Hibernate. Для примеров в этой секции будет использоваться база данных-образец world.
Первая задача состоит в том, чтобы настроить источник данных MySQL из Spring.
Компоненты в Spring используют терминологию
bean. Например, чтобы формировать связь с сервером
MySQL, поддерживающим базу данных-образец, вы могли бы использовать: В вышеупомянутом примере мы назначаем значения свойствам, которые будут
использоваться в конфигурации. Для конфигурации источника данных: Заполнители используются, чтобы предоставить значения для свойств этого
блока. Это означает, что мы можем определить все свойства конфигурации в
одном месте вместо того, чтобы задавать значения для каждого свойства.
Нам действительно, однако, нужен еще один блок, чтобы собрать все это вместе.
Последний блок ответственен за то, чтобы заменить
заполнители значениями свойств. Теперь, когда мы сформировали наш источник данных MySQL и готовы к
работе, мы пишем некоторый код на Java, чтобы получить доступ к нему.
Пример ниже получит три случайных города и их соответствующую страну,
используя источник данных, который мы сформировали в Spring. Это очень похоже на нормальный доступ JDBC к MySQL с основным различием
в том, что мы используем DataSourceUtils вместо DriverManager,
чтобы создать связь. В то время как это может походить на небольшую разницу, последствия
несколько больше. Spring управляет этим ресурсом, в некотором роде подобным
контейнерному источнику управляемых данных в сервере приложений J2EE. Когда
связь открыта, к ней можно впоследствии получить доступ в других частях кода,
если они синхронизированы с транзакцией. Это позволяет рассматривать
различные части вашего приложения как транзакции вместо того, чтобы раздавать
соединение с базой данных. Spring широко применяет шаблон разработки метода Template (см.
Template Method Pattern). Нашим непосредственным центром будет
Следующий пример показывает, как использовать
Центром в вышеупомянутом коде является метод
Чтобы получить доступ к этому коду, необходимо формировать его в Spring,
обеспечивая ссылку на источник данных. В этом пункте мы можем просто захватить ссылку на DAO из Spring и вызвать
Этот пример показывает, как использовать классы Spring JDBC
для абстрактного использования традиционных классов JDBC, включая
Spring позволяет нам добавлять транзакции в наш код, не имея дела
непосредственно с классами JDBC. С этой целью Spring
обеспечивает пакет управления транзакциями, который не только заменяет
управление транзакциями JDBC, но также и позволяет декларативное управление
транзакциями (конфигурация вместо кода). Чтобы использовать транзакционный доступ к базе данных, мы должны будем
изменить механизм хранения таблиц в базе данных. Загруженный скрипт
явно составляет таблицы MyISAM, которые не поддерживают транзакционную
семантику. Механизм хранения InnoDB действительно поддерживает
транзакции и это то, что мы будем использовать. Мы можем изменить механизм
хранения следующими запросами. Хорошая практика программирования в Spring отделяет интерфейсы и
реализации. Это означает, что мы можем создать интерфейс Java и только
использовать операции в этом интерфейсе без любого внутреннего ведома того,
какова фактическая реализация. Мы позволим Spring работать с
внедрением, и это будет управлять транзакциями для нашего внедрения. Сначала вы создаете простой интерфейс: Этот интерфейс содержит один метод, который создаст новую запись города
в базе данных и возвратит идентификатор новой записи.
Затем необходимо создать реализацию этого интерфейса. Вы видите, что мы только воздействуем на абстрактные объекты
запроса здесь и не имеем дело непосредственно с API JDBC. Кроме того, это
полноценная реализация. Со всем нашим управлением транзакциями будет иметь
дело конфигурация. Чтобы начать конфигурацию, мы должны создать DAO. Теперь мы должны настроить операционную конфигурацию. Первая вещь, которую
мы должны сделать, это создать менеджер транзакций, чтобы управлять
источником данных и спецификацией того, какие операционные свойства требуются
для методов Предыдущий код создает менеджер транзакций, который обращается с
транзакциями для источника данных, предоставленного ему.
Это в основном говорит что все методы, к которым обращается интерфейс
Мы можем проверить, что нет никакого управления транзакциями,
происходящего в нашем коде Java, и все формируется с Spring.
Это очень сильное понятие, рассматриваемое как одна из самых
выгодных особенностей Spring. Во многих ситуациях, таких как веб-приложения, будет большое количество
маленьких транзакций базы данных. Когда дело обстоит так, обычно имеет смысл
создавать фонд соединений с базой данных, доступных для веб-запросов по мере
необходимости. Хотя MySQL не порождает дополнительный процесс, когда связь
установлена, есть все еще небольшое количество издержек, чтобы создать и
настроить связь. Объединение связей также облегчает такие проблемы, как
работа большого числа сокетов в состоянии Подготовка объединения подключений с Spring так же проста, как изменение
конфигурации источника данных в прикладном контексте. Есть много
конфигураций, которые мы можем использовать. Первый пример основан на
Jakarta
Commons DBCP library. Пример ниже заменяет исходную конфигурацию, которая
была на основе Конфигурация этих двух решений очень похожа. Различие в том, что DBCP
объединит связи с базой данных вместо того, чтобы создать новую связь каждый
раз, когда она нужна. Мы также установили параметр, здесь названный
Другой способ формировать объединение связи состоит в том, чтобы
формировать источник данных в нашем сервере приложений J2EE. Используя JBoss
как пример, можно настроить фонд подключений MySQL создав файл, названный
Глава 14. Connector/J и Spring
<util:map id="dbProps">
<entry key="db.driver" value="com.mysql.cj.jdbc.Driver"/>
<entry key="db.jdbcurl" value="jdbc:mysql://localhost/world"/>
<entry key="db.username" value="myuser"/>
<entry key="db.password" value="mypass"/>
</util:map>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.jdbcurl}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="dbProps"/>
</bean>
// Create a new application context. this processes the Spring config
ApplicationContext ctx = new ClassPathXmlApplicationContext("ex1appContext.xml");
// Retrieve the data source from the application context
DataSource ds = (DataSource) ctx.getBean("dataSource");
// Open a database connection using Spring's DataSourceUtils
Connection c = DataSourceUtils.getConnection(ds);
try {
// retrieve a list of three random cities
PreparedStatement ps = c.prepareStatement(
"select City.Name as 'City', Country.Name as 'Country' " +
"from City inner join Country on City.CountryCode = Country.Code " +
"order by rand() limit 3");
ResultSet rs = ps.executeQuery();
while(rs.next()) {
String city = rs.getString("City");
String country = rs.getString("Country");
System.out.printf("The city %s is in %s%n", city, country);
}
} catch (SQLException ex) {
// something has failed and we print a stack trace to analyse the error
ex.printStackTrace();
// ignore failure closing connection
try { c.close(); } catch (SQLException e) { }
} finally {
// properly release our connection
DataSourceUtils.releaseConnection(c, ds);
}
14.1. Использование
JdbcTemplate
JdbcTemplate
и связанные классы, определенно
NamedParameterJdbcTemplate
. Получение
обработчика шаблонных классов и наличие связи для доступа к данным,
когда это необходимо.NamedParameterJdbcTemplate
в классе DAO
(Data Access Object), чтобы получить случайный город по коду страны.
public class Ex2JdbcDao {
/**
* Data source reference which will be provided by Spring.
*/
private DataSource dataSource;
/**
* Our query to find a random city given a country code. Notice
* the ":country" parameter toward the end. This is called a
* named parameter.
*/
private String queryString = "select Name from City " +
"where CountryCode = :country order by rand() limit 1";
/**
* Retrieve a random city using Spring JDBC access classes.
*/
public String getRandomCityByCountryCode(String cntryCode) {
// A template that permits using queries with named parameters
NamedParameterJdbcTemplate template =
new NamedParameterJdbcTemplate(dataSource);
// A java.util.Map is used to provide values for the parameters
Map params = new HashMap();
params.put("country", cntryCode);
// We query for an Object and specify what class we are expecting
return (String)template.queryForObject(queryString, params, String.class);
}
/**
* A JavaBean setter-style method to allow Spring to inject the data source.
* @param dataSource
*/
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}
getRandomCityByCountryCode()
.
Мы передаем код страны и используем
NamedParameterJdbcTemplate
для запроса города.
Код страны помещается в Map с ключем "country",
который является параметром, названным в SQL-запросе.
<bean id="dao" class="code.Ex2JdbcDao">
<property name="dataSource" ref="dataSource"/>
</bean>
getRandomCityByCountryCode()
.
// Create the application context
ApplicationContext ctx =
new ClassPathXmlApplicationContext("ex2appContext.xml");
// Obtain a reference to our DAO
Ex2JdbcDao dao = (Ex2JdbcDao) ctx.getBean("dao");
String countryCode = "USA";
// Find a few random cities in the US
for (int i = 0; i < 4; ++i)
System.out.printf("A random city in %s is %s%n", countryCode,
dao.getRandomCityByCountryCode(countryCode));
Connection
и
PreparedStatement
.
14.2. Транзакционный доступ JDBC
ALTER TABLE City ENGINE=InnoDB;
ALTER TABLE Country ENGINE=InnoDB;
ALTER TABLE CountryLanguage ENGINE=InnoDB;
public interface Ex3Dao {
Integer createCity(String name, String countryCode,
String district, Integer population);
}
public class Ex3DaoImpl implements Ex3Dao {
protected DataSource dataSource;
protected SqlUpdate updateQuery;
protected SqlFunction idQuery;
public Integer createCity(String name, String countryCode,
String district, Integer population)
{
updateQuery.update(new Object[]
{name, countryCode, district, population});
return getLastId();
}
protected Integer getLastId() {
return idQuery.run();
}
}
<bean id="dao" class="code.Ex3DaoImpl">
<property name="dataSource" ref="dataSource"/>
<property name="updateQuery">...</property>
<property name="idQuery">...</property>
</bean>
dao
.
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
txAdvice
использует этот менеджер транзакций и
определяет признаки, чтобы создать транзакцию для всех методов.
Наконец мы должны применить это с AOP.
<aop:config>
<aop:pointcut id="daoMethods"
expression="execution(* code.Ex3Dao.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="daoMethods"/>
</aop:config>
Ex3Dao
, обернуты в транзакцию.
Чтобы использовать это, мы только должны получить
dao
от прикладного контекста и обращатся к
методу в экземпляре dao
.
Ex3Dao dao = (Ex3Dao) ctx.getBean("dao");
Integer id = dao.createCity(name,countryCode, district, pop);
14.3. Объединение связи в Spring
TIME_WAIT
.DriverManagerDataSource
с DBCP's BasicDataSource.
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.jdbcurl}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
<property name="initialSize" value="3"/>
</bean>
initialSize
. Это говорит DBCP, что мы хотим три
связи в пуле, когда он создается.mysql-local-ds.xml
и разместив его в каталоге
server/default/deploy
в JBoss.
Как только мы это настроили, мы можем использовать JNDI, чтобы искать его.
С Spring этот поиск очень прост. Конфигурация источника данных похожа на это:
<jee:jndi-lookup id="dataSource" jndi-name="java:MySQL_DS"/>
Найди своих коллег! |
Вы можете направить письмо администратору этой странички, Алексею Паутову.