一.实现读写分离的多数据源
在application.properties文件中配置多数据源
## master 数据源配置
master.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
master.datasource.username=root
master.datasource.password=123456
master.datasource.driverClassName=com.mysql.jdbc.Driver
## cluster 数据源配置
cluster.datasource.url=jdbc:mysql://localhost:3306/cluster?useUnicode=true&characterEncoding=utf8
cluster.datasource.username=root
cluster.datasource.password=123456
cluster.datasource.driverClassName=com.mysql.jdbc.Driver
主库为 maste ,从库为cluster
@Value("${master.datasource.url}")
private String url;
@Value("${master.datasource.username}")
private String user;
@Value("${master.datasource.password}")
private String password;
@Value("${master.datasource.driverClassName}")
private String driverClass;
public DataSource masterDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(password);
return dataSource;
}
创建masterDataSource和clusterDataSource。
创建动态数据源
@Bean(name = "dynamicDataSource")
@Primary
public DynamicDataSource dynamicDataSource() {
DynamicDataSource dataSource = new DynamicDataSource();
Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
targetDataSources.put("masterDataSource",masterDataSource());
targetDataSources.put("clusterDataSource",clusterDataSource());
dataSource.setTargetDataSources(targetDataSources);
dataSource.setDefaultTargetDataSource(masterDataSource());
return dataSource;
}
创建SqlSessionFactory
@Bean(name = "sqlSessionFactory")
@Primary
public SqlSessionFactory getSqlSessionFactory(@Qualifier("dynamicDataSource") DynamicDataSource dynamicDataSource)
throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dynamicDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(DynamicDataSourceConfig.MAPPER_LOCATION));
return sessionFactory.getObject();
}
二注解实现动态数据源
import java.lang.annotation.*;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSourceType {
String type() default "masterDataSource";
}
AOP的实现,在service实现类实现数据源的切换。
@Aspect
@Component
public class DataSourceAspect {
@Pointcut("execution(public * org.spring.springboot.service.impl..*.*(..))")
public void changeDataSource(){}
@Before("changeDataSource() && @annotation(type)")
public void setDataSource(DataSourceType type) throws Throwable{
System.out.println(type.type());
DataSourceTypeHolder.setCustomerType(type.type());
}
@After("changeDataSource() && @annotation(type)")
public void resetDataSource(DataSourceType type) throws Throwable{
DataSourceTypeHolder.clearCustomerType();
}
}
动态数据源的实现,继承AbstractRoutingDataSource,重载determineCurrentLookupKey方法。
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
String type = DataSourceTypeHolder.getCustomerType();
System.out.println("DynamicDataSource"+type);
return type;
}
}
在service层实现数据源切换
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao; // 主数据源
@Override
@DataSourceType(type = "masterDataSource")
public User findByName(String userName) {
User user = userDao.findByName(userName);
return user;
}
}
这样就实现了数据源的动态切换。
源码地址:https://git.oschina.net/sp999/springboot.git