복붙노트

[SPRING] Spring을 사용하여 JdbcTemplate - 데이터 소스 대 jdbcTemplate 삽입하기

SPRING

Spring을 사용하여 JdbcTemplate - 데이터 소스 대 jdbcTemplate 삽입하기

Spring 문서에 따르면, Spring 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은 데이터 소스에 대한 setter를 사용하여 Component 클래스 내에 작성됩니다.

대신이 방법으로 잘못해서 응용 프로그램에 jdbcTemplate의 인스턴스가 하나만 존재합니까?

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

그런 다음 jdbcTemplate 자체를 Component에 직접 삽입합니다.

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


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

jdbcTemplate 자체를 컴포넌트 클래스에 직접 주입해서는 안되는 이유가 있습니까?

SGB

해결법

  1. ==============================

    1.당신이 원하는 것을 할 수 있습니다. JdbcTemplate의 javadoc은 분명히 다음과 같이 말합니다.

    당신이 원하는 것을 할 수 있습니다. JdbcTemplate의 javadoc은 분명히 다음과 같이 말합니다.

  2. ==============================

    2.spring-context.xml에 다음을 추가합니다.

    spring-context.xml에 다음을 추가합니다.

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

    직접 autowiring과 같이 jdbcTemplate을 사용할 수 있습니다.

      @Autowired JdbcTemplate jdbcTemplate;
    

    예:

    this.jdbcTemplate.query("select * from ******",new RowMapper());
    
  3. ==============================

    3.당신도 그것을 할 수 있습니다.

    당신도 그것을 할 수 있습니다.

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

    감사

  4. from https://stackoverflow.com/questions/17868096/using-spring-jdbctemplate-injecting-datasource-vs-jdbctemplate by cc-by-sa and MIT license