You can create a data source with a storage area using factory and connect it to the SqlSessionFactory, which is used by the mappers created by mybatis-spring. Here is the relevant section app-context.xml
<bean id="dataSourceFactory" class="com.myapp.TenantDataSourceFactory" depends-on="tenant" scope="singleton"/> <bean id="dataSource" factory-bean="dataSourceFactory" factory-method="getObject" destroy-method="close" scope="tenant" > <aop:scoped-proxy/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:myBatisConfig.xml" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.myapp" /> <property name="annotationClass" value="com.myapp.mapper.Mapper"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean>
And TenantDataSourceFactory:
public class TenantDataSourceFactory { @Autowired Tenant tenant; public DataSource getObject() throws Exception { BasicDataSource ds = new BasicDataSource(); ds.setDriverClassName("org.postgresql.Driver"); ds.setUrl(String.format("jdbc:postgresql://%s:%s/%s", tenant.getDbHost(), tenant.getDbPort(), tenant.getDbName())); ds.setUsername(tenant.getDbUser()); ds.setPassword(tenant.getDbPassword()); return ds; } }
tenant scope is a custom scope that contains Map<String, Map<String, Object>> , which is the tenant name for the beans scope. He goes to the tenant, based on the concept of the current tenant.
source share