版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_36553913/article/details/82317624
说明
通过在翟永超的博客学习了多数据源的配置章节后,发现当结合实际的需求使用时还有些困难,于是找资料学习了结合mybatis的多数据源配置,在这里记录下。在学习中,使用了两个不同的mysql数据库,分别在本地和虚拟机,用来模拟不同ip的数据库,类似于分库分表后部署在不同地方的情况。
正文
本文通过使用不同的数据源,达到在不同库中查找不同的数据的目的。
1.项目的初始构建
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
通过手动配置数据源,要在项目启动类中排除数据源的自动配置
@SpringBootApplication
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class MulDatasourceApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(MulDatasourceApplication.class, args);
}
}
2.在application.properties中添加配置
#第一数据源
datasource.first.driverClassName=com.mysql.jdbc.Driver
datasource.first.url=jdbc:mysql://ip:3306/dataBase?characterEncoding=UTF-8
datasource.first.username=**
datasource.first.password=**
#第二数据源
datasource.second.driverClassName=com.mysql.jdbc.Driver
datasource.second.url=jdbc:mysql://ip:3306/dataBase?characterEncoding=UTF-8
datasource.second.username=**
datasource.second.password=**
3.编写注解类
该注解用于mybatis的查询时标注接口使用的数据源
第一数据源 UseDatasourceFirst
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface UseDatasourceFirst {
}
第二数据源 UseDatasourceSecond
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface UseDatasourceSecond {
}
4.配置数据源
第一数据源配置
@Configuration
@MapperScan(basePackages = "com.example.mul_datasource.db.dao", annotationClass = UseDatasourceFirst.class, sqlSessionFactoryRef = FirstDatasoruceConfig.SQL_SESSION_FACTOR_NAME)
public class FirstDatasoruceConfig {
public static final String SQL_SESSION_FACTOR_NAME = "sqlSessionFactoryFirst";
public static final String TRANSACTION_MANAGER="txManagerFirst";
protected Logger logger = LoggerFactory.getLogger(FirstDatasoruceConfig.class);
@Bean(name = "datasourceFirst")
@Primary
@ConfigurationProperties(prefix = "datasource.first")
public DataSource dataSourceFirst(){
return DataSourceBuilder.create().build();
}
@Bean(name = TRANSACTION_MANAGER)
@Primary
public PlatformTransactionManager txManagerFirst(@Qualifier("datasourceFirst") DataSource datasourceFirst){
return new DataSourceTransactionManager(datasourceFirst);
}
@Bean(name = FirstDatasoruceConfig.SQL_SESSION_FACTOR_NAME)
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("datasourceFirst") DataSource datasourceFirst) throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(datasourceFirst);
sessionFactoryBean.setTypeAliasesPackage("com.example.mul_datasource.db.pojo");
Resource[] resources = new PathMatchingResourcePatternResolver()
.getResources("classpath:com/example/mul_datasource/db/mapper/*Mapper.xml");
sessionFactoryBean.setMapperLocations(resources);
return sessionFactoryBean.getObject();
}
}
第二数据源配置
@Configuration
@MapperScan(basePackages = "com.example.mul_datasource.db2.dao", annotationClass = UseDatasourceSecond.class, sqlSessionFactoryRef = SecondDatasourceConfig.SQL_SESSION_FACTORY_NAME)
public class SecondDatasourceConfig {
public static final String SQL_SESSION_FACTORY_NAME = "sqlSessionFactorySecond";
public static final String TRANSACTION_MANAGER = "txManageSecond";
protected Logger logger = LoggerFactory.getLogger(SecondDatasourceConfig.class);
@Bean(name = "datasourceSecond")
@ConfigurationProperties(prefix = "datasource.second")
public DataSource dataSourceSecond(){
return DataSourceBuilder.create().build();
}
@Bean(name = SecondDatasourceConfig.TRANSACTION_MANAGER)
public PlatformTransactionManager txManagerSecond(@Qualifier("datasourceSecond") DataSource datasourceSecond){
return new DataSourceTransactionManager(datasourceSecond);
}
@Bean(name = SQL_SESSION_FACTORY_NAME)
public SqlSessionFactory sqlSessionFactory(@Qualifier(value = "datasourceSecond") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
sessionFactoryBean.setTypeAliasesPackage("com.example.mul_datasource.db2.pojo");
Resource[] resources = new PathMatchingResourcePatternResolver()
.getResources("classpath:com/example/mul_datasource/db2/mapper/*Mapper.xml");
sessionFactoryBean.setMapperLocations(resources);
return sessionFactoryBean.getObject();
}
}
5.插件自动生成
通过上篇博文的学习《使用c3p0连接池集成mybatis及mybatis自动代码生成插件》,学习了如果使用插件自动生成代码。这里在第一个主机数据库中创建表teacher,在第二个虚机数据库中创建表student,利用插件分别生成pojo、mapper文件、mapper接口
分别放于不同的package中,在mapper接口类上配置使用编写的注解类
@UseDatasourceFirst
public interface TeacherMapper {
int deleteByPrimaryKey(Integer id);
int insert(Teacher record);
int insertSelective(Teacher record);
Teacher selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Teacher record);
int updateByPrimaryKey(Teacher record);
}
@UseDatasourceSecond
public interface StudentMapper {
int deleteByPrimaryKey(Integer id);
int insert(Student record);
int insertSelective(Student record);
Student selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Student record);
int updateByPrimaryKey(Student record);
}
6.测试
@Autowired
private TeacherMapper teacherMapper;
@Autowired
private StudentMapper studentMapper;
@Test
public void testSelectFirstDatasource(){
Teacher teacher = teacherMapper.selectByPrimaryKey(1);
System.out.println(teacher.getId() + "--" + teacher.getTname());
}
@Test
public void testSelectSecondDatasource(){
Student student = studentMapper.selectByPrimaryKey(1);
System.out.println(student.getId() + "--" + student.getUname() + "--" + student.getAge());
}
问题
- 在使用自动生成代码插件时,一直只生成insert语句,原因是未设置主键
- 数据库的权限问题
- 在配置数据库时,使用的参数名称必须符合要求,driverClassName,url,username,password
源码地址:https://github.com/Edenwds/springboot_study/tree/master/mul_datasource
参考资料:https://github.com/mybatis/spring-boot-starter/issues/78