shardbait2.0实现分表的功能可以用一句话描述:使用mybatis3的插件机制在执行sql之前对原始sql的里的表名进行修改。
优点:原有Service、 dao、 *.xml 基本不需要更改。
需要注意:*.xml 不支持modTime=current timestamp 需要更改为modTime=current_timestamp
一:引入jar包
shardbatis-2.0.0B.jar
jsqlparser-0.8.0.jar
私服坐标如下:
<dependency>
<groupId>shardbatis</groupId>
<artifactId>shardbatis</artifactId>
<version>2.0.0B</version>
</dependency>
<dependency>
<groupId>net.sf.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.8.0</version>
</dependency>
二、配置:
1.在mybatis配置文件Configuration.xml中添加插件配置
<plugins>
<plugin interceptor="com.google.code.shardbatis.plugin.ShardPlugin">
<property name="shardingConfig" value="shard_config.xml"/>
</plugin>
</plugins>
2.添加sharding配置
新建一个xml文件,例如:shard_config.xml 。shard_config.xml必须保存在应用的classpath中
<?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>
<!--
ignoreList可选配置
ignoreList配置的mapperId会被分表参加忽略解析,不会对sql进行修改
-->
<!--
<ignoreList>
<value>com.google.code.shardbatis.test.mapper.AppTestMapper.insertNoShard</value>
</ignoreList>
-->
<!--
parseList可选配置
如果配置了parseList,只有在parseList范围内并且不再ignoreList内的sql才会被解析和修改
-->
<parseList>
<value>Order.getTrans</value>
<value>Order.findTrans</value>
<value>Order.getTransByTrace</value>
<value>Order.Get</value>
<value>Order.getOrder</value>
<value>Order.Find</value>
<value>Order.Find_count</value>
<value>Order.Insert</value>
<value>Order.Update</value>
<value>Order.Delete</value>
<value>Order.payResultOrderUpdate</value>
<value>Trans.Get</value>
<value>Trans.Find</value>
<value>Trans.Find_count</value>
<value>Trans.Insert</value>
<value>Trans.Update</value>
<value>Trans.Delete</value>
<value>Trans.payResultTransUpdate</value>
</parseList>
<!--
配置分表策略
-->
<strategy tableName="T_ORDER" strategyClass="com.umpay.pbmp.service.impl.ShardStrategybImpl"/>
<strategy tableName="T_TRANS" strategyClass="com.umpay.pbmp.service.impl.ShardStrategybImpl"/>
</shardingConfig>
三、实现自己的sharding策略
实现ShardStrategy接口即可 实现自己的sharding策略
package com.umpay.pbmp.service.impl;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import com.google.code.shardbatis.strategy.ShardStrategy;
import com.umpay.pbmp.common.PlatLogger;
import com.umpay.pbmp.po.Order;
import com.umpay.pbmp.po.Trans;
public class ShardStrategybImpl implements ShardStrategy {
//params为map,statement按照orderDate分表(2,6)
public static final Map<String,String> paramsMap = new LinkedHashMap<String, String>();
static{
paramsMap.put("Order.getOrder","");//暂时未用到
paramsMap.put("Order.getTrans","");//暂时未用到
paramsMap.put("Order.findTrans","");
}
//params为Trans,statement按照trace分表(0,4)
public static final Map<String,String> paramsTrans = new LinkedHashMap<String, String>();
static{
paramsTrans.put("Trans.Find","");//暂时未用到
paramsTrans.put("Trans.Find_count","");//暂时未用到
paramsTrans.put("Trans.Insert","");
paramsTrans.put("Trans.Update","");
paramsTrans.put("Trans.Delete","");//暂时未用到
paramsTrans.put("Trans.payResultTransUpdate","");
}
//params为Order,statement按照tradeno分表(0,4)
public static final Map<String,String> paramsOrder = new LinkedHashMap<String, String>();
static{
paramsOrder.put("Order.Find","");//暂时未用到
paramsOrder.put("Order.Find_count","");//暂时未用到
paramsOrder.put("Order.Insert","");
paramsOrder.put("Order.Update","");
paramsOrder.put("Order.Delete","");//暂时未用到
paramsOrder.put("Order.payResultOrderUpdate","");
}
//params为String,主键(0,4)
public static final Map<String,String> paramsString = new LinkedHashMap<String, String>();
static{
paramsString.put("Trans.Get","");//暂时未用到
paramsString.put("Order.Get","");
paramsString.put("Order.getTransByTrace","");
}
/**
* 得到实际表名
*
* @param baseTableName 逻辑表名,一般是没有前缀或者是后缀的表名
* @param params mybatis执行某个statement时使用的参数
* @param mapperId mybatis配置的statement id
* @return
*/
public String getTargetTableName(String baseTableName, Object params, String mapperId) {
PlatLogger.getLogger(getClass()).info("baseTableName: "+ baseTableName);
PlatLogger.getLogger(getClass()).info("params: "+ params);
PlatLogger.getLogger(getClass()).info("mapperId: "+ mapperId);
String k = "";
if (params != null) {
if(paramsMap.containsKey(mapperId)){
HashMap<String,String> map = (HashMap<String,String>) params;
String orderDate = map.get("orderDate");
k = orderDate.substring(2, 6);
}else if(paramsTrans.containsKey(mapperId)){
Trans trans = (Trans) params;
String trace = trans.getTrace();
k = trace.substring(0, 4);
}else if(paramsOrder.containsKey(mapperId)){
Order order = (Order) params;
String tradeNo = order.getTradeNo();
k = tradeNo.substring(0, 4);
}else if(paramsString.containsKey(mapperId)){
String primaryKey = (String) params;
k = primaryKey.substring(0, 4);
}
}
PlatLogger.getLogger(getClass()).info("TableName"+ baseTableName + "_" + k);
return baseTableName + "_" + k;
}
}