|
|
|
@@ -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()) { |
|
|
|
|