项目架构:springboot+dubbo+zookeeper
电商订单项目分正向和逆向两个部分:其中正向数据库记录了订单的基本信息,包括订单基本信息、订单商品信息、优惠卷信息、发票信息、账期信息、结算信息、订单备注信息、收货人信息等;逆向数据库主要包含了商品的退货信息和维修信息。数据量超过500万行就要考虑分库分表和读写分离,那么我们在正向操作和逆向操作的时候,就需要动态的切换到相应的数据库,进行相关的操作。
项目使用mybatis采用开发mapper接口(相当于dao接口)来进行dao的开发,即通过开发mapper接口,将自动生成其代理类来进行操作。其中Mapper代理使用的是jdk的代理策略。假设在执行dao层代码之前能够将数据源(DataSource)换成我们想要执行操作的数据源,那么这个问题就解决了。
首先,我们来找下DataSource接口,然后发现类:AbstractRoutingDataSource,它继承于AbstractDataSource而AbstractDataSource实现了DataSource接口,所以,这是一个标准的数据源。
查看AbstractRoutingDataSource类:
/**
* DataSource抽象类getConnection()方法的实现,根据键值来决定调用哪个数据库
*/
public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
/**
*根据键找到数据源。数据源的值可以是相应的{@link javax.sql.DataSource}实例或数据源名称字符串(要通过
* {@link #setDataSourceLookup DataSourceLookup}方法解析),键可以是任意类型的; 这个类实现了
*通用键查找数据源,键必须由{@link #resolveSpecifiedLookupKey(Object)}和 {@link #determineCurrentLookupKey() *处理}。
*/
public void setTargetDataSources(Map<Object, Object> targetDataSources) {
this.targetDataSources = targetDataSources;
}
/**
* 确定当前的查找键。这通常会实现以检查线程绑定的事务上下文。
* 允许任意键。返回的键需要与存储的键类型匹配, 用{@link #resolveSpecifiedLookupKey} 方法解决。
*/
protected abstract Object determineCurrentLookupKey();
}
这两个方法比较重要,这个类是abstract类,要创建一个类来继承它并且实现它的determineCurrentLookupKey()方法,通过这个方法进行数据源的切换,如何设置数据源?上面贴出了另外一个核心的方法setTargetDataSources(Map<Object, Object> targetDataSources),它需要一个Map,这个Map存储的就是我们配置的多个数据源的键值对。这个类切换数据源的运作方式就是在连接数据库之前会执行determineCurrentLookupKey()方法,这个方法返回的数据将作为key去targetDataSources中查找相应的值,如果查找到相对应的DataSource,那么就使用此DataSource获取数据库连接。
未完待续