springBoot中使用mybatis拦截器添加数据库前缀
SpringBoot中使用mybatis拦截器
·
背景:
- 项目中需要根据企业分对应的数据库,所以要动态根据企业的标识去操作对应的数据库
思路:
- 用
mybatis plus
动态表名,但是有个缺点就是只会在项目启动是注入bean对象时调用一次,不像拦截器那样每次调用,所以放弃了;(其实简单的根据日期什么的切换数据表,直接用mp的这种实现更加简单)
- 使用
mybatis
的拦截器
Example:
package com.huawen.framework.interceptor;
import cn.hutool.core.util.ObjectUtil;
import com.huawen.common.enums.CompanyEnum;
import com.huawen.common.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.*;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.Properties;
/**
* @author:kyrie
* @date:2022/12/7 9:48
* @Description: 添加数据库前缀 拦截器
**/
@Slf4j
// 注入到spring中托管
@Component
// @Intercepts表示是拦截器
// @Signature声明要拦截的接口、方法以及对应的参数列表
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class AddDbPrefixInterceptor implements Interceptor {
/**
* 拦截方法
*
* @param invocation 调用
* @return obj
* @throws Throwable 异常
*/
@Override
public Object intercept(Invocation invocation) throws Throwable {
log.info("执行intercept方法:{}", invocation.toString());
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
// BoundSql对象
BoundSql boundSql = statementHandler.getBoundSql();
// 原始sql
String origSql = boundSql.getSql();
log.info("原始SQL: {}", origSql);
// 在表名之前添加数据库库前缀 [这里做自己的业务就行]
String newSql = addDbPrefixBeforeTableName(origSql);
log.info("修改后SQL: {}", newSql);
// 使用反射获取属性
Field field = boundSql.getClass().getDeclaredField("sql");
field.setAccessible(true);
// 设置新的属性
field.set(boundSql, newSql);
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
/**
* 在表名之前添加数据库库前缀 [处理自己的业务 我这是把sql直接replace]
*
* @param sql 原始的sql
* @return 添加了之后的sql
*/
private String addDbPrefixBeforeTableName(String sql) {
try {
// todo
} catch (Exception e) {
// ignore
}
return sql;
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)