第一种:注解拦截
优点: 支持进一步分片
缺点:架构配置繁琐
注解式 / *!mycat:schema = [schemaName] * /
/ *!mycat:schema = USER1 * / select * from order; //模式是逻辑库
可以在每个sql语句前面添加此注解, 指定操作的数据库, Mybatis可以重写MappedStatement的 getBoundSql 来添加。
第二种:枚举分片
优点:schema.xml中中配置相对简洁
缺点: 不可进一步分片
我目前的需求是:按门店分库,按月份分表,需要进行2次划分,因此采用的是第一种方式: 注解拦截 。此外,公司有100多家门店,因此需要100多个库,在进行分表时,按月份分表会产生12个子表,若每个子表在一个库内,即一个店需要12个库,总共需要1200多个库,所以,考虑再三,采用 单库分表 的方式,即拆分的子表在一个库内,数据库数量大大减少。
1)在schema.xml中,配置多个schema logic87,一个逻辑库代表一家门店,与一个实际的数据库相对应。
注意:table标签中datanode节点只能写一个,因为是单库分表 ,subTables中填写的是拆分的12张子表的名字,i_billdel1,.....,i_billdel12,简写i_billdel $ 1-12
2)修改rule.xml
列是用来分表的字段
dataFormat需要注意,若格式为yyyy-MM-dd或yyyy-MM-dd hh:mm:ss,那么所分的表只能存放自sBeginDate开始一年内的数据,只写MM,则对应表内存放相应月份的数据,即每年1月份的数据都存在1月的表内。
3)修改的server.xml的中
在模式中写上的模式,根用户即可操作逻辑库
4)在实际数据库中建好这12张子表
5)连接mycat
mycat的连接端口为8066
连接成功后显示的逻辑库:
6)使用mycat注解
Data_node节点对应实际数据库,这里将将dn3对应的是8M,所以可以通过注解的方式操作逻辑库,mycat会对注解进行解析,找到要查询的数据库。并且可以使用分表字段 指定查询的表。
我们只需在后台根据用户的信息动态绑定要操作的逻辑库即可。
MyBatis的的可以重写MappedStatement的 getBoundSql 来添加 注解 。
我这里是通过拦截器的方式对SQL添加注解(或叫注释)。
在MyBatis的配置文件中加入如下代码:
<插件>
<plugin interceptor =“com.htxx.interceptor.MybatisInterceptor”>
<property name =“name”value =“test”> </ property>
</插件>
</插件>
新建一个拦截器
package com.htxx.interceptor;
import java.lang.reflect.Field; import java.sql.Connection; import java.util.Properties;
import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.reflection.DefaultReflectorFactory; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject;
// obstioned StatementHandler类中参数类型为Statement的准备方法 //即被截止语句准备(连接var1,整数var2)方法@Incecepts( { @ Signature(type = StatementHandler.class,method =“prepare”,args = { Connection .class,Integer.class})}) 公共类MybatisInterceptor实现Interceptor {
@Override public Object intercept(Invocation invocation)抛出Throwable {
StatementHandler statementHandler =(StatementHandler)invocation.getTarget(); //通过MetaObject优雅访问对象的属性,这里是访问语句处理程序的属性;:MetaObject是Mybatis提供的一个用于方便, //优雅访问对象属性的对象,通过它可以简化代码,不需要试试/捕捉各种反映异常,同时它支持对JavaBean,Collection,Map 三种类型对象的操作.MetaObject metaObject = MetaObject.forObject(statementHandler,SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,new DefaultReflectorFactory()); //先拦截到RoutingStatementHandler,里面有个StatementHandler类型的委托变量,其实现类是BaseStatementHandler,然后就到到BaseStatementHandler的成员变量mappedStatement MappedStatement mappedStatement =(MappedStatement)metaObject.getValue(“delegate.mappedStatement”); // id为执行的mapper方法的全路径名,如com.uv.dao.UserMapper.insertUser String id = mappedStatement.getId(); System.out.println(“执行方法的全路径:”+ id); // sql语句类型select,delete,insert,update String sqlCommandType = mappedStatement.getSqlCommandType()。toString(); System.out.println(“执行方法的类型:”+ sqlCommandType); //数据库连接信息 //配置配置= mappedStatement.getConfiguration(); // ComboPooledDataSource dataSource =(ComboPooledDataSource)configuration.getEnvironment()。getDataSource(); // dataSource.getJdbcUrl();
BoundSql boundSql = statementHandler.getBoundSql(); //获取到原始sql语句 String sql = boundSql.getSql();
//获取在mapper接口中定义的方法里的参数 String param = boundSql.getParameterObject()。toString(); //System.out.println(param);
//在这里实现自己的逻辑,可以对SQL进行拼接
SQL =“/ * mycat:schema = main * /”+ SQL;
//这样所有的sql语句都会拼接上/ *!mycat:schema = main * /, 可以判断原始的sql中否包含某写特殊字符来决定是否添加mycat注释 //通过反射修改sql语句 Field field = boundSql ..getClass()getDeclaredField(“SQL”); field.setAccessible(真); field.set(boundSql,SQL);
return invocation.proceed(); }
@Override public Object plugin(Object target){ return Plugin.wrap(target,this); }
@Override public void setProperties(Properties properties){ //此处可以接收到配置文件的属性参数 System.out.println(properties.getProperty(“name”)); }
}
第二种: 枚举分片
schema.xml 配置如下: i_billdel所有库中都有, t_user相当于全局表, 放在默认节点中
rule.xml:
即可实现枚举分片,下面查看路由:
查的所有库, 下面带上分库字段QYBH:
参考:HTTP://www.cnblogs.com/huaxingtianxia/p/7339574.html