【问题标题】:How do I manually configure a JdbcTemplate in Spring Boot?如何在 Spring Boot 中手动配置 JdbcTemplate?
【发布时间】:2017-07-07 12:55:15
【问题描述】:

这是我的基本 DAO 实现类:

@Repository
public class MeetingDaoImpl implements MeetingDao {

  @Autowired
  JdbcTemplate jdbcTemplate;

  public boolean insertNewMeeting(String initials, String meetingId, int numYears) {

    int numRowsAffected = jdbcTemplate.update(SQLConstants.INSERT_NEW_MEETING,
        new Object[] {initials.toLowerCase(), meetingId, numYears});

    return numRowsAffected > 0;

  }
}

jdbcTemplate 自动从我的application.properties 文件中读取spring.datasource 属性,这很好,但它包含我不想提交的数据库密码。相反,我想从本地 server.properties 文件中读取它,而不是从 Java 类中轻松读取它。

有没有办法用 Java 配置 jdbcTemplate?我见过多个使用 bean 和 XML 的示例,但没有使用 Java。

【问题讨论】:

  • 那么不要提交它...与其围绕框架工作,不如与框架一起工作。在启动应用程序时提供密码作为参数,或者在 jar 旁边放入 application.properties 或设置为环境变量。请参阅reference guide,了解如何以及从何处读取属性。

标签: java spring


【解决方案1】:

只需声明一个JdbcTemplate bean:

@Bean
JdbcTemplate jdbcTemplate() throws IllegalAccessException, InvocationTargetException, InstantiationException {
    // extract this 4 parameters using your own logic
    final String driverClassName = "org.h2.Driver";
    final String jdbcUrl = "jdbc:h2:mem:test";
    final String username = "sa";
    final String password = "";
    // Build dataSource manually:
    final Class<?> driverClass = ClassUtils.resolveClassName(driverClassName, this.getClass().getClassLoader());
    final Driver driver = (Driver) ClassUtils.getConstructorIfAvailable(driverClass).newInstance();
    final DataSource dataSource = new SimpleDriverDataSource(driver, jdbcUrl, username, password);
    // or using DataSourceBuilder:
    final DataSource dataSource = DataSourceBuilder.create().driverClassName(driverClassName).url(jdbcUrl).username(username).password(password).build();
    // and make the jdbcTemplate
    return new JdbcTemplate(dataSource);
}

另一种方法不是在application.properties 文件中设置数据源参数,而是在运行时声明它。运行应用时,您可以覆盖 application.properties 中定义的任何属性或定义新属性。

例如:

java -jar my-spring-boot-app.jar --spring.datasource.url=jdbc:h2:mem:test --spring.datasource.username=sa --spring.datasource.password=secret

更复杂的方法是使用spring-cloud-config-serverConsul 来管理您的设置。

【讨论】:

  • 我把这个函数放在一个新的类中,DatabaseConfig,但是我如何在我的 DAO 中实现它?
  • 在 DAO 中只需像以前一样注入 JdbcTemplate,因为它应该像以前一样工作
  • 我不得不将 @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) 添加到主应用程序类中以防止 JDBC 模板的自动配置,但它成功了!谢谢!
  • 您使用的是什么 ClassUtils? Eclipse 给了我 10 种选择。
  • @mmaceachran 来自spring-framework
【解决方案2】:

您可以提供如下属性:

datasource.local.url= datasource.local.driver-class-name= datasource.local.username= datasource.local.password=

创建一个配置类:

@Configuration
   @ConfigurationProperties("datasource.local")
   @EnableJpaRepositories(
        basePackages = "com...",
        transactionManagerRef = "localTransactionManager",
        entityManagerFactoryRef = "localEntityManagerFactory"
    )
    public class OracleConfiguration {
    @NotNull
    private String username;
    @NotNull
    private String password;

    @NotNull
    private String url;

    private String driverClassName;


    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @Bean
    DataSource localDataSource() throws SQLException {

         return DataSourceBuilder
                 .create()
                 .url(this.url)
                 .username(this.username)
                 .password(this.password)
                 .driverClassName(this.driverClassName)
                 .build();
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    @Bean
    @Autowired
    public PlatformTransactionManager localTransactionManager(@Qualifier("localEntityManagerFactory")
                                                                          EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

    @Bean
    @Autowired
    public LocalContainerEntityManagerFactoryBean localEntityManagerFactory(@Qualifier("localDataSource")DataSource dataSource) {

        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();

        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();

        factoryBean.setDataSource(dataSource);
        factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
        factoryBean.setPackagesToScan("com...");

        return factoryBean;
    }
    @Bean
    @Autowired
    public JdbcTemplate localJdbcTemplate(@Qualifier("localDataSource")DataSource dataSource) {
            return new JdbcTemplate(dataSource);
        }}

在您的主应用程序类中,包含此配置文件:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class })
@EnableTransactionManagement
@Import({ OracleConfiguration.class})
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }}

然后在你需要注入模板的类中:

@Autowired
    private JdbcTemplate localJdbcTemplate;

【讨论】:

  • 仅仅配置一个数据源似乎需要做很多工作,没有更简单的方法吗?
【解决方案3】:
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class GetJdbcTemplate {
    @Bean
    public JdbcTemplate getJdbcTemplate() {
        JdbcTemplate template=new JdbcTemplate();
        template.setDataSource(getBasicDataSource());
        return template;
    }
    private BasicDataSource getBasicDataSource() {
        BasicDataSource bds=new BasicDataSource();
        bds.setDriver(new com.microsoft.sqlserver.jdbc.SQLServerDriver());
        bds.setUrl("jdbc:sqlserver://localhost:21443;databaseName=dev");
        bds.setUsername("username");
        bds.setPassword("password");
        bds.setMaxIdle(10);
        bds.setMinIdle(5);
        return bds;
    }
}

【讨论】:

    猜你喜欢
    • 2019-09-10
    • 2016-02-23
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    • 2017-07-30
    • 2015-10-03
    • 1970-01-01
    • 2021-07-07
    相关资源
    最近更新 更多