MybatisPlus分表

MybatisPlus分表

Id分表

  • 注解
@Target({ ElementType.METHOD })
@Retention(RUNTIME)
@Documented
public @interface VoteTenantId {

	/**
	 * 拦截方法之上,EL表达式
	 * @return EL表达式
	 */
	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);
		// SPEL解析
		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();
		// 这里清除ThreadLocal的值,防止线程复用出现问题
		ID.remove();

		return tableName + tableName(table);
	}

	/**
	 * 划分分表规则,由子类实现
	 * @param tenantId tenantId
	 * @return tableName
	 */
	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;

	/**
	 * MybatisPlusInterceptor 插件,默认提供分页插件</br>
	 * 如需其他MP内置插件,则需自定义该Bean
	 * @return MybatisPlusInterceptor
	 */
	@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;
	}

}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值