一、业务场景分析
只有大表才需要分表,而且这个大表还会有经常需要读的需要,即使经过sql服务器优化和sql调优,查询也会非常慢。例如共享汽车的定位数据表等。
二、实现步骤
1.准备pom依赖
mysql
mysql-connector-java
5.1.30
com.alibaba
druid
1.1.3
org.springframework
spring-jdbc
4.3.11.RELEASE
org.mybatis
mybatis-spring
1.2.1
org.mybatis
mybatis
3.2.3
这里关键是要额外引入 插件shardbatis 相关的依赖,主要有两个:
org.shardbatis
shardbatis
2.0.0B
net.sf.jsqlparser
jsqlparser
0.7.0
2.准备表
把原来的t_location单表拆分成t_location_01、t_location_02、t_location_03、t_location_04、t_location_05、t_location_06
3.准备好mybatis的mapper interface
public interfaceUserMapper {intdeleteByPrimaryKey(Integer id);intinsert(User record);intinsertSelective(User record);
User selectByPrimaryKey(Integer id);intupdateByPrimaryKeySelective(User record);intupdateByPrimaryKey(User record);
}
对应的sql这里就省略了,shardbatis这个插件使用时也不需要去调整实际的sql,插件达到的效果就是替换掉实际sql中的表名。
4.新增一个shard_config.xml文件
/p>
"http://shardbatis.googlecode.com/dtd/shardbatis-config.dtd">
xxx.xxx
xxx.dao.UserMapper.insertSelective
xxx.dao.UserMapper.selectByPrimaryKey
xxx.UserMapper.updateByPrimaryKeySelective
并在项目的mybatis-config.xml里声明使用这个插件,比如
5.实现分表策略
就是完成上面strategyClass对应的分表策略实现类,其实只需要实现ShardStrategy接口并实现其中的getTargetTableName方法即可,比如:
public class DeviceShardStrategyImpl implementsShardStrategy {private final static int tableCount = 5;/*** 得到实际表名
*@parambaseTableName 逻辑表名,一般是没有前缀或者是后缀的表名
*@paramparams mybatis执行某个statement时使用的参数
*@parammapperId mybatis配置的statement id
*@return
*/@OverridepublicString getTargetTableName(String baseTableName, Object params, String mapperId) {//TODO: 需要根据实际的参数或其他(比如当前时间)计算出一个满足要求的值
int value = 2;try{int index = value % tableCount + 1;
String strIndex= "0" +index;return baseTableName + "_" +strIndex;
}catch(Exception e) {throw newRuntimeException(e.getMessage(), e);
}
}
}
实际中实现需要根据实际的参数或其他(比如当前时间)计算出一个满足要求的值,最后拼接成实际的表名就