Просмотр исходного кода

fix 分表bug

release_toaliyun_real
xiaohanzi 5 лет назад
Родитель
Сommit
f89338896c
5 измененных файлов: 111 добавлений и 53 удалений
  1. +1
    -0
      mallinkService/src/main/java/com/iformall/service/impl/WxCUserServiceImpl.java
  2. +13
    -2
      mybatis-multi-tenancy/src/main/java/com/iformall/plugin/MyBatisItercepters.java
  3. +8
    -1
      mybatis-multi-tenancy/src/main/java/com/iformall/plugin/MyBatisPlus.java
  4. +9
    -1
      mybatis-multi-tenancy/src/main/java/com/iformall/plugin/autoTenantId/MultiTenancy.java
  5. +80
    -49
      mybatis-multi-tenancy/src/main/java/com/iformall/plugin/shard/plugin/ShardingSpherePlugin.java

+ 1
- 0
mallinkService/src/main/java/com/iformall/service/impl/WxCUserServiceImpl.java Просмотреть файл

@@ -89,6 +89,7 @@ public class WxCUserServiceImpl implements WxCUserService {
user.setId(oldUser.getId());
user.setLoginCount(oldUser.getLoginCount()==null?0:oldUser.getLoginCount() + 1);
user.setUpdateDate(curr);
user.updateTenantInfo(oldUser);
// TODO 是否其他信息需要更新
ret = wxCUserMapper.updateById(user);
return ret;


+ 13
- 2
mybatis-multi-tenancy/src/main/java/com/iformall/plugin/MyBatisItercepters.java Просмотреть файл

@@ -4,7 +4,9 @@ import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import java.sql.Connection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*共享数据库的多租户系统实现
* Created by Stormeye on 2018/10/22.
@@ -29,12 +31,21 @@ public class MyBatisItercepters implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
if (null != plugins && plugins.size() > 0 ) {
// 能从cookie或者session获取到tenantId
for (MyBatisPlus plug: plugins) {
plug.intercept(invocation);
Map<String,Object> chainMap = new HashMap<String,Object>();
for (int i = 0 ; i < plugins.size() ; i++) {
MyBatisPlus plug = plugins.get(i);
invokeIntercept(plug, invocation, chainMap);
}
}
return invocation.proceed();
}
private void invokeIntercept(MyBatisPlus plug,Invocation invocation,Map<String,Object> chainMap) throws Throwable {
Map<String,Object> resultMap = plug.intercept(invocation, chainMap);
if (null != resultMap) {
chainMap.putAll(resultMap);
}
}

/**
* 生成代理对象


+ 8
- 1
mybatis-multi-tenancy/src/main/java/com/iformall/plugin/MyBatisPlus.java Просмотреть файл

@@ -1,8 +1,15 @@
package com.iformall.plugin;

import java.util.Map;

import org.apache.ibatis.plugin.Invocation;

public interface MyBatisPlus {

public void intercept(Invocation invocation) throws Throwable;
/**
* @param invocation
* @return Map<coloumn,value>
* @throws Throwable
*/
public Map<String,Object> intercept(Invocation invocation,Map<String,Object> parentChainMap) throws Throwable;
}

+ 9
- 1
mybatis-multi-tenancy/src/main/java/com/iformall/plugin/autoTenantId/MultiTenancy.java Просмотреть файл

@@ -36,7 +36,9 @@ import com.iformall.plugin.MyBatisPlus;

