当前使用版本(必填,否则不予处理)
3.1.2
现象及背景
- 我想要一个method, 这个method告诉我数据库中是否存在这条记录, 即返回true/false, 而不是去count(*);
- 自定义一个增强型Sql方法
ExistOneMethod后, 发现这个自定义注入无法使用多租户插件;
该问题是如何引起的?(确定最新版也有问题再提!!!)
抱歉, 目前业务非常繁忙; 我先提出, 后续如有时间我再验证最新版本是否也有问题;
重现步骤(如果有就写完整)
- 开启租户插件
TenantHandler - 增加自定义Sql方法
ExistOneMethod, 代码如下
public class ExistOneMethod extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
/* ALERT here:
语法解析器 net.sf.jsqlparser.parser, 仍不支持 SELECT {关键字} 语法;
*/
String existSql = String.format(
"<script>\nSELECT CASE WHEN EXISTS(SELECT 1 FROM %s %s %s) THEN 1 ELSE 0 END\n</script>",
tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo),
sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, existSql, modelClass);
return this.addSelectMappedStatementForOther(mapperClass, "exist", sqlSource, boolean.class);
}
}
报错信息
无报错, 但租户插件失效;
自排查后, 与 net.sf.jsqlparser.parser 语法解析实现有关.
它解析到 SELECT EXIST(子查询) 语法后, 把它解析成了 PlainSelect, 导致fromItem=null,
而formItem=null, 则导致了TenantHandler失效问题;
但实际上子查询中是有表的.
Comment From: lite-up
补充:
SELECT EXIST( ... )语法直接过不了parser那关;
所以改成了 SELECT CASE WHEN EXIST( ... )
Comment From: miemieYaho
你写个default方法里面 count > 0 不好吗?
Comment From: lite-up
你写个default方法里面 count > 0 不好吗?
可以是可以, 但MySQL的count会全量计数, 而exists则是遇到一个则马上停止, 所以实际上也是个性能问题吧.