2013-07-25 56 views
27

作爲在每個Spring documentation, 步驟使用Spring的JdbcTemplate如下:Spring的JdbcTemplate - 注入數據源VS的JdbcTemplate

<?xml version="1.0" encoding="UTF-8"?> 
    <beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xsi:schemaLocation=" 
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 

     <!-- Scans within the base package of the application for @Components to configure as beans --> 
     <context:component-scan base-package="org.springframework.docs.test" /> 

     <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"/> 

    </beans> 

然後,

@Repository 
    public class JdbcCorporateEventDao implements CorporateEventDao { 

     private JdbcTemplate jdbcTemplate; 

     @Autowired 
     public void setDataSource(DataSource dataSource) { 
      this.jdbcTemplate = new JdbcTemplate(dataSource); 
     } 

     // JDBC-backed implementations of the methods on the CorporateEventDao follow... 
    } 

基本上,在創建的JdbcTemplate在Component類中使用數據源的setter。

這樣做是否有什麼問題,以便在應用程序中只有一個jdbcTemplate實例?

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" 
    p:dataSource-ref="dataSource" 
/> 

然後注入的JdbcTemplate本身直接進入組件

@Repository 
public class JdbcCorporateEventDao implements CorporateEventDao { 
    @Resource("jdbcTemplate") 
    private JdbcTemplate jdbcTemplate; 


    // JDBC-backed implementations of the methods on the CorporateEventDao follow... 
} 

有沒有爲什麼的JdbcTemplate本身不能被注入到直接組件類的理由?

SGB

+0

可能是HTTP的副本:// stackoverflo w.com/q/9460507/309399。但問題沒有回答。 – SGB

回答

24

你可以做你想做的。 The javadoc of JdbcTemplate甚至明確表示它:

可以服務實現內通過直接實例化時使用一個DataSource引用,或在應用程序上下文獲得準備並提供給服務bean的引用。

+2

++爲鏈接。感謝您的簡潔的回答以及javadoc的引用。這個特定的問題一直困擾着我很長一段時間 - 因爲我在網上看到的所有例子似乎注入了數據源 - 讓我想知道我是否錯過了一些東西... – SGB

21

在彈簧context.xml中添加下列和

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 
    <property name="dataSource" ref="dataSource"/> 
</bean> 

,直接就可以通過自動裝配像

@Autowired JdbcTemplate jdbcTemplate; 

例子中使用的JdbcTemplate:

this.jdbcTemplate.query("select * from ******",new RowMapper()); 
+0

如何爲多個數據源做同樣的事情?我可以這樣指定: 以及另一個數據源,如 。這是將多個數據源設置爲JDBC模板的正確方法 – Analysts

+0

@Analysts,您應該爲每個數據源定義一個單獨的jdbcTemplate,因此如果您有2個數據源,你需要jdbcTemplate1爲datasource1,jdbcTemplate2爲datasource2,然後根據需要分別注入jdbcTemplates到你的服務層。 – SGB

+0

@SCB說的是對的,你必須爲多個數據庫擁有多個bean。 – Odaiah

5

你也可以這樣做,如

@Configuration 
@Import({PersistenceConfig.class}) 
@ComponentScan(basePackageClasses = { 
    ServiceMarker.class, 
    RepositoryMarker.class } 
) 
public class AppConfig { 

    /** 
    * To resolve ${} in @Values, you must register a static PropertySourcesPlaceholderConfigurer in either XML or 
    * annotation configuration file. 
    */ 
    @Bean 
    public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() { 
     return new PropertySourcesPlaceholderConfigurer(); 
    } 
} 

PersistenceConfig

@Configuration 
@PropertySource(value = { "classpath:database/jdbc.properties" }) 
@EnableTransactionManagement 
public class PersistenceConfig { 

    @Autowired 
    private Environment env; 

/** 
    * The @Bean annotation is used to declare a Spring bean and the DI requirements. The @Bean annotation is equivalent to 
* the <bean> tag, the method name is equivalent to the id attribute within the <bean> tag. 
    * 
    * <bean id="mySqlDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" 
     p:driverClassName="${jdbc.mysql.driverClassName}" 
     p:url="${jdbc.mysql.url}" 
     p:username="${jdbc.mysql.username}" 
     p:password="${jdbc.mysql.password}" /> 
    * 
    * @return 
    */ 
    @Bean(destroyMethod = "close") 
    public DataSource mySqlDataSource() { 
     BasicDataSource dataSource = new BasicDataSource(); 
     dataSource.setDriverClassName(env.getProperty("jdbc.mysql.driverClassName")); 
     dataSource.setUrl(env.getProperty("jdbc.mysql.url")); 
     dataSource.setUsername(env.getProperty("jdbc.mysql.username")); 
     dataSource.setPassword(env.getProperty("jdbc.mysql.password")); 
     return dataSource; 
    } 

    @Bean(destroyMethod = "close") 
    public DataSource ls360DataSource() { 
     BasicDataSource dataSource = new BasicDataSource(); 
     dataSource.setDriverClassName(env.getProperty("jdbc.ls360.driverClassName")); 
     dataSource.setUrl(env.getProperty("jdbc.ls360.url")); 
     dataSource.setUsername(env.getProperty("jdbc.ls360.username")); 
     dataSource.setPassword(env.getProperty("jdbc.ls360.password")); 
     return dataSource; 
    } 
} 

MySqlDaoImpl

@Repository 
public class MySqlDaoImpl implements MySqlDao{ 

    private static final Logger logger = LogManager.getLogger(); 

    @Inject 
    private DataSource mySqlDataSource; 
    private JdbcTemplate mySqlJdbcTemplate; 

    @PostConstruct 
    public void afterPropertiesSet() throws Exception { 
     if (mySqlDataSource == null) { 
      throw new BeanCreationException("Must set mySqlDataSource on " + this.getClass().getName()); 
     } 
     this.mySqlJdbcTemplate = new JdbcTemplate(mySqlDataSource); 
    } 

    @Override 
    public void callStoredProcedure(String storedProcedureName, Map<String, Object> inParamMap) throws Exception { 

     SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(mySqlJdbcTemplate).withProcedureName(storedProcedureName); 
     SqlParameterSource in = new MapSqlParameterSource(inParamMap); 

     logger.info("Calling stored Procedure: " + storedProcedureName); 
     Map<String, Object> simpleJdbcCallResult = simpleJdbcCall.execute(in); 
     logger.info("Stored Procedure Result: " + simpleJdbcCallResult); 
    } 
} 

主要

public static void main(String[] args) { 
    try (GenericApplicationContext springContext = new AnnotationConfigApplicationContext(AppConfig.class)) { 
     MySQLDao mySqlDao = springContext.getBean(MySQLDaoImpl.class); 
     try { 
      Map<String, Object> inParamMap = new HashMap<String, Object>(); 
      inParamMap.put("iCourseId", 1); 
      mySqlCourseRenewalDao.callStoredProcedure("usp_processCourseRenewal", inParamMap); 
     } catch (Exception e) { 
      logger.error("Exception occurs", e); 
     } 
    } catch (Exception e) { 
     logger.error("Exception occurs in loading Spring context: ", e); 
    } 
} 

感謝

相關問題