wrapper) {
+ wrapper.selectAsClass(this.currentModelClass(), this.currentVoClass());
+ return this.selectJoinList(this.currentVoClass(), wrapper);
+ }
+
+ /**
+ * 根据条件分页查询VO对象列表(MPJ版本可减少非VO字段查询)
+ *
+ * @param page 分页信息
+ * @param wrapper MPJ查询条件Wrapper
+ * @return 查询到的VO对象分页列表
+ * @author LukewarmMe
+ */
+ default > P selectVoPage(P page, MPJLambdaWrapper wrapper) {
+ wrapper.selectAsClass(this.currentModelClass(), this.currentVoClass());
+ return this.selectJoinPage(page, this.currentVoClass(), wrapper);
+ }
+
}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataBaseHelper.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataBaseHelper.java
index 1a923a30a..452bb87e3 100644
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataBaseHelper.java
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataBaseHelper.java
@@ -2,6 +2,9 @@ package org.dromara.common.mybatis.helper;
import cn.hutool.core.convert.Convert;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
+import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
+import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.dromara.common.core.exception.ServiceException;
@@ -81,4 +84,84 @@ public class DataBaseHelper {
public static List getDataSourceNameList() {
return new ArrayList<>(DS.getDataSources().keySet());
}
+
+
+ /**
+ * 获取findInSet所需的sql片段(使用MPJ的applyFunc来实现)
+ * @author LukewarmMe
+ */
+ public static String findInSet() {
+ return switch (getDataBaseType()) {
+ case ORACLE -> "instr(','||%s||',', ',{0},') <> 0";
+ case POSTGRE_SQL -> "strpos(','||%s||',', ',{0},') <> 0";
+ case SQL_SERVER -> "charindex(',{0},', ','+%s+',') <> 0";
+ default -> "find_in_set({0}, %s) > 0";
+ };
+ }
+
+ /**
+ * 构建不同数据库的JSON等值查询SQL模板(使用MPJ的applyFunc来实现)
+ * @author LukewarmMe
+ */
+ public static String buildJsonEqSql(SFunction jsonProperty) {
+ String jsonPath = lambdaToJsonPath(jsonProperty);
+ return switch (DataBaseHelper.getDataBaseType()) {
+ case ORACLE -> "json_value(%s, '$" + jsonPath + "') = {0}";
+ case POSTGRE_SQL -> "%s->>'" + jsonPath.replaceFirst("\\.", "") + "' = {0}";
+ case SQL_SERVER -> "JSON_VALUE(%s, '$" + jsonPath + "') = {0}";
+ default -> "%s->>'$" + jsonPath + "' = {0}";
+ };
+ }
+
+ /**
+ * 构建不同数据库的JSON模糊查询SQL模板(使用MPJ的applyFunc来实现)
+ * @author LukewarmMe
+ */
+ public static String buildJsonLikeSql(SFunction jsonProperty) {
+ String jsonPath = lambdaToJsonPath(jsonProperty);
+ return switch (DataBaseHelper.getDataBaseType()) {
+ case ORACLE -> "json_value(%s, '$" + jsonPath + "') LIKE {0}";
+ case POSTGRE_SQL -> "%s->>'" + jsonPath.replaceFirst("\\.", "") + "' LIKE {0}";
+ case SQL_SERVER -> "JSON_VALUE(%s, '$" + jsonPath + "') LIKE {0}";
+ default -> "%s->>'$" + jsonPath + "' LIKE {0}";
+ };
+ }
+
+ /**
+ * 构建不同数据库的JSON非空判断SQL模板(使用MPJ的applyFunc来实现)
+ * @author LukewarmMe
+ */
+ public static String buildJsonIsNotNullSql(SFunction jsonProperty) {
+ String jsonPath = lambdaToJsonPath(jsonProperty);
+ return switch (DataBaseHelper.getDataBaseType()) {
+ case ORACLE -> "json_value(%s, '$" + jsonPath + "') IS NOT NULL";
+ case POSTGRE_SQL -> "%s->>'" + jsonPath.replaceFirst("\\.", "") + "' IS NOT NULL";
+ case SQL_SERVER -> "JSON_VALUE(%s, '$" + jsonPath + "') IS NOT NULL";
+ default -> "%s->>'$" + jsonPath + "' IS NOT NULL";
+ };
+ }
+
+ /**
+ * 核心:Lambda 解析为 JSON 路径(复用原有逻辑,增加空值校验)
+ * 示例:SysUser中UserExtInfo::getWorkNumber → .workNumber
+ * @author LukewarmMe
+ */
+ public static String lambdaToJsonPath(SFunction jsonProperty) {
+ LambdaMeta lambdaMeta = LambdaUtils.extract(jsonProperty);
+ String methodName = lambdaMeta.getImplMethodName();
+ String propertyName;
+ if (methodName.startsWith("get")) {
+ propertyName = methodName.substring(3);
+ } else if (methodName.startsWith("is")) {
+ propertyName = methodName.substring(2);
+ } else if (methodName.startsWith("set")) {
+ propertyName = methodName.substring(3);
+ } else {
+ throw new ServiceException("不支持的Lambda方法类型,仅支持get/is/set开头:" + methodName);
+ }
+ if (!propertyName.isEmpty()) {
+ propertyName = Character.toLowerCase(propertyName.charAt(0)) + propertyName.substring(1);
+ }
+ return "." + propertyName;
+ }
}