是否具有多个 JdbcTemplate 实例?

2022-09-01 23:54:07

据我所知,和 都是 ,因此您可以配置 JdbcTemplate 的单个实例,然后安全地将此共享引用注入到多个 DAO(或存储库)中。也应该是一个 Spring 单例,因为它管理连接池。DataSourceJdbcTemplatesthreadsafeDataSource

官方的Spring文档JdbcTemplate最佳实践解释了替代方案(手册的摘录是斜体的,我的注释在方括号之间:

  • 在Spring配置文件中配置一个数据源,然后将该共享的DataSource Bean注入DAO类中;JdbcTemplate在DataSource的设置器中创建。[使用XML配置,这会导致多个JdbcTemplate实例,因为在数据源设置器中有new JdbcTemplate(dataSource)]
  • 使用组件扫描和注释支持进行依赖关系注入。在这种情况下,您可以使用@Repository对类进行批注(这使其成为组件扫描的候选项),并使用@Autowired对 DataSource setter 方法进行批注。[这种情况也会导致多个 JdbcTemplate 实例]
  • 如果您使用的是Spring的JdbcDaoSupport类,并且您的各种JDBC支持的DAO类从它扩展,那么您的子类将从JdbcDaoSupport类继承setDataSource(..)方法。您可以选择是否从此类继承。提供 JdbcDaoSupport 类只是为了方便起见。[由于每个扩展它的类都有一个 JdbcDaoSupport 实例,因此派生类的每个实例也有一个 JdbcTemplate 实例(请参阅 JdbcDaoSupport 的源代码)]

但是,稍后的说明不鼓励刚才提供的所有选项:

配置完成后,JdbcTemplate 实例是线程安全的。如果您的应用程序访问多个数据库,则可能需要多个 JdbcTemplate 实例,这需要多个数据源,随后需要多个不同配置的 JdbcTemplate。

换句话说,刚刚提供的所有选项都将导致具有多个JdbcTemplate实例(每个DAO一个),并且在文档说在使用单个数据库时不需要这样做之后。

我要做的是直接注入需要它的各种DAO,所以我的问题是,这样做可以吗?而且,您是否也认为Spring参考文档是自相矛盾的?还是我的误解?JdbcTemplate


答案 1

IMO,将JdbcTemplate注入您的(多个)DAO没有问题。该模板用于在需要运行数据库查询时将 DAO“连接”到物理资源(数据库连接)。因此,如果SessionFactory和TransalageManager配置正确,您将不会遇到并发问题 - Spring管理使用持久性层所需的Bean的生命周期。使用模板的优点是:

  1. JDBC 模板管理自动与数据库交互所需的物理资源,例如创建和释放数据库连接。
  2. Spring JDBC 模板将标准 JDBC SQLExceptions 转换为 RuntimeExceptions。这使您可以更灵活地对错误做出反应。Spring JDBC 模板还将供应商特定的错误消息转换为更易于理解的错误消息

答案 2

所以它应该是溢出两种情况:

我们不会在 DAO 中更改 JdbcTemplate 属性,我们可以定义如下:

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

注意:大多数情况下,我们不会更改 JdbcTemplate 属性,因为这不是必需的。

我们在 DAO 中更改 JdbcTemplate 属性,我们应该扩展 JdbcDaoSupport。

State:
•   fetchSize: If this variable is set to a non-zero value, it will be used for setting the fetchSize property on statements used for query processing(JDBC Driver default)
•   maxRows: If this variable is set to a non-zero value, it will be used for setting the maxRows property on statements used for query processing(JDBC Driver default)
•   queryTimeout: If this variable is set to a non-zero value, it will be used for setting the queryTimeout property on statements used for query processing.(JDBC Driver default)
•   skipResultsProcessing: If this variable is set to true then all results checking will be bypassed for any callable statement processing.  This can be used to avoid a bug in some older Oracle JDBC drivers like 10.1.0.2.(false)
•   skipUndeclaredResults: If this variable is set to true then all results from a stored procedure call that don't have a corresponding SqlOutParameter declaration will be bypassed. All other results processing will be take place unless the variable {@code skipResultsProcessing} is set to {@code true}(false)
•   resultsMapCaseInsensitive: If this variable is set to true then execution of a CallableStatement will return the results in a Map that uses case insensitive names for the parameters if Commons Collections is available on the classpath.(false)
  1. JdbcDaoSupport

    公共抽象类 JdbcDaoSupport extends DaoSupport {

    private JdbcTemplate jdbcTemplate;
    
    
    /**
     * Set the JDBC DataSource to be used by this DAO.
     */
    public final void setDataSource(DataSource dataSource) {
        if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {
            this.jdbcTemplate = createJdbcTemplate(dataSource);
            initTemplateConfig();
        }
    }
    

总结:我不认为春天给实践指导是最好的。


推荐