diff --git a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/QueryController.java b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/QueryController.java
index 4b6867f..87572aa 100644
--- a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/QueryController.java
+++ b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/QueryController.java
@@ -1,5 +1,8 @@
package com.lanyuanxiaoyao.service.template.common.controller;
+import com.lanyuanxiaoyao.service.template.common.entity.GlobalResponse;
+import com.lanyuanxiaoyao.service.template.common.entity.Query;
+
/**
* 查询控制器接口,用于定义统一的查询实体详情和列表的接口规范
*
diff --git a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/RemoveController.java b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/RemoveController.java
index 93a43a8..34ebe04 100644
--- a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/RemoveController.java
+++ b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/RemoveController.java
@@ -1,5 +1,7 @@
package com.lanyuanxiaoyao.service.template.common.controller;
+import com.lanyuanxiaoyao.service.template.common.entity.GlobalResponse;
+
/**
* 删除控制器接口,用于定义统一的删除实体对象的接口规范
*
diff --git a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/SaveController.java b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/SaveController.java
index 18130e4..c14f421 100644
--- a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/SaveController.java
+++ b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/SaveController.java
@@ -1,5 +1,7 @@
package com.lanyuanxiaoyao.service.template.common.controller;
+import com.lanyuanxiaoyao.service.template.common.entity.GlobalResponse;
+
/**
* 保存控制器接口,用于定义统一的保存实体对象的接口规范
*
diff --git a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/GlobalResponse.java b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/entity/GlobalResponse.java
similarity index 99%
rename from spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/GlobalResponse.java
rename to spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/entity/GlobalResponse.java
index c61f768..7685580 100644
--- a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/GlobalResponse.java
+++ b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/entity/GlobalResponse.java
@@ -1,4 +1,4 @@
-package com.lanyuanxiaoyao.service.template.common.controller;
+package com.lanyuanxiaoyao.service.template.common.entity;
import java.util.List;
import java.util.Map;
diff --git a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/service/Page.java b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/entity/Page.java
similarity index 93%
rename from spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/service/Page.java
rename to spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/entity/Page.java
index d624929..3026cb9 100644
--- a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/service/Page.java
+++ b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/entity/Page.java
@@ -1,4 +1,4 @@
-package com.lanyuanxiaoyao.service.template.common.service;
+package com.lanyuanxiaoyao.service.template.common.entity;
import java.util.stream.Stream;
diff --git a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/Query.java b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/entity/Query.java
similarity index 99%
rename from spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/Query.java
rename to spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/entity/Query.java
index c395358..1fd00dd 100644
--- a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/controller/Query.java
+++ b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/entity/Query.java
@@ -1,4 +1,4 @@
-package com.lanyuanxiaoyao.service.template.common.controller;
+package com.lanyuanxiaoyao.service.template.common.entity;
import java.util.List;
import java.util.Map;
diff --git a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/service/QueryParser.java b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/service/QueryParser.java
new file mode 100644
index 0000000..e688edb
--- /dev/null
+++ b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/service/QueryParser.java
@@ -0,0 +1,125 @@
+package com.lanyuanxiaoyao.service.template.common.service;
+
+import com.lanyuanxiaoyao.service.template.common.entity.Query;
+import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper;
+
+public abstract class QueryParser {
+ protected abstract void nullEqual(Query.Queryable queryable);
+
+ protected abstract void notNullEqual(Query.Queryable queryable);
+
+ protected abstract void empty(Query.Queryable queryable);
+
+ protected abstract void notEmpty(Query.Queryable queryable);
+
+ protected abstract void equal(Query.Queryable queryable);
+
+ protected abstract void notEqual(Query.Queryable queryable);
+
+ protected abstract void like(Query.Queryable queryable);
+
+ protected abstract void notLike(Query.Queryable queryable);
+
+ protected abstract void contain(Query.Queryable queryable);
+
+ protected abstract void notContain(Query.Queryable queryable);
+
+ protected abstract void startWith(Query.Queryable queryable);
+
+ protected abstract void notStartWith(Query.Queryable queryable);
+
+ protected abstract void endWith(Query.Queryable queryable);
+
+ protected abstract void notEndWith(Query.Queryable queryable);
+
+ protected abstract void great(Query.Queryable queryable);
+
+ protected abstract void less(Query.Queryable queryable);
+
+ protected abstract void greatEqual(Query.Queryable queryable);
+
+ protected abstract void lessEqual(Query.Queryable queryable);
+
+ protected abstract void inside(Query.Queryable queryable);
+
+ protected abstract void notInside(Query.Queryable queryable);
+
+ protected abstract void between(Query.Queryable queryable);
+
+ protected abstract void notBetween(Query.Queryable queryable);
+
+ protected abstract O build();
+
+ public O build(Query.Queryable queryable) {
+ if (ObjectHelper.isNull(queryable)) {
+ return null;
+ }
+ if (ObjectHelper.isNotEmpty(queryable.nullEqual())) {
+ nullEqual(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.notNullEqual())) {
+ notNullEqual(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.empty())) {
+ empty(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.notEmpty())) {
+ notEmpty(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.equal())) {
+ equal(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.notEqual())) {
+ notEqual(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.like())) {
+ like(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.notLike())) {
+ notLike(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.contain())) {
+ contain(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.notContain())) {
+ notContain(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.startWith())) {
+ startWith(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.notStartWith())) {
+ notStartWith(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.endWith())) {
+ endWith(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.notEndWith())) {
+ notEndWith(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.great())) {
+ great(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.less())) {
+ less(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.greatEqual())) {
+ greatEqual(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.lessEqual())) {
+ lessEqual(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.inside())) {
+ inside(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.notInside())) {
+ notInside(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.between())) {
+ between(queryable);
+ }
+ if (ObjectHelper.isNotEmpty(queryable.notBetween())) {
+ notBetween(queryable);
+ }
+ return build();
+ }
+}
diff --git a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/service/QueryService.java b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/service/QueryService.java
index efda3d4..a2bec1d 100644
--- a/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/service/QueryService.java
+++ b/spring-boot-service-template-common/src/main/java/com/lanyuanxiaoyao/service/template/common/service/QueryService.java
@@ -1,6 +1,7 @@
package com.lanyuanxiaoyao.service.template.common.service;
-import com.lanyuanxiaoyao.service.template.common.controller.Query;
+import com.lanyuanxiaoyao.service.template.common.entity.Page;
+import com.lanyuanxiaoyao.service.template.common.entity.Query;
import java.util.List;
import java.util.Set;
diff --git a/spring-boot-service-template-jpa/src/main/java/com/lanyuanxiaoyao/service/template/jpa/controller/SimpleControllerSupport.java b/spring-boot-service-template-jpa/src/main/java/com/lanyuanxiaoyao/service/template/jpa/controller/SimpleControllerSupport.java
index 88e45c5..a790481 100644
--- a/spring-boot-service-template-jpa/src/main/java/com/lanyuanxiaoyao/service/template/jpa/controller/SimpleControllerSupport.java
+++ b/spring-boot-service-template-jpa/src/main/java/com/lanyuanxiaoyao/service/template/jpa/controller/SimpleControllerSupport.java
@@ -1,8 +1,8 @@
package com.lanyuanxiaoyao.service.template.jpa.controller;
-import com.lanyuanxiaoyao.service.template.common.controller.GlobalResponse;
-import com.lanyuanxiaoyao.service.template.common.controller.Query;
import com.lanyuanxiaoyao.service.template.common.controller.SimpleController;
+import com.lanyuanxiaoyao.service.template.common.entity.GlobalResponse;
+import com.lanyuanxiaoyao.service.template.common.entity.Query;
import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper;
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
import com.lanyuanxiaoyao.service.template.jpa.service.SimpleServiceSupport;
diff --git a/spring-boot-service-template-jpa/src/main/java/com/lanyuanxiaoyao/service/template/jpa/service/SimpleServiceSupport.java b/spring-boot-service-template-jpa/src/main/java/com/lanyuanxiaoyao/service/template/jpa/service/SimpleServiceSupport.java
index 1c1a71c..bec8969 100644
--- a/spring-boot-service-template-jpa/src/main/java/com/lanyuanxiaoyao/service/template/jpa/service/SimpleServiceSupport.java
+++ b/spring-boot-service-template-jpa/src/main/java/com/lanyuanxiaoyao/service/template/jpa/service/SimpleServiceSupport.java
@@ -1,12 +1,13 @@
package com.lanyuanxiaoyao.service.template.jpa.service;
-import com.lanyuanxiaoyao.service.template.common.controller.Query;
+import com.lanyuanxiaoyao.service.template.common.entity.Page;
+import com.lanyuanxiaoyao.service.template.common.entity.Query;
import com.lanyuanxiaoyao.service.template.common.exception.IdNotFoundException;
import com.lanyuanxiaoyao.service.template.common.exception.NotCollectionException;
import com.lanyuanxiaoyao.service.template.common.exception.NotComparableException;
import com.lanyuanxiaoyao.service.template.common.exception.NotStringException;
import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper;
-import com.lanyuanxiaoyao.service.template.common.service.Page;
+import com.lanyuanxiaoyao.service.template.common.service.QueryParser;
import com.lanyuanxiaoyao.service.template.common.service.SimpleService;
import com.lanyuanxiaoyao.service.template.jpa.entity.IdOnlyEntity;
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
@@ -159,300 +160,6 @@ public abstract class SimpleServiceSupport implemen
);
}
- /**
- * 解析字段路径
- *
- * 支持多级字段路径解析,使用"."分隔多级字段。
- * 例如: "user.name" 表示实体的user属性的name字段。
- *
- *
- * @param root JPA Criteria查询根节点
- * @param column 字段路径字符串
- * @param 字段类型
- * @return 返回字段路径对象
- * @throws IllegalArgumentException 当字段路径为空时抛出
- */
- private Path column(Root root, String column) {
- if (ObjectHelper.isEmpty(column)) {
- throw new IllegalArgumentException("Column cannot be blank");
- }
- var columns = column.split("\\.");
- Path path = root.get(columns[0]);
- for (int i = 1; i < columns.length; i++) {
- path = path.get(columns[i]);
- }
- return path;
- }
-
- /**
- * 处理字段值
- *
- * 对于枚举类型字段,将字符串值转换为对应的枚举值。
- * 对于LocalDateTime类型字段,将字符串转换为时间对象。
- * 其他类型直接返回原值。
- *
- *
- * @param column 字段路径
- * @param value 字段值
- * @param 字段类型
- * @return 处理后的字段值
- * @throws IllegalArgumentException 当枚举类型字段的值不是字符串时抛出
- */
- @SuppressWarnings({"unchecked", "rawtypes"})
- private Object value(Path column, Object value) {
- if (ObjectHelper.isNull(value)) {
- return null;
- }
- var javaType = column.getJavaType();
- if (javaType.isEnum()) {
- if (value instanceof String enumName) {
- var enumType = (Class) javaType;
- return Enum.valueOf(enumType, enumName);
- } else {
- throw new IllegalArgumentException("枚举类型字段需要 String 类型的值");
- }
- } else if (javaType.isAssignableFrom(LocalDateTime.class)) {
- return LocalDateTime.parse(String.valueOf(value), DATE_TIME_FORMATTER);
- }
- return value;
- }
-
- /**
- * 构建查询条件谓词列表
- *
- * 根据Query.Queryable对象构建JPA Criteria查询的谓词列表。
- * 支持多种查询条件类型,包括相等、不等、模糊匹配、范围查询等。
- *
- *
- * @param queryable 查询条件对象
- * @param root JPA Criteria查询根节点
- * @param query JPA Criteria查询对象
- * @param builder JPA Criteria构建器
- * @return 返回构建的谓词列表
- */
- @SuppressWarnings("unchecked")
- private Predicate queryPredicates(Query.Queryable queryable, Root root, CriteriaQuery> query, CriteriaBuilder builder) {
- var predicates = new ArrayList();
- if (ObjectHelper.isNull(queryable)) {
- return null;
- }
- if (ObjectHelper.isNotEmpty(queryable.nullEqual())) {
- queryable.nullEqual().forEach(column -> predicates.add(builder.isNull(column(root, column))));
- }
- if (ObjectHelper.isNotEmpty(queryable.notNullEqual())) {
- queryable.notNullEqual().forEach(column -> predicates.add(builder.isNotNull(column(root, column))));
- }
- if (ObjectHelper.isNotEmpty(queryable.empty())) {
- queryable.empty().forEach(column -> {
- var path = this.>column(root, column);
- checkCollection(path, column);
- predicates.add(builder.isEmpty(path));
- });
- }
- if (ObjectHelper.isNotEmpty(queryable.notEmpty())) {
- queryable.notEmpty().forEach(column -> {
- var path = this.>column(root, column);
- checkCollection(path, column);
- predicates.add(builder.isNotEmpty(path));
- });
- }
- if (ObjectHelper.isNotEmpty(queryable.equal())) {
- queryable.equal().forEach((column, value) -> {
- var path = column(root, column);
- predicates.add(builder.equal(path, value(path, value)));
- });
- }
- if (ObjectHelper.isNotEmpty(queryable.notEqual())) {
- queryable.notEqual().forEach((column, value) -> {
- var path = column(root, column);
- predicates.add(builder.notEqual(path, value(path, value)));
- });
- }
- if (ObjectHelper.isNotEmpty(queryable.like())) {
- queryable.like().forEach((column, value) -> {
- var path = this.column(root, column);
- checkString(path, value, column);
- predicates.add(builder.like(path, value));
- });
- }
- if (ObjectHelper.isNotEmpty(queryable.notLike())) {
- queryable.notLike().forEach((column, value) -> {
- var path = this.column(root, column);
- checkString(path, value, column);
- predicates.add(builder.notLike(path, value));
- });
- }
- if (ObjectHelper.isNotEmpty(queryable.contain())) {
- queryable.contain().forEach((column, value) -> {
- var path = this.column(root, column);
- checkString(path, value, column);
- predicates.add(builder.like(path, "%" + value + "%"));
- });
- }
- if (ObjectHelper.isNotEmpty(queryable.notContain())) {
- queryable.notContain().forEach((column, value) -> {
- var path = this.column(root, column);
- checkString(path, value, column);
- predicates.add(builder.notLike(path, "%" + value + "%"));
- });
- }
- if (ObjectHelper.isNotEmpty(queryable.startWith())) {
- queryable.startWith().forEach((column, value) -> {
- var path = this.column(root, column);
- checkString(path, value, column);
- predicates.add(builder.like(path, value + "%"));
- });
- }
- if (ObjectHelper.isNotEmpty(queryable.notStartWith())) {
- queryable.notStartWith().forEach((column, value) -> {
- var path = this.column(root, column);
- checkString(path, value, column);
- predicates.add(builder.notLike(path, value + "%"));
- });
- }
- if (ObjectHelper.isNotEmpty(queryable.endWith())) {
- queryable.endWith().forEach((column, value) -> {
- var path = this.column(root, column);
- checkString(path, value, column);
- predicates.add(builder.like(path, "%" + value));
- });
- }
- if (ObjectHelper.isNotEmpty(queryable.notEndWith())) {
- queryable.notEndWith().forEach((column, value) -> {
- var path = this.column(root, column);
- checkString(path, value, column);
- predicates.add(builder.notLike(path, "%" + value));
- });
- }
- if (ObjectHelper.isNotEmpty(queryable.great())) {
- queryable.great().forEach((column, value) -> {
- var path = this.>column(root, column);
- checkComparable(path, value, column);
- predicates.add(builder.greaterThan(path, (Comparable