问题
This question comes along NoUniqueBeanDefinitionException when multiple datasouces in Spring Boot and Mybatis project. I try to configure two dataSources in Spring Boot and MyBatis project, but exception occurs:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.bookSystem.mapper.UserDao.findByDomain at org.apache.ibatis.binding.MapperMethod$SqlCommand.(MapperMethod.java:227) ~[mybatis-3.4.6.jar:3.4.6] at org.apache.ibatis.binding.MapperMethod.(MapperMethod.java:49) ~[mybatis-3.4.6.jar:3.4.6] at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:65) ~[mybatis-3.4.6.jar:3.4.6] at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:58) ~[mybatis-3.4.6.jar:3.4.6] at com.sun.proxy.$Proxy83.findByDomain(Unknown Source) ~[na:na] at com.bookSystem.serviceImp.UserServiceImp.findByDomain(UserServiceImp.java:72) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
application.properties
# multiple datases
spring.datasource.primary.driverClassName = com.mysql.jdbc.Driver
spring.datasource.primary.url = jdbc:mysql://127.0.0.1/book?useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.datasource.primary.username = root
spring.datasource.primary.password = 123456
spring.datasource.primary.initialization-mode=always
spring.datasource.second.driverClassName = com.mysql.jdbc.Driver
spring.datasource.second.url = jdbc:mysql://127.0.0.1/newBook?useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.datasource.second.username = root
spring.datasource.second.password = 123456
spring.datasource.second.initialization-mode=always
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mapper directories
start of project
@SpringBootApplication( exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class
})
@EnableTransactionManagement
public class BookSystemApplication {
}
datasource configuration
@Configuration
public class DataSourceConfig {
@Bean(name = "primaryDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondDataSource")
@ConfigurationProperties(prefix = "spring.datasource.second")
public DataSource secondDataSource() {
return DataSourceBuilder.create().build();
}
}
primary dataSource
@Configuration
@MapperScan(basePackages = {"com.bookSystem.mapper"}, sqlSessionFactoryRef = "primarySqlSessionFactory")
public class MyBatisPrimaryDbConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Bean
public SqlSessionFactory primarySqlSessionFactory() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(primaryDataSource);
return factoryBean.getObject();
}
@Bean
public SqlSessionTemplate primarySqlSessionTempmlate() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(primarySqlSessionFactory());
return template;
}
}
Transaction
@Configuration
public class TransactionConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primary;
@Autowired
@Qualifier("secondDataSource")
private DataSource second;
@Bean(name="primaryTx")
@Primary
public PlatformTransactionManager primaryTransaction() {
return new DataSourceTransactionManager(primary);
}
@Bean(name="secondTx")
public PlatformTransactionManager secondTransaction() {
return new DataSourceTransactionManager(second);
}
}
UserDao
package com.bookSystem.mapper;
@Mapper
public interface UserDao {
public User findByDomain(String domainName);
}
userMapper.xml, use primary datasource
<mapper namespace = "com.bookSystem.mapper.UserDao">
<select id="findByDomain" resultMap= "userResultMap">
SELECT
u.userId as user_user_id,
u.userName as user_user_name,
u.domainName as user_domain_name,
u.department as user_department,
u.title as user_title,
u.date as user_date,
u.password as user_password,
u.accountRole as user_account_role
FROM USER u
WHERE u.domainName = #{domainName}
</select>
UserServiceImp, use primary datasource.Service layer which causes the exception
@Service("UserService")
public class UserServiceImp implements UserService {
@Override
public User findByDomain(String domainName) {
User user = userDao.findByDomain(domainName);
return user;
}
}
来源:https://stackoverflow.com/questions/51320198/bindingexception-occurs-when-multiple-datasources-are-configured-in-spring-boot