import java.sql.Connection;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
@@ -87,11 +89,17 @@ public class MultiTenancy implements MyBatisPlus {
public MultiTenancy(){
}

public void intercept(Invocation invocation) throws Throwable {
@Override
public Map<String,Object> intercept(Invocation invocation,Map<String,Object> parentChainMap) throws Throwable {
if (getTenantInfo().getTenantId() != null || getTenantInfo().getParentTenantId() != null) {
// 能从cookie或者session获取到tenantId
mod(invocation);
Map<String,Object> resultMap = new HashMap<String,Object>();
resultMap.put(tenantIdColumn, getTenantInfo().getTenantId());
resultMap.put(parentTenantIdColumn, getTenantInfo().getParentTenantId());
return resultMap;
}
return null;
}

/**


+ 80
- 49
mybatis-multi-tenancy/src/main/java/com/iformall/plugin/shard/plugin/ShardingSpherePlugin.java Просмотреть файл

@@ -74,9 +74,9 @@ public class ShardingSpherePlugin implements MyBatisPlus {
}
}
public void intercept(Invocation invocation) throws Throwable {
public Map<String,Object> intercept(Invocation invocation,Map<String,Object> parentChainMap) throws Throwable {
if (!ShardingTableExcuter.hasShardingConfig()) {
return ;
return parentChainMap;
}
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
@@ -92,29 +92,31 @@ public class ShardingSpherePlugin implements MyBatisPlus {
// if (null == ignore) {
Object parameterObject = metaStatementHandler.getValue("delegate.boundSql.parameterObject");
BoundSql boundSql = statementHandler.getBoundSql();
String newSQL = buildTable(boundSql,parameterObject);
String newSQL = buildTable(boundSql,parameterObject,parentChainMap);
metaStatementHandler.setValue("delegate.boundSql.sql", newSQL);
// }
//}
//没有添加字段,只是根据字段分表,没有别的需要返回
return parentChainMap;
}

private String buildTable(BoundSql boundSql,Object parameterObject) throws JSQLParserException {
private String buildTable(BoundSql boundSql,Object parameterObject,Map<String,Object> parentChainMap) throws JSQLParserException {
String oldSql = boundSql.getSql();
Statement stmt = CCJSqlParserUtil.parse(oldSql);
if (stmt instanceof Insert) {
return buildInsert((Insert) stmt,oldSql,parameterObject);
return buildInsert((Insert) stmt,oldSql,parameterObject,parentChainMap);
}

if (stmt instanceof Delete) {
return buildDelete((Delete) stmt,oldSql,parameterObject);
return buildDelete((Delete) stmt,oldSql,parameterObject,parentChainMap);
}

if (stmt instanceof Update) {
return buildUpdate((Update) stmt,oldSql,parameterObject);
return buildUpdate((Update) stmt,oldSql,parameterObject,parentChainMap);
}

if (stmt instanceof Select) {
return buildSelect((Select) stmt,oldSql,parameterObject);
return buildSelect((Select) stmt,oldSql,parameterObject,parentChainMap);
}

if (stmt instanceof CreateTable) {
@@ -123,86 +125,115 @@ public class ShardingSpherePlugin implements MyBatisPlus {
throw new RuntimeException("非法sql语句,请检查"+oldSql);
}
private String buildInsert(Insert stmt,String oldSql,Object parameterObject) {
return buildTable(stmt.getTable(), oldSql, parameterObject);
private String buildInsert(Insert stmt,String oldSql,Object parameterObject,Map<String,Object> parentChainMap) {
return buildTable(stmt.getTable(), oldSql, parameterObject,parentChainMap);
}
private String buildDelete(Delete stmt,String oldSql,Object parameterObject) {
return buildTable(stmt.getTable(), oldSql, parameterObject);
private String buildDelete(Delete stmt,String oldSql,Object parameterObject,Map<String,Object> parentChainMap) {
return buildTable(stmt.getTable(), oldSql, parameterObject,parentChainMap);
}
private String buildUpdate(Update stmt,String oldSql,Object parameterObject) {
return buildListTables(stmt.getTables(), oldSql, parameterObject);
private String buildUpdate(Update stmt,String oldSql,Object parameterObject,Map<String,Object> parentChainMap) {
return buildListTables(stmt.getTables(), oldSql, parameterObject,parentChainMap);
}
private String buildSelect(Select stmt,String oldSql,Object parameterObject) {
private String buildSelect(Select stmt,String oldSql,Object parameterObject,Map<String,Object> parentChainMap) {
TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
List<String> tableList = tablesNamesFinder.getTableList(stmt);
return buildByListTableNames(tableList, oldSql, parameterObject);
return buildByListTableNames(tableList, oldSql, parameterObject,parentChainMap);
}
private String buildTable(Table table,String oldSql,Object parameterObject) {
return buildByTableName(table.getName(), oldSql, parameterObject);
private String buildTable(Table table,String oldSql,Object parameterObject,Map<String,Object> parentChainMap) {
return buildByTableName(table.getName(), oldSql, parameterObject,parentChainMap);
}
private String buildByTableName(String table,String oldSql,Object parameterObject) {
private String buildByTableName(String table,String oldSql,Object parameterObject,Map<String,Object> parentChainMap) {
if (!ShardingTableExcuter.isShardingTable(table)) {
return oldSql;
}
String newtable = getShareTable(table,parameterObject);
String newtable = getShareTable(table,parameterObject,parentChainMap);
//此处处理前缀相似的表,如wx_c_user, wx_c_user_basic_info, 直接替换wx_c_user会有问题
return oldSql.replaceAll(table+"_", "########").replaceAll(table, newtable).replaceAll("########", table+"_");
}
private String buildListTables(List<Table> tables,String oldSql,Object parameterObject) {
private String buildListTables(List<Table> tables,String oldSql,Object parameterObject,Map<String,Object> parentChainMap) {
for (Table t : tables) {
oldSql = buildTable(t,oldSql,parameterObject);
oldSql = buildTable(t,oldSql,parameterObject,parentChainMap);
}
return oldSql;
}
private String buildByListTableNames(List<String> tables,String oldSql,Object parameterObject) {
private String buildByListTableNames(List<String> tables,String oldSql,Object parameterObject,Map<String,Object> parentChainMap) {
for (String t : tables) {
oldSql = buildByTableName(t,oldSql,parameterObject);
oldSql = buildByTableName(t,oldSql,parameterObject,parentChainMap);
}
return oldSql;
}
private String getShareTable(String table,Object parameterObject) {
private String getShareTable(String table,Object parameterObject,Map<String,Object> parentChainMap) {
ShardingSphere ss = ShardingTableExcuter.getShardingSphere(table);
return ss.getTableName()+ShardingSphere.TABLE_SUFFIX+ShardingRuleExcuter.getTableIndex(ss.getRule(), getValue(ss.getColumn(),parameterObject), ss.getCount());
return ss.getTableName()+ShardingSphere.TABLE_SUFFIX+ShardingRuleExcuter.getTableIndex(ss.getRule(), getValue(ss.getColumn(),parameterObject,parentChainMap), ss.getCount());
}
private Object getValue(String column,Object parameterObject) {
private Object getValue(String column,Object parameterObject,Map<String,Object> parentChainMap) {
if (null != parentChainMap && parentChainMap.containsKey(column)) {
return parentChainMap.get(column);
}
if (parameterObject instanceof Map) {
return ((Map) parameterObject).get(column);
}else if (parameterObject instanceof Integer || parameterObject instanceof Long || parameterObject instanceof Short || parameterObject instanceof Float
|| parameterObject instanceof Double || parameterObject instanceof BigDecimal || parameterObject instanceof Character || parameterObject instanceof String
|| parameterObject instanceof Byte || parameterObject instanceof Date || parameterObject instanceof Time || parameterObject instanceof Timestamp) {
String field = getField(column);
field = field.substring(0,1).toLowerCase()+field.substring(1);
Object o = parameterObject;
if (((Map) parameterObject).containsKey("et")) {
o = ((Map) parameterObject).get("et");
}else if(((Map) parameterObject).containsKey(column)) {
o = ((Map) parameterObject).get(column);
}else if (((Map) parameterObject).containsKey(field)) {
o = ((Map) parameterObject).get(column);
}
return getValue(column,o,parentChainMap);
}else if (isBasicTypeValue(parameterObject)) {
return parameterObject;
//认为是实体
}else {
try {
String[] field = column.split("_");
String fieldName = "";
if (null != field && field.length > 0) {
for (String f : field) {
fieldName = fieldName + f.substring(0,1).toUpperCase()+f.substring(1);
}
}else {
fieldName = column.substring(0,1).toUpperCase()+column.substring(1);
}
Method method = getMethodFromAllParent(parameterObject.getClass(),"get"+fieldName);
Object o = method.invoke(parameterObject);
return o;
}catch(Exception e) {
e.printStackTrace();
return parameterObject;
}
return getEntityValue(column, parameterObject, parentChainMap);
}
}
private String getField(String column) {
String[] field = column.split("_");
String fieldName = "";
if (null != field && field.length > 0) {
for (String f : field) {
fieldName = fieldName + f.substring(0,1).toUpperCase()+f.substring(1);
}
}else {
fieldName = column.substring(0,1).toUpperCase()+column.substring(1);
}
return fieldName;
}
private boolean isBasicTypeValue(Object parameterObject) {
if( parameterObject instanceof Integer || parameterObject instanceof Long || parameterObject instanceof Short || parameterObject instanceof Float
|| parameterObject instanceof Double || parameterObject instanceof BigDecimal || parameterObject instanceof Character || parameterObject instanceof String
|| parameterObject instanceof Byte || parameterObject instanceof Date || parameterObject instanceof Time || parameterObject instanceof Timestamp ) {
return true;
}
return false;
}
private Object getEntityValue(String column,Object parameterObject,Map<String,Object> parentChainMap) {
try {
Method method = getMethodFromAllParent(parameterObject.getClass(),"get"+getField(column));
Object o = method.invoke(parameterObject);
return o;
}catch(Exception e) {
e.printStackTrace();
return parameterObject;
}
}
private Method getMethodFromAllParent(Class<?> currentClazz,String methodName) {
Method method = null;
for(Class<?> clazz = currentClazz ; clazz != Object.class ; clazz = clazz.getSuperclass()) {


Загрузка…
Отмена
Сохранить