Статьи

Spring JDBC Tutorial

В этом примере вы узнаете, как 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));
		
	}
	
}

Вы можете скачать и попробовать пример здесь.


Источник:
Скачать

Source + Lib:
Скачать