2013-07-25 6 views
27

Per Frühling documentation, die Schritte Frühling JdbcTemplate ist wie folgt zu verwenden:mit Spring JdbcTemplate - Injizieren Datenquelle 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> 

Und dann

@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... 
    } 

Grundsätzlich ist die JdbcTemplate erstellt innerhalb der Component-Klasse mit dem Setter für die Datenquelle.

Ist etwas falsch damit, es stattdessen zu tun, so dass es genau eine Instanz von jdbcTemplate in der Anwendung gibt?

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

Und dann die jdbcTemplate selbst direkt in die Komponente

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


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

Gibt es einen Grund, warum die jdbcTemplate selbst injizieren müssen in die Komponentenklasse nicht direkt injiziert werden?

SGB

+0

kann ein Duplikat von http: // stackoverflo w.com/q/9460507/309399. Aber die Frage wird nicht beantwortet. – SGB

Antwort

24

Sie können tun, was Sie wollen. The javadoc of JdbcTemplate sogar deutlich sagt es:

innerhalb einer Service-Implementierung über direkte Instanziierung mit einer Datasource Referenz verwendet werden kann, oder in einem Anwendungskontext und zu Dienstleistungen wie Bohnen Bezug gegeben wird erhalten.

+2

++ für den Link. Danke für die knappe Antwort und das Zitat aus dem Javadoc. Diese spezielle Frage stört mich schon seit einiger Zeit - alle Beispiele, die ich online gesehen habe, scheinen die Datenquelle zu injizieren - und mich fragen lassen, ob ich etwas verpasst habe ... – SGB

21

Im Frühjahr-context.xml fügen Sie den folgenden und

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

und direkt können Sie jdbcTemplate verwenden, indem autowiring wie

@Autowired JdbcTemplate jdbcTemplate; 

Beispiel:

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

Wie mache ich dasselbe für mehrere Datenquellen? Kann ich Folgendes angeben: und für eine andere Datenquelle wie . Ist dies die richtige Methode, um die multiple Datenquelle auf eine JDBC-Vorlage – Analysts

+0

@Analysys zu setzen, sollten Sie eine separate jdbcTemplate für jede Datenquelle definieren. Wenn Sie also 2 Datenquellen haben, Sie hätten jdbcTemplate1 für dataSource1 und jdbcTemplate2 für dataSource2 und fügen die jdbcTemplates nach Bedarf separat in Ihre Serviceschicht ein – SGB

+0

Was @SCB gesagt hat, ist richtig, Sie müssen mehrere Beans für mehrere Datenbanken haben. – Odaiah

5

Sie kann es auch tun

@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); 
    } 
} 

Haupt

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); 
    } 
} 

Dank