分表,通常在数据量大的情况下进行,当然应该先对项目的数据量进行数量级的预估,以根据不同的需求进行采用不同的分表策略。
(shard在mybatis中的配置就不多聊了,直接搜"mybatis分表"会有很多资料,大多类似)
shard原理,相当于一个过滤器,在执行sql语句之前对表名进行处理。
shard_config.xml的配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE shardingConfig PUBLIC "-//shardbatis.googlecode.com//DTD Shardbatis 2.0//EN"
"http://shardbatis.googlecode.com/dtd/shardbatis-config.dtd">
<shardingConfig>
<parseList>
<value>com.hello.IDao.AuthLogMapper.insert</value>
<value>com.hello.IDao.IdcardCacheMapper.insert</value>
</parseList>
<!--配置分表策略-->
<strategy tableName ="auth_log" strategyClass = "com.hello.strategy.ShardStrategyImpl"/>
<strategy tableName ="idcard_cache" strategyClass = "com.hello.strategy.ShardStrategyImpl"/>
</shardingConfig>
以上配置中,auth_log和idcard_cache两个表都采用了ShardStrategyImpl进行分表策略的处理,auth_log采用根据日期进行分表,而idcard_cache采用根据idcard的哈希值分为20个表。像参数中有hashmap之类的可以根据不同的sql进行不同的分表处理。大体思路是:根据表名,参数类别,参数值的不同采用不同的分表策略。
public class ShardStrategyImpl implements ShardStrategy {
private static int idCardTbName = 20;
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
@Override
public String getTargetTableName(String tableName, Object arg1, String arg2) {
if("auth_log".equals(tableName)){
//认证记录分表策略
Class<?> cla = arg1.getClass();
if(cla == HashMap.class){
HashMap<String,Object> hs = (HashMap<String,Object>)arg1;
String date= hs.get("date").toString();
String sTableName = tableName + "_" + date;
return sTableName;
}
String sTableName = tableName + "_" + sdf.format(new Date());
return sTableName;
}else if("idcard_cache".equals(tableName)){
//信息表分表策略
Class<?> cla = arg1.getClass();
if(cla == HashMap.class){
HashMap<String,Object> hs = (HashMap<String,Object>)arg1;
String idCard= hs.get("idCard").toString();
int s = idCard.hashCode();
String sTableName = tableName + "_" + Math.abs(s)%idCardTbName;
System.out.println(sTableName);
return sTableName;
}
if(cla == IdcardCache.class){
IdcardCache ic = (IdcardCache)arg1;
String idCard= ic.getCardNo();
int s = idCard.hashCode();
String sTableName = tableName + "_" + Math.abs(s)%idCardTbName;
System.out.println(sTableName);
return sTableName;
}
return tableName;
}
return tableName;
}
}