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; } }