如何挑选网站主机做亚马逊有哪些站外折扣网站
多数据源(数据源进行切换)
AbstractRoutingDataSource 根据用户定义的规则选择当前的数据源,这样我们可以在执行查询之前,设置使用的数据源。实现可动态路由的数据源,在每次数据库查询操作前执行。它的抽象方法 determineCurrentLookupKey() 决定使用哪个数据源。
1、application.yml中配置多个数据源
# Order
spring.datasource.order.url=jdbc:mysql://localhost:3306/seata_order?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false
spring.datasource.order.username=root
spring.datasource.order.password=123456
spring.datasource.order.driver-class-name=com.mysql.cj.jdbc.Driver
# Storage
spring.datasource.storage.url=jdbc:mysql://localhost:3306/seata_storage?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false
spring.datasource.storage.username=root
spring.datasource.storage.password=123456
spring.datasource.storage.driver-class-name=com.mysql.cj.jdbc.Driver
# Pay
spring.datasource.pay.url=jdbc:mysql://localhost:3306/seata_pay?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false
spring.datasource.pay.username=root
spring.datasource.pay.password=123456
spring.datasource.pay.driver-class-name=com.mysql.cj.jdbc.Driver
2、主启动类添加注解
@SpringBootApplication
@MapperScan("com.example.demo.mapper")
3、编写配置类
@Getter
public enum DataSourceKey {
     /**
     * Order data source key.
     */
    ORDER,
     /**
     * Storage data source key.
     */
    STORAGE,
     /**
     * Pay data source key.
     */
    PAY,
}
public class DynamicDataSourceContextHolder {
     private static final ThreadLocal<String> CONTEXT_HOLDER = ThreadLocal.withInitial(DataSourceKey.ORDER::name);
     private static List<Object> dataSourceKeys = new ArrayList<>();
     public static void setDataSourceKey(DataSourceKey key) {
         CONTEXT_HOLDER.set(key.name());
    }
     public static String getDataSourceKey() {
         return CONTEXT_HOLDER.get();
    }
     public static void clearDataSourceKey() {
         CONTEXT_HOLDER.remove();
    }
     public static List<Object> getDataSourceKeys() {
         return dataSourceKeys;
    }
}
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
     @Override
     protected Object determineCurrentLookupKey() {
         //log.info("当前数据源 [{}]", DynamicDataSourceContextHolder.getDataSourceKey());
        return DynamicDataSourceContextHolder.getDataSourceKey();
    }
}
@Configuration
public class DataSourceProxyConfig {
     @Bean("originOrder")
     @ConfigurationProperties(prefix = "spring.datasource.order")
     public DataSource dataSourceMaster() {
         return new DruidDataSource();
    }
     @Bean("originStorage")
     @ConfigurationProperties(prefix = "spring.datasource.storage")
     public DataSource dataSourceStorage() {
         return new DruidDataSource();
    }
     @Bean("originPay")
     @ConfigurationProperties(prefix = "spring.datasource.pay")
     public DataSource dataSourcePay() {
         return new DruidDataSource();
    }
     @Bean(name = "order")
     public DataSourceProxy masterDataSourceProxy(@Qualifier("originOrder") DataSource dataSource) {
         return new DataSourceProxy(dataSource);
    }
     @Bean(name = "storage")
     public DataSourceProxy storageDataSourceProxy(@Qualifier("originStorage") DataSource dataSource) {
         return new DataSourceProxy(dataSource);
    }
     @Bean(name = "pay")
     public DataSourceProxy payDataSourceProxy(@Qualifier("originPay") DataSource dataSource) {
         return new DataSourceProxy(dataSource);
    }
     @Bean("dynamicDataSource")
     public DataSource dynamicDataSource(@Qualifier("order") DataSource dataSourceOrder,
                                         @Qualifier("storage") DataSource dataSourceStorage,
                                         @Qualifier("pay") DataSource dataSourcePay) {
        DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
        Map<Object, Object> dataSourceMap = new HashMap<>(3);
        dataSourceMap.put(DataSourceKey.ORDER.name(), dataSourceOrder);
        dataSourceMap.put(DataSourceKey.STORAGE.name(), dataSourceStorage);
        dataSourceMap.put(DataSourceKey.PAY.name(), dataSourcePay);
        dynamicRoutingDataSource.setDefaultTargetDataSource(dataSourceOrder);
        dynamicRoutingDataSource.setTargetDataSources(dataSourceMap);
        DynamicDataSourceContextHolder.getDataSourceKeys().addAll(dataSourceMap.keySet());
         return dynamicRoutingDataSource;
    }
     @Bean
    @ConfigurationProperties(prefix = "mybatis-plus")  // MybatisSqlSessionFactoryBean中有各种MybatisPlus的配置属性(globalConfig、mapperLocations} 而SqlSessionFactoryBean中则是mybatis的各种配置属性(typeAlies、mapperLocations) 
     public MybatisSqlSessionFactoryBean sqlSessionFactoryBean(@Qualifier("dynamicDataSource") DataSource dataSource) {
         // 这里用 MybatisSqlSessionFactoryBean 代替了 SqlSessionFactoryBean,否则 MyBatisPlus 不会生效
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
         return mybatisSqlSessionFactoryBean;
    }
}
调用切换数据源:
@GlobalTransactional
@Override
public OperationResponse placeOrder(PlaceOrderRequestVO placeOrderRequestVO) throws Exception {
     DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.ORDER);//切换数据源
    Integer amount = 1;
    Integer price = placeOrderRequestVO.getPrice();
    Order order = Order.builder().build();
    Integer saveOrderRecord = orderDao.insert(order);
     // 扣减库存
    boolean operationStorageResult = storageService.reduceStock(placeOrderRequestVO.getProductId(), amount);
     // 扣减余额
    boolean operationBalanceResult = payService.reduceBalance(placeOrderRequestVO.getUserId(), price);
     DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.ORDER);//切换数据源
    order.setStatus(OrderStatus.SUCCESS);
    Integer updateOrderRecord = orderDao.updateById(order);
     return success(operationStorageResult && operationBalanceResult);
}
项目启动报错:Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured
原因:导入spring-mybatis依赖后,springboot启动时会自动加载数据源,由于dataSource配置成多数据源加载不到spring.datasource.url故而报错。
解决:1、主启动类添加@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
2、若上面配置还是无法解决,可以配置一个默认数据源让其启动时加载(不影响,会被多数据源切换时覆盖的):spring.datasource.url
额外:
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession=factory.openSession(); //sqlSession就是用来操作sql语句的
使用 MyBatis-Spring 之后, 会使用SqlSessionFactoryBean来代替SqlSessionFactoryBuilder创建SqlSessionFactory
MybatisPlus需要使用MybatisSqlSessionFactoryBean。
