Id分表
@Target({ ElementType.METHOD })
@Retention(RUNTIME)
@Documented
public @interface VoteTenantId {
String value() default "";
}
@Component
@Aspect
public class VoteTenantIdAop {
@Before(value = "@annotation(com.hccake.extend.mybatis.plus.annotation.VoteTenantId)")
public void beforeCheckout(JoinPoint joinPoint) throws NoSuchMethodException {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = joinPoint.getTarget().getClass().getMethod(signature.getName(),
signature.getMethod().getParameterTypes());
VoteTenantId voteTenantId = method.getAnnotation(VoteTenantId.class);
Object[] args = joinPoint.getArgs();
String result = parseExpression(voteTenantId.value(), method, args);
BaseIdDivideTableNameParser.setId(Integer.valueOf(result));
}
private String parseExpression(String expressionString, Method method, Object[] args) {
LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
String[] paramNameArr = discoverer.getParameterNames(method);
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
for (int i = 0; i < Objects.requireNonNull(paramNameArr).length; i++) {
context.setVariable(paramNameArr[i], args[i]);
}
return parser.parseExpression(expressionString).getValue(context, String.class);
}
}
public abstract class BaseIdDivideTableNameParser implements TableNameHandler {
private static final ThreadLocal<Integer> ID = new ThreadLocal<>();
public static void setId(Integer idValue) {
ID.set(idValue);
}
@Override
public String dynamicTableName(String sql, String tableName) {
Integer table = ID.get();
ID.remove();
return tableName + tableName(table);
}
public abstract String tableName(Integer tenantId);
}
@Service
public class DivideTableName extends BaseIdDivideTableNameParser {
@Override
public String tableName(Integer tenantId) {
return DivideRule.customerInfoRule(tenantId);
}
}
@Component
@RequiredArgsConstructor
public class MybatisPlusInterceptorConfig {
private final BaseIdDivideTableNameParser baseIdDivideTableNameParser;
@Bean
@ConditionalOnMissingBean(MybatisPlusInterceptor.class)
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
HashMap<String, TableNameHandler> map = new HashMap<>(8);
map.put("t_message_record", new TimeTableNameParser());
map.put("t_customer_info", baseIdDivideTableNameParser);
dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map);
interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
@Override
@VoteTenantId("{{#customerInfo.tenantId}}")
@Transactional(rollbackFor = Exception.class)
public void insert(CustomerInfo customerInfo) {
baseMapper.insert(customerInfo);
}
时间分表
public class TimeTableNameParser implements TableNameHandler {
@Override
public String dynamicTableName(String sql, String tableName) {
LocalDate date = LocalDate.now();
String table = "_" + date.format(DateTimeFormatter.ofPattern("yyyy_MM"));
return tableName + table;
}
}