В этом примере вы узнаете, как Spring JDBCTemplate упрощает код, который необходимо написать для выполнения операций, связанных с базой данных. Метод insertForum () ниже показывает объем кода, который необходимо написать для вставки данных с использованием JDBC.
package com.vaannila.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import com.vaannila.domain.Forum; public class JDBCForumDAOImpl implements ForumDAO { private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public void insertForum(Forum forum) { /** * Specify the statement */ String query = "INSERT INTO FORUMS (FORUM_ID, FORUM_NAME, FORUM_DESC) VALUES (?,?,?)"; /** * Define the connection and preparedStatement parameters */ Connection connection = null; PreparedStatement preparedStatement = null; try { /** * Open the connection */ connection = dataSource.getConnection(); /** * Prepare the statement */ preparedStatement = connection.prepareStatement(query); /** * Bind the parameters to the PreparedStatement */ preparedStatement.setInt(1, forum.getForumId()); preparedStatement.setString(2, forum.getForumName()); preparedStatement.setString(3, forum.getForumDesc()); /** * Execute the statement */ preparedStatement.execute(); } catch (SQLException e) { /** * Handle any exception */ e.printStackTrace(); } finally { try { /** * Close the preparedStatement */ if (preparedStatement != null) { preparedStatement.close(); } /** * Close the connection */ if (connection != null) { connection.close(); } } catch (SQLException e) { /** * Handle any exception */ e.printStackTrace(); } } } }
Как вы можете видеть, это в основном стандартный код, необходимый для управления ресурсами и обработки исключений. Приведенный ниже код показывает, как Spring JDBCTemplate может упростить эту задачу для вас.
public class ForumDAOImpl implements ForumDAO { private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } public void insertForum(Forum forum) { /** * Specify the statement */ String query = "INSERT INTO FORUMS (FORUM_ID, FORUM_NAME, FORUM_DESC) VALUES (?,?,?)"; /** * Specify the values */ jdbcTemplate.update(query, new Object[] { Integer.valueOf(forum.getForumId()), forum.getForumName(), forum.getForumDesc() }); } }
Используя JDBCTemplate, вы пишете код, относящийся только к вставке данных, а весь другой шаблонный код заботится о самом шаблоне. Доступны разные методы update () , вы можете реализовать тот, который прост и соответствует вашим потребностям. Тот, который мы реализовали здесь, принимает запрос sql и массив Object, который содержит значения, которые должны быть привязаны к индексированным параметрам запроса. JDBCTemplate подходит для JDK 1.4 и выше.
Метод selectForum () ниже показывает объем кода, который вам нужно написать для извлечения данных с использованием JDBC.
package com.vaannila.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import com.vaannila.domain.Forum; public class JDBCForumDAOImpl implements ForumDAO { private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public Forum selectForum(int forumId) { /** * Specify the statement */ String query = "SELECT * FROM FORUMS WHERE FORUM_ID=?"; /** * Define the connection, preparedStatement and resultSet parameters */ Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { /** * Open the connection */ connection = dataSource.getConnection(); /** * Prepare the statement */ preparedStatement = connection.prepareStatement(query); /** * Bind the parameters to the PreparedStatement */ preparedStatement.setInt(1, forumId); /** * Execute the statement */ resultSet = preparedStatement.executeQuery(); Forum forum = null; /** * Extract data from the result set */ if(resultSet.next()) { forum = new Forum(resultSet.getInt("FORUM_ID"), resultSet.getString("FORUM_NAME"), resultSet.getString("FORUM_DESC")); } return forum; } catch (SQLException e) { /** * Handle any exception */ e.printStackTrace(); } finally { try { /** * Close the resultSet */ if (resultSet != null) { resultSet.close(); } /** * Close the preparedStatement */ if (preparedStatement != null) { preparedStatement.close(); } /** * Close the connection */ if (connection != null) { connection.close(); } } catch (SQLException e) { /** * Handle any exception */ e.printStackTrace(); } } return null; } }
Теперь посмотрим, как вы можете удалить шаблонный код, используя Spring JDBCTemplate .
package com.vaannila.dao; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import com.vaannila.domain.Forum; public class ForumDAOImpl implements ForumDAO { private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } public Forum selectForum(int forumId) { /** * Specify the statement */ String query = "SELECT * FROM FORUMS WHERE FORUM_ID=?"; /** * Implement the RowMapper callback interface */ return (Forum) jdbcTemplate.queryForObject(query, new Object[] { Integer.valueOf(forumId) }, new RowMapper() { public Object mapRow(ResultSet resultSet, int rowNum) throws SQLException { return new Forum(resultSet.getInt("FORUM_ID"), resultSet.getString("FORUM_NAME"), resultSet.getString("FORUM_DESC")); } }); } }
Здесь необходимо реализовать mapRow () метод RowMapper интерфейса обратного вызова. В методе mapRow () сопоставьте одну строку набора результатов с объектом Forum. Метод queryForObject () принимает SQL-запрос, массив Object, который содержит значения, которые должны быть привязаны к индексированным параметрам запроса, и объект RowMapper .
Вам не нужно явно обрабатывать исключения, связанные с базой данных, вместо этого Spring JDBC Framework будет обрабатывать их за вас. Все исключения, создаваемые Spring JDBC Framework, являются подклассами DataAccessException. DataAccessException является тип RuntimeException , так что вы не обязаны обращаться. SQLException является проверяемым исключение, когда вы бросаете SQLException здесь Spring JDBC Framework будет обернуть это проверяемое исключение внутри одного из подклассов DataAccessException и повторно выдать его, это устраняет необходимость явно обрабатывать их.
В файле конфигурации bean-компонента Spring необходимо сначала настроить источник данных, а затем внедрить его в класс DAO.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="org.hsqldb.jdbcDriver"/> <property name="url" value="jdbc:hsqldb:hsql://localhost"/> <property name="username" value="sa"/> <property name="password" value=""/> </bean> <bean id="forumDAO" class="com.vaannila.dao.ForumDAOImpl"> <property name="dataSource" ref="dataSource"/> </bean> </beans>
Здесь мы используем пулы соединений базы данных Jakarta Commons (DBCP) для настройки источника данных. BasicDataSource можно легко настроить и поддерживает пул соединений. Для использования DBCP у вас должен быть следующий jar-файл в classpath commons-dbcp.jar и commons-pool.jar . После создания источника данных введите источник данных в класс DAO. В классе DAO мы используем этот источник данных для создания объекта JDBCTemplate .
Следующие файлы JAR необходимы для запуска примера. Все связанные с JDBCTemplate файлы находятся в файле org.springframework.jdbc-3.0.0.M3.jar, а все связанные с DataAccessException классы находятся в файле org.springframework.transaction-3.0.0.M3.jar .
antlr-runtime-3.0 commons-logging-1.0.4 org.springframework.asm-3.0.0.M3 org.springframework.beans-3.0.0.M3 org.springframework.context-3.0.0.M3 org.springframework.context.support-3.0.0.M3 org.springframework.core-3.0.0.M3 org.springframework.expression-3.0.0.M3 org.springframework.jdbc-3.0.0.M3.jar org.springframework.transaction-3.0.0.M3.jar hsqldb.jar commons-dbcp.jar commons-pool.jar
Для выполнения примера запустите следующий основной класс.
package com.vaannila.dao; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.vaannila.domain.Forum; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); ForumDAO forumDAO = (ForumDAO) context.getBean("forumDAO"); Forum springForum = new Forum(1,"Spring Forum", "Discuss everything related to Spring"); forumDAO.insertForum(springForum); System.out.println(forumDAO.selectForum(1)); } }
Вы можете скачать и попробовать пример здесь.