mybatis-plus
mybatis-plus copied to clipboard
想要查询自动增加两个查询条件,用多租户插件模式是否满足?
目前看好像多租户只能加一个字段是吗,能否组合,而且我只想开启查询需要加
可以的啊,在spring ioc容器里注册两个TenantLineInnerInterceptor就可以了
查询代码
生成的sql
TenantLineInnerInterceptor
但是我要设置租户的值 是从token里面获取的,如果这样是不是没办法这样做,而且我只是想查询的接口要加条件
租户的值和开关可以通过ThreadLocal【在拦截器注入相关值,开关可以通过注解控制】将值传递给线程上下文来进行判断,之前我是这么实现的
租户的值和开关可以通过ThreadLocal【在拦截器注入相关值,开关可以通过注解控制】将值传递给线程上下文来进行判断,之前我是这么实现的
提供一下代码行不
具体代码是用在公司项目不方便透露 不过可以提供大致的代码 1.关于只在查询的时候需要加字段 可以查看mybatis-plus的源码TenantLineInnerInterceptor类里面有beforeQuery、beforePrepare、processInsert、processUpdate 若只想要查询加可以继承这个TenantLineInnerInterceptor类 processUpdate、processInsert等方法可以空实现
@Service
public class TestInterceptor extends TenantLineInnerInterceptor {
@Autowired
private TenantLineHandlerImpl tenantLineHandler;
@Autowired
private TenantProperties tenantProperties;
public CourtCodesInterceptor(TenantLineHandler tenantLineHandler) {
super(tenantLineHandler);
}
/**
* 不处理连接数据库语句
* @param sh
* @param connection
* @param transactionTimeout
*/
@Override
public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
//empty
}
/**
* 不处理update语句
* @param executor
* @param ms
* @param parameter
* @throws SQLException
*/
@Override
public void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) throws SQLException {
//empty
}
/**
* 在query查询语句触发之前
* @param executor
* @param ms
* @param parameter
* @param rowBounds
* @param resultHandler
* @param boundSql
* @throws SQLException
*/
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
if (InterceptorIgnoreHelper.willIgnoreTenantLine(ms.getId())) return;
if (SqlParserHelper.getSqlParserInfo(ms)) return;
// System.err.println("原sql为:\n" + SQLUtils.formatMySql(boundSql.getSql()));
PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
mpBs.sql(parserSingle(mpBs.sql(), null));
// System.err.println("插件sql为:\n" + SQLUtils.formatMySql(boundSql.getSql()));
}
/**
* 拼接条件
* @param currentExpression
* @param table
* @return
*/
@Override
protected Expression builderExpression(Expression currentExpression, Table table) {
Column aliasColumn = getAliasColumn(table);
Expression expression = tenantLineHandler.getTenantId(aliasColumn);
if (currentExpression == null) {
return expression;
}
if (currentExpression instanceof OrExpression) {
return new AndExpression(new Parenthesis(currentExpression), expression);
} else {
return new AndExpression(currentExpression, expression);
}
}
@Override
protected Column getAliasColumn(Table table) {
StringBuilder column = new StringBuilder();
if (table.getAlias() != null) {
column.append(table.getAlias().getName()).append(StringPool.DOT);
}
column.append(tenantLineHandler.getTenantIdColumn());
return new Column(column.toString());
}
}
2.要设置租户的值 是从token里面获取,可以配置一个拦截器
@Slf4j
public class UserInterceptor extends HandlerInterceptorAdapter {
@Autowired
CommonHeader commonHeader;
@Autowired
UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (response.getStatus() == HttpServletResponse.SC_NOT_FOUND) {
return false;
}
//1,获取名字
String username = request.getHeader("X-Login-User");
// 设置commonHeader
commonHeader.setUsername(username);
if (StringUtils.isEmpty(username)) {
log.error("用户名不能为空,URI:" + request.getRequestURI());
response.setStatus(200);
response.setCharacterEncoding("UTF8");
response.setContentType("application/json;charset=UTF8");
response.getWriter().print(JSONObject.toJSONString(WebApiResponse.error("username为空")));
response.flushBuffer();
response.getWriter().close();
return false;
}
return true;
}
}
//注入相关上下文
@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public CommonHeader getCommonHeader() {
return new CommonHeader();
}
相关租户配置逻辑
@Repository
public class TenantLineHandlerImpl implements TenantLineHandler {
@Autowired
TenantProperties tenantProperties;
@Autowired
CommonHeader commonHeader;
@Override
public Expression getTenantId() {
//请求上下文
String userName = commonHeader.getUserName();
//你可以在此commonHeader获取token相关内容
//相关逻辑
}
/**
* 获取多租户的字段名
*
* @return String
*/
@Override
public String getTenantIdColumn() {
return tenantProperties.getColumn();
}
/**
* 过滤不需要根据租户隔离的表
* 这是 default 方法,默认返回 false 表示所有表都需要拼多租户条件
*可能表名带 ``因此需要去除
* @param tableName 表名
*/
@Override
public boolean ignoreTable(String tableName) {
//根据自己业务来是否需要过滤租户条件,可以根据线程上下文实现
}
}
不过我推荐你自己阅读一下mybatis-plus 租户插件的源码 根据Spring 某些特性 是可以实现你的需求