001/* 002 * Copyright 2002-2012 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jdbc.core.support; 018 019import java.sql.Connection; 020import javax.sql.DataSource; 021 022import org.springframework.dao.support.DaoSupport; 023import org.springframework.jdbc.CannotGetJdbcConnectionException; 024import org.springframework.jdbc.core.JdbcTemplate; 025import org.springframework.jdbc.datasource.DataSourceUtils; 026import org.springframework.jdbc.support.SQLExceptionTranslator; 027 028/** 029 * Convenient super class for JDBC-based data access objects. 030 * 031 * <p>Requires a {@link javax.sql.DataSource} to be set, providing a 032 * {@link org.springframework.jdbc.core.JdbcTemplate} based on it to 033 * subclasses through the {@link #getJdbcTemplate()} method. 034 * 035 * <p>This base class is mainly intended for JdbcTemplate usage but can 036 * also be used when working with a Connection directly or when using 037 * {@code org.springframework.jdbc.object} operation objects. 038 * 039 * @author Juergen Hoeller 040 * @since 28.07.2003 041 * @see #setDataSource 042 * @see #getJdbcTemplate 043 * @see org.springframework.jdbc.core.JdbcTemplate 044 */ 045public abstract class JdbcDaoSupport extends DaoSupport { 046 047 private JdbcTemplate jdbcTemplate; 048 049 050 /** 051 * Set the JDBC DataSource to be used by this DAO. 052 */ 053 public final void setDataSource(DataSource dataSource) { 054 if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) { 055 this.jdbcTemplate = createJdbcTemplate(dataSource); 056 initTemplateConfig(); 057 } 058 } 059 060 /** 061 * Create a JdbcTemplate for the given DataSource. 062 * Only invoked if populating the DAO with a DataSource reference! 063 * <p>Can be overridden in subclasses to provide a JdbcTemplate instance 064 * with different configuration, or a custom JdbcTemplate subclass. 065 * @param dataSource the JDBC DataSource to create a JdbcTemplate for 066 * @return the new JdbcTemplate instance 067 * @see #setDataSource 068 */ 069 protected JdbcTemplate createJdbcTemplate(DataSource dataSource) { 070 return new JdbcTemplate(dataSource); 071 } 072 073 /** 074 * Return the JDBC DataSource used by this DAO. 075 */ 076 public final DataSource getDataSource() { 077 return (this.jdbcTemplate != null ? this.jdbcTemplate.getDataSource() : null); 078 } 079 080 /** 081 * Set the JdbcTemplate for this DAO explicitly, 082 * as an alternative to specifying a DataSource. 083 */ 084 public final void setJdbcTemplate(JdbcTemplate jdbcTemplate) { 085 this.jdbcTemplate = jdbcTemplate; 086 initTemplateConfig(); 087 } 088 089 /** 090 * Return the JdbcTemplate for this DAO, 091 * pre-initialized with the DataSource or set explicitly. 092 */ 093 public final JdbcTemplate getJdbcTemplate() { 094 return this.jdbcTemplate; 095 } 096 097 /** 098 * Initialize the template-based configuration of this DAO. 099 * Called after a new JdbcTemplate has been set, either directly 100 * or through a DataSource. 101 * <p>This implementation is empty. Subclasses may override this 102 * to configure further objects based on the JdbcTemplate. 103 * @see #getJdbcTemplate() 104 */ 105 protected void initTemplateConfig() { 106 } 107 108 @Override 109 protected void checkDaoConfig() { 110 if (this.jdbcTemplate == null) { 111 throw new IllegalArgumentException("'dataSource' or 'jdbcTemplate' is required"); 112 } 113 } 114 115 116 /** 117 * Return the SQLExceptionTranslator of this DAO's JdbcTemplate, 118 * for translating SQLExceptions in custom JDBC access code. 119 * @see org.springframework.jdbc.core.JdbcTemplate#getExceptionTranslator() 120 */ 121 protected final SQLExceptionTranslator getExceptionTranslator() { 122 return getJdbcTemplate().getExceptionTranslator(); 123 } 124 125 /** 126 * Get a JDBC Connection, either from the current transaction or a new one. 127 * @return the JDBC Connection 128 * @throws CannotGetJdbcConnectionException if the attempt to get a Connection failed 129 * @see org.springframework.jdbc.datasource.DataSourceUtils#getConnection(javax.sql.DataSource) 130 */ 131 protected final Connection getConnection() throws CannotGetJdbcConnectionException { 132 return DataSourceUtils.getConnection(getDataSource()); 133 } 134 135 /** 136 * Close the given JDBC Connection, created via this DAO's DataSource, 137 * if it isn't bound to the thread. 138 * @param con Connection to close 139 * @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection 140 */ 141 protected final void releaseConnection(Connection con) { 142 DataSourceUtils.releaseConnection(con, getDataSource()); 143 } 144 145}