私の理解では、DataSource
とJdbcTemplates
はどちらもthreadsafe
なので、JdbcTemplate
の単一インスタンスを構成し、この共有参照を複数のDAO(またはリポジトリ)に安全に挿入できます。また、DataSource
は接続プールを管理するため、Springシングルトンである必要があります。
公式 Spring Documentation JdbcTemplateのベストプラクティス 代替案について説明しています(マニュアルからの抜粋はイタリック体で、角括弧で囲まれたメモは次のとおりです。
new JdbcTemplate(dataSource)
があるため、これにより複数のJdbcTemplateインスタンスが生成されます。ただし、後のメモでは、提示されたすべてのオプションを推奨していません。
構成が完了すると、JdbcTemplateインスタンスはスレッドセーフになります。アプリケーションが複数のデータベースにアクセスする場合は、複数のJdbcTemplateインスタンスが必要になることがあります。これには、複数のデータソースが必要であり、その後、異なる構成の複数のJdbcTemplateが必要になります。
言い換えると、提示されたすべてのオプションは、複数のJdbcTemplateインスタンス(DAOごとに1つ)を持つことになり、ドキュメントの直後に、単一のデータベースで作業する場合は必要ありません。
私がすることは、それを必要とするさまざまなDAOに直接JdbcTemplate
を注入することです。したがって、私の質問は、そうしても大丈夫ですか?また、Springのリファレンスドキュメントは自己矛盾していると思いますか?それとも私の誤解ですか?
IMO、JdbcTemplateを(複数の)DAOに挿入するのに問題はありません。テンプレートは、dbクエリを実行する必要があるときにDAOを物理リソース(db接続)に「配線」するために使用されます。したがって、SessionFactoryとTransactionManagerが適切に構成されていれば、並行性の問題が発生することはありません。Springは、永続層での作業に必要なBeanのライフサイクルを管理します。テンプレートを使用する利点は次のとおりです。
したがって、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)
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();
}
}
要約:春にガイドで練習するのが最善だとは思いません。
本質的に、春はベストプラクティスについて非常に微妙です。
JdbcTemplate
はスレッドセーフで、特にロックフリーです(v4.2.4)。つまり、並行スレッド間で共有されたときにパフォーマンスが低下することはありません*。したがって、データソースごとに複数のインスタンスがあるという説得力のある理由はありません。
投機的な注意:このセクションは確かに紛らわしいです。おそらく歴史的(進化的)な理由によるものです。たぶん、春は、スレッドセーフがないか、ドメインの理解が不十分だったために、過去にdaoごとのポリシーがありました。 xmlベースの構成「災害」に似ています。今日、春は意見のある見解を放棄し、代わりに柔軟になるよう努めています。残念ながら、これは悪いデザインの選択がひそかにしか認められないことにつながりました。
*測定は推測しない