rowmapper query example ejemplos baeldung java spring jdbctemplate

java - query - Varias instancias de JdbcTemplate o no?



jdbctemplate spring boot (3)

Por lo que entiendo, tanto DataSource como JdbcTemplates son threadsafe para threadsafe , por lo que puede configurar una instancia única de JdbcTemplate y luego inyectar esta referencia compartida en varios DAO (o repositorios) de manera segura . Además, DataSource debe ser un singleton de Spring, ya que administra el grupo de conexiones.

Las mejores prácticas oficiales de Spring Documentation JdbcTemplate explican las alternativas (los extractos del manual están en cursiva y mis notas entre corchetes:

  • configure un DataSource en su archivo de configuración de Spring, y luego ingrese dependencias ese bean DataSource compartido en sus clases DAO; El JdbcTemplate se crea en el setter para el DataSource. [con la configuración XML y esto conduce a múltiples instancias de JdbcTemplate, ya que en el configurador de fuente de datos hay una new JdbcTemplate(dataSource) ]
  • utilice el componente de escaneo y soporte de anotación para la inyección de dependencia. En este caso, anote la clase con @Repository (lo que la convierte en una candidata para el escaneo de componentes) y anote el método de establecimiento de DataSource con @Autowired. [También este caso conduce a múltiples instancias de JdbcTemplate]
  • Si está utilizando la clase JdbcDaoSupport de Spring y sus diversas clases DAO respaldadas por JDBC se extienden desde ella, entonces su subclase hereda un método setDataSource (..) de la clase JdbcDaoSupport. Puede elegir si desea heredar de esta clase. La clase JdbcDaoSupport se proporciona solo para su comodidad. [ya que tiene una instancia de JdbcDaoSupport para cada clase que la extiende, también hay una instancia de JdbcTemplate para cada instancia de la clase derivada (consulte el código fuente de JdbcDaoSupport )]

Sin embargo, una nota posterior, desalienta todas las opciones que se acaban de presentar:

Una vez configurada, una instancia de JdbcTemplate es segura para subprocesos. Es posible que desee varias instancias de JdbcTemplate si su aplicación accede a múltiples bases de datos, lo que requiere múltiples DataSources y, posteriormente, múltiples JdbcTemplates configurados de manera diferente.

En otras palabras, todas las opciones que se acaban de presentar darán lugar a múltiples instancias de JdbcTemplate (una por DAO), y justo después de que la documentación indique que no es necesario cuando se trabaja con una sola base de datos.

Lo que haría sería inyectar directamente JdbcTemplate a los diversos DAO que lo necesiten, así que mi pregunta es: ¿está bien hacerlo? Y también, ¿crees que la documentación de referencia de Spring se contradice? ¿O es mi malentendido?


En mi opinión, no hay problema para inyectar JdbcTemplate a su (múltiples) DAO (s). La plantilla se utiliza para "conectar" su DAO al recurso físico (conexión de base de datos) cuando necesita ejecutar la consulta de base de datos. Por lo tanto, si SessionFactory y TransactionManager están configurados correctamente, no tendrá problemas de concurrencia: Spring administra el ciclo de vida de los beans que necesita para trabajar con su capa de persistencia. Las ventajas de usar una plantilla son:

  1. La plantilla JDBC gestiona los recursos físicos necesarios para interactuar con la base de datos automáticamente, por ejemplo, crear y liberar las conexiones de la base de datos.
  2. La plantilla Spring JDBC convierte las SQLExceptions de JDBC estándar en RuntimeExceptions. Esto le permite reaccionar más flexible a los errores. La plantilla Spring JDBC convierte también los mensajes de error específicos del proveedor en mensajes de error más comprensibles

Inherentemente la primavera es muy sutil sobre las mejores prácticas.

JdbcTemplate es seguro para subprocesos, notablemente sin bloqueo (v4.2.4). Lo que significa que no debería causar una degradación del rendimiento cuando se comparte entre subprocesos concurrentes *. Por lo tanto, no hay razones de peso para más de una instancia por fuente de datos.

Nota especulativa: esta sección es de hecho confusa. Probablemente debido a razones históricas (evolutivas). Tal vez la primavera tuvo una política por día en el pasado debido a la falta de seguridad de subprocesos o una subestimación deficiente del dominio a la vez. Similar a la configuración basada en xml "desastre". Hoy en día la primavera renuncia a las opiniones opinadas y se esfuerza por ser flexible en su lugar. Lo que, desafortunadamente, llevó a que las malas elecciones de diseño se reconocieran solo de manera encubierta.

* medida no adivinar


por lo que se debe derramar dos situaciones:

No cambiamos las propiedades de JdbcTemplate en DAO, podemos definirlas a continuación:

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

NOTA: La mayoría de las veces no cambiamos las propiedades de JdbcTemplate, porque no es necesario.

Cambiamos las propiedades de JdbcTemplate en DAO, deberíamos ampliar 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

    la clase abstracta pública JdbcDaoSupport extiende 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(); } }

Resumen: No creo que la primavera dé la práctica en guía es la mejor.