web-dev-qa-db-ja.com

複数のJdbcTemplateインスタンスかどうか?

私の理解では、DataSourceJdbcTemplatesはどちらもthreadsafeなので、JdbcTemplateの単一インスタンスを構成し、この共有参照を複数のDAO(またはリポジトリ)に安全に挿入できます。また、DataSourceは接続プールを管理するため、Springシングルトンである必要があります。

公式 Spring Documentation JdbcTemplateのベストプラクティス 代替案について説明しています(マニュアルからの抜粋はイタリック体で、角括弧で囲まれたメモは次のとおりです。

  • Spring構成ファイルでデータソースを構成してから、その共有データソースBeanをDAOクラスに依存性注入します。 JdbcTemplateは、DataSourceのセッターで作成されます。[XML構成では、データソースセッターにnew JdbcTemplate(dataSource)があるため、これにより複数のJdbcTemplateインスタンスが生成されます。
  • 依存性注入のためのコンポーネントスキャンとアノテーションのサポートを使用します。この場合、クラスに@Repository(コンポーネントスキャンの候補になります)で注釈を付け、DataSource setterメソッドに@Autowiredで注釈を付けます。[この場合も複数のJdbcTemplateインスタンスになります]
  • SpringのJdbcDaoSupportクラスを使用していて、JDBCでサポートされているさまざまなDAOクラスがそこから拡張されている場合、サブクラスはJdbcDaoSupportクラスからsetDataSource(..)メソッドを継承します。このクラスから継承するかどうかを選択できます。 JdbcDaoSupportクラスは便宜上提供されています。[それを拡張する各クラスにJdbcDaoSupportのインスタンスがあるため、派生クラスの各インスタンスにもJdbcTemplateのインスタンスがあります(を参照)。 JdbcDaoSupportのソースコード )]

ただし、後のメモでは、提示されたすべてのオプションを推奨していません。

構成が完了すると、JdbcTemplateインスタンスはスレッドセーフになります。アプリケーションが複数のデータベースにアクセスする場合は、複数のJdbcTemplateインスタンスが必要になることがあります。これには、複数のデータソースが必要であり、その後、異なる構成の複数のJdbcTemplateが必要になります。

言い換えると、提示されたすべてのオプションは、複数のJdbcTemplateインスタンス(DAOごとに1つ)を持つことになり、ドキュメントの直後に、単一のデータベースで作業する場合は必要ありません。

私がすることは、それを必要とするさまざまなDAOに直接JdbcTemplateを注入することです。したがって、私の質問は、そうしても大丈夫ですか?また、Springのリファレンスドキュメントは自己矛盾していると思いますか?それとも私の誤解ですか?

21
stivlo

IMO、JdbcTemplateを(複数の)DAOに挿入するのに問題はありません。テンプレートは、dbクエリを実行する必要があるときにDAOを物理リソース(db接続)に「配線」するために使用されます。したがって、SessionFactoryとTransactionManagerが適切に構成されていれば、並行性の問題が発生することはありません。Springは、永続層での作業に必要なBeanのライフサイクルを管理します。テンプレートを使用する利点は次のとおりです。

  1. JDBCテンプレートは、DBと自動的に対話するために必要な物理リソースを管理します。データベース接続を作成して解放します。
  2. Spring JDBCテンプレートは、標準のJDBCSQLExceptionsをRuntimeExceptionsに変換します。これにより、エラーに対してより柔軟に対応できます。 Spring JDBCテンプレートは、ベンダー固有のエラーメッセージもより理解しやすいエラーメッセージに変換します
4
aviad

したがって、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は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();
        }
    }
    

要約:春にガイドで練習するのが最善だとは思いません。

1
zg_spring

本質的に、春はベストプラクティスについて非常に微妙です。

JdbcTemplateはスレッドセーフで、特にロックフリーです(v4.2.4)。つまり、並行スレッド間で共有されたときにパフォーマンスが低下することはありません*。したがって、データソースごとに複数のインスタンスがあるという説得力のある理由はありません。

投機的な注意:このセクションは確かに紛らわしいです。おそらく歴史的(進化的)な理由によるものです。たぶん、春は、スレッドセーフがないか、ドメインの理解が不十分だったために、過去にdaoごとのポリシーがありました。 xmlベースの構成「災害」に似ています。今日、春は意見のある見解を放棄し、代わりに柔軟になるよう努めています。残念ながら、これは悪いデザインの選択がひそかにしか認められないことにつながりました。

*測定は推測しない

0
user2418306