Al configurar múltiples fuentes de datos en Spring Boot, la sección de MyBatis en application.yml puede no aplicarse, ya que no se indica explícitamente a qué fuente de datos debe vincularse.
Configuración de ejemplo en application.yml
server:
port: 8080
spring:
datasource:
primaria:
jdbc-url: jdbc:mysql://localhost:3306/base_principal?useSSL=false&serverTimezone=UTC
username: usuario
password: clave
driver-class-name: com.mysql.cj.jdbc.Driver
secundaria:
jdbc-url: jdbc:mysql://localhost:3306/base_secundaria?useSSL=false&serverTimezone=UTC
username: usuario
password: clave
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
type-aliases-package: com.example.modelo
mapper-locations: classpath*:mappers/**/*.xml
configuration:
map-underscore-to-camel-case: true
Primera solución: Configuración global
Se mantiene la configuración de camelCase en application.yml y se define un bean para la configuración global de MyBatis.
@Bean
@ConfigurationProperties(prefix = "mybatis.configuration")
public org.apache.ibatis.session.Configuration configuracionMybatis() {
return new org.apache.ibatis.session.Configuration();
}
Luego, se asigna esta connfiguración al crear el SqlSessionFactory:
@Primary
@Bean(name = "fabricaSesionPrimaria")
public SqlSessionFactory crearFabricaSesion(@Qualifier("fuenteDatosPrimaria") DataSource fuenteDatos,
org.apache.ibatis.session.Configuration configuracionMybatis) throws Exception {
SqlSessionFactoryBean fabricaBean = new SqlSessionFactoryBean();
fabricaBean.setDataSource(fuenteDatos);
fabricaBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mappers/*.xml"));
fabricaBean.setTypeAliasesPackage("com.example.modelo");
fabricaBean.setConfiguration(configuracionMybatis);
return fabricaBean.getObject();
}
Código completo de configuración para la fuente de datos primaria:
package com.example.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = {"com.example.repositorio"}, sqlSessionFactoryRef = "fabricaSesionPrimaria")
public class ConfiguracionDatosPrimarios {
@Bean(name = "fuenteDatosPrimaria")
@ConfigurationProperties(prefix = "spring.datasource.primaria")
public DataSource fuenteDatos() {
return DataSourceBuilder.create().build();
}
@Bean
public PlatformTransactionManager gestorTransacciones() {
return new DataSourceTransactionManager(this.fuenteDatos());
}
@Bean
@ConfigurationProperties(prefix = "mybatis.configuration")
public org.apache.ibatis.session.Configuration configuracionMybatis() {
return new org.apache.ibatis.session.Configuration();
}
@Primary
@Bean(name = "fabricaSesionPrimaria")
public SqlSessionFactory fabricaSesionPrimaria(@Qualifier("fuenteDatosPrimaria") DataSource fuenteDatos,
org.apache.ibatis.session.Configuration configuracionMybatis) throws Exception {
SqlSessionFactoryBean fabricaBean = new SqlSessionFactoryBean();
fabricaBean.setDataSource(fuenteDatos);
fabricaBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mappers/*.xml"));
fabricaBean.setTypeAliasesPackage("com.example.modelo");
fabricaBean.setConfiguration(configuracionMybatis);
return fabricaBean.getObject();
}
}
Segunda solución: Configuración directa en SqlSessionFactory
Se establece el mapeo camelCase directamente al obtener el objeto SqlSessionFactory:
sqlSessionFactoryBean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
Ejemplo de implementación en el método del bean:
@Primary
@Bean(name = "fabricaSesionPrimaria")
public SqlSessionFactory fabricaSesionPrimaria(@Qualifier("fuenteDatosPrimaria") DataSource fuenteDatos) throws Exception {
SqlSessionFactoryBean fabricaBean = new SqlSessionFactoryBean();
fabricaBean.setDataSource(fuenteDatos);
fabricaBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mappers/*.xml"));
fabricaBean.setTypeAliasesPackage("com.example.modelo");
fabricaBean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
return fabricaBean.getObject();
}
Esta solución no requiere un bean separado para la configuración de MyBatis y se integra directamente en la creación de la fábrica de sesiones.