refactor(common): 将包结构从 jpa 迁移至 common 并重构核心类
- 将所有控制器接口从 jpa 包迁移至 common 包 - 将 GlobalResponse、Query、Page 等核心类重构为 record 类型 - 移除 Lombok 依赖并简化代码结构 - 更新 SimpleService 接口以支持更通用的实体类型 - 调整 SimpleControllerSupport 和 SimpleServiceSupport 以适配新的 API - 清理 web 模块的 pom.xml 中的冗余依赖和配置
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.controller;
|
||||
package com.lanyuanxiaoyao.service.template.common.controller;
|
||||
|
||||
/**
|
||||
* 详情控制器接口,用于定义统一的获取实体详情的接口规范
|
||||
@@ -1,42 +1,23 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.controller;
|
||||
package com.lanyuanxiaoyao.service.template.common.controller;
|
||||
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@ToString
|
||||
public class GlobalResponse<T> {
|
||||
public record GlobalResponse<T>(
|
||||
Integer status,
|
||||
String message,
|
||||
T data
|
||||
) {
|
||||
private static final int SUCCESS_STATUS = 0;
|
||||
private static final int ERROR_STATUS = 500;
|
||||
private static final String SUCCESS_MESSAGE = "OK";
|
||||
private static final String ERROR_MESSAGE = "ERROR";
|
||||
private Integer status;
|
||||
private String message;
|
||||
private T data;
|
||||
|
||||
private GlobalResponse() {
|
||||
this(SUCCESS_STATUS, SUCCESS_MESSAGE, null);
|
||||
}
|
||||
|
||||
private GlobalResponse(Integer status, String message) {
|
||||
this(status, message, null);
|
||||
}
|
||||
|
||||
private GlobalResponse(Integer status, String message, T data) {
|
||||
this.status = status;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static GlobalResponse<Object> responseError() {
|
||||
return responseError(ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
public static GlobalResponse<Object> responseError(String message) {
|
||||
return new GlobalResponse<>(ERROR_STATUS, message);
|
||||
return new GlobalResponse<>(ERROR_STATUS, message, null);
|
||||
}
|
||||
|
||||
public static GlobalResponse<Object> responseSuccess() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.controller;
|
||||
package com.lanyuanxiaoyao.service.template.common.controller;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
package com.lanyuanxiaoyao.service.template.common.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 查询条件封装类,用于构建复杂的查询条件
|
||||
* 包含查询条件、排序条件和分页条件
|
||||
*
|
||||
* <p>前端传入的JSON格式示例:</p>
|
||||
* <pre>
|
||||
* {
|
||||
* "query": {
|
||||
* "equal": {
|
||||
* "name": "张三"
|
||||
* },
|
||||
* "like": {
|
||||
* "address": "%北京%"
|
||||
* },
|
||||
* "greatEqual": {
|
||||
* "age": 18
|
||||
* },
|
||||
* "less": {
|
||||
* "age": 60
|
||||
* },
|
||||
* "between": {
|
||||
* "salary": {
|
||||
* "start": 5000,
|
||||
* "end": 10000
|
||||
* }
|
||||
* }
|
||||
* },
|
||||
* "sort": [
|
||||
* {
|
||||
* "column": "createTime",
|
||||
* "direction": "DESC"
|
||||
* }
|
||||
* ],
|
||||
* "page": {
|
||||
* "index": 0,
|
||||
* "size": 10
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>查询条件说明:</p>
|
||||
* <ul>
|
||||
* <li>nullEqual: 字段值为null的条件</li>
|
||||
* <li>notNullEqual: 字段值不为null的条件</li>
|
||||
* <li>empty: 字段值为空的条件</li>
|
||||
* <li>notEmpty: 字段值不为空的条件</li>
|
||||
* <li>equal: 字段值相等的条件</li>
|
||||
* <li>notEqual: 字段值不相等的条件</li>
|
||||
* <li>like: 字段值模糊匹配的条件</li>
|
||||
* <li>notLike: 字段值不模糊匹配的条件</li>
|
||||
* <li>great: 字段值大于的条件</li>
|
||||
* <li>less: 字段值小于的条件</li>
|
||||
* <li>greatEqual: 字段值大于等于的条件</li>
|
||||
* <li>lessEqual: 字段值小于等于的条件</li>
|
||||
* <li>in: 字段值在指定范围内的条件</li>
|
||||
* <li>notIn: 字段值不在指定范围内的条件</li>
|
||||
* <li>between: 字段值在指定区间内的条件</li>
|
||||
* <li>notBetween: 字段值不在指定区间内的条件</li>
|
||||
* </ul>
|
||||
*/
|
||||
public record Query(
|
||||
Queryable query,
|
||||
List<Sortable> sort,
|
||||
Pageable page
|
||||
) {
|
||||
/**
|
||||
* 可查询条件类,封装各种查询条件
|
||||
*/
|
||||
public record Queryable(
|
||||
List<String> nullEqual,
|
||||
List<String> notNullEqual,
|
||||
List<String> empty,
|
||||
List<String> notEmpty,
|
||||
Map<String, Object> equal,
|
||||
Map<String, Object> notEqual,
|
||||
Map<String, String> like,
|
||||
Map<String, String> notLike,
|
||||
Map<String, String> contain,
|
||||
Map<String, String> notContain,
|
||||
Map<String, String> startWith,
|
||||
Map<String, String> notStartWith,
|
||||
Map<String, String> endWith,
|
||||
Map<String, String> notEndWith,
|
||||
Map<String, Object> great,
|
||||
Map<String, Object> less,
|
||||
Map<String, Object> greatEqual,
|
||||
Map<String, Object> lessEqual,
|
||||
Map<String, List<Object>> inside,
|
||||
Map<String, List<Object>> notInside,
|
||||
Map<String, Between> between,
|
||||
Map<String, Between> notBetween
|
||||
) {
|
||||
/**
|
||||
* 区间范围类,用于表示起始值和结束值
|
||||
*/
|
||||
public record Between(
|
||||
Object start,
|
||||
Object end
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public record Sortable(
|
||||
String column,
|
||||
Direction direction
|
||||
) {
|
||||
public enum Direction {
|
||||
/**
|
||||
* 升序排列
|
||||
*/
|
||||
ASC,
|
||||
/**
|
||||
* 降序排列
|
||||
*/
|
||||
DESC,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 可分页条件类,用于指定分页参数
|
||||
*/
|
||||
public record Pageable(
|
||||
Integer index,
|
||||
Integer size
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.controller;
|
||||
package com.lanyuanxiaoyao.service.template.common.controller;
|
||||
|
||||
/**
|
||||
* 删除控制器接口,用于定义统一的删除实体对象的接口规范
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.controller;
|
||||
package com.lanyuanxiaoyao.service.template.common.controller;
|
||||
|
||||
/**
|
||||
* 保存控制器接口,用于定义统一的保存实体对象的接口规范
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.controller;
|
||||
package com.lanyuanxiaoyao.service.template.common.controller;
|
||||
|
||||
public interface SimpleController<SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> extends SaveController<SAVE_ITEM>, ListController<LIST_ITEM>, DetailController<DETAIL_ITEM>, RemoveController {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.lanyuanxiaoyao.service.template.common.service;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @version 20260106
|
||||
*/
|
||||
public record Page<ENTITY>(Stream<ENTITY> items, long total) {
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.service;
|
||||
package com.lanyuanxiaoyao.service.template.common.service;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.jpa.controller.Query;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
|
||||
import com.lanyuanxiaoyao.service.template.common.controller.Query;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
public interface SimpleService<ENTITY extends SimpleEntity> {
|
||||
public interface SimpleService<ENTITY> {
|
||||
Long save(ENTITY entity) throws Exception;
|
||||
|
||||
void save(Iterable<ENTITY> entities) throws Exception;
|
||||
@@ -1,247 +0,0 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 查询条件封装类,用于构建复杂的查询条件
|
||||
* 包含查询条件、排序条件和分页条件
|
||||
*
|
||||
* <p>前端传入的JSON格式示例:</p>
|
||||
* <pre>
|
||||
* {
|
||||
* "query": {
|
||||
* "equal": {
|
||||
* "name": "张三"
|
||||
* },
|
||||
* "like": {
|
||||
* "address": "%北京%"
|
||||
* },
|
||||
* "greatEqual": {
|
||||
* "age": 18
|
||||
* },
|
||||
* "less": {
|
||||
* "age": 60
|
||||
* },
|
||||
* "between": {
|
||||
* "salary": {
|
||||
* "start": 5000,
|
||||
* "end": 10000
|
||||
* }
|
||||
* }
|
||||
* },
|
||||
* "sort": [
|
||||
* {
|
||||
* "column": "createTime",
|
||||
* "direction": "DESC"
|
||||
* }
|
||||
* ],
|
||||
* "page": {
|
||||
* "index": 0,
|
||||
* "size": 10
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>查询条件说明:</p>
|
||||
* <ul>
|
||||
* <li>nullEqual: 字段值为null的条件</li>
|
||||
* <li>notNullEqual: 字段值不为null的条件</li>
|
||||
* <li>empty: 字段值为空的条件</li>
|
||||
* <li>notEmpty: 字段值不为空的条件</li>
|
||||
* <li>equal: 字段值相等的条件</li>
|
||||
* <li>notEqual: 字段值不相等的条件</li>
|
||||
* <li>like: 字段值模糊匹配的条件</li>
|
||||
* <li>notLike: 字段值不模糊匹配的条件</li>
|
||||
* <li>great: 字段值大于的条件</li>
|
||||
* <li>less: 字段值小于的条件</li>
|
||||
* <li>greatEqual: 字段值大于等于的条件</li>
|
||||
* <li>lessEqual: 字段值小于等于的条件</li>
|
||||
* <li>in: 字段值在指定范围内的条件</li>
|
||||
* <li>notIn: 字段值不在指定范围内的条件</li>
|
||||
* <li>between: 字段值在指定区间内的条件</li>
|
||||
* <li>notBetween: 字段值不在指定区间内的条件</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@ToString
|
||||
public class Query {
|
||||
/**
|
||||
* 查询条件
|
||||
*/
|
||||
private Queryable query;
|
||||
/**
|
||||
* 排序条件列表
|
||||
*/
|
||||
private List<Sortable> sort;
|
||||
/**
|
||||
* 分页条件
|
||||
*/
|
||||
private Pageable page;
|
||||
|
||||
/**
|
||||
* 可查询条件类,封装各种查询条件
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@ToString
|
||||
public static class Queryable {
|
||||
/**
|
||||
* 指定字段值为null的条件列表
|
||||
*/
|
||||
private List<String> nullEqual;
|
||||
/**
|
||||
* 指定字段值不为null的条件列表
|
||||
*/
|
||||
private List<String> notNullEqual;
|
||||
/**
|
||||
* 指定字段值为空的条件列表(如空字符串、空集合等)
|
||||
*/
|
||||
private List<String> empty;
|
||||
/**
|
||||
* 指定字段值不为空的条件列表
|
||||
*/
|
||||
private List<String> notEmpty;
|
||||
/**
|
||||
* 指定字段值相等的条件映射(字段名 -> 值)
|
||||
*/
|
||||
private Map<String, Object> equal;
|
||||
/**
|
||||
* 指定字段值不相等的条件映射(字段名 -> 值)
|
||||
*/
|
||||
private Map<String, Object> notEqual;
|
||||
/**
|
||||
* 指定字段模糊匹配的条件映射(字段名 -> 匹配值)
|
||||
*/
|
||||
private Map<String, String> like;
|
||||
/**
|
||||
* 指定字段不模糊匹配的条件映射(字段名 -> 匹配值)
|
||||
*/
|
||||
private Map<String, String> notLike;
|
||||
/**
|
||||
* 指定字段包含指定字符串的条件映射(字段名 -> 包含值)
|
||||
*/
|
||||
private Map<String, String> contain;
|
||||
/**
|
||||
* 指定字段不包含指定字符串的条件映射(字段名 -> 不包含值)
|
||||
*/
|
||||
private Map<String, String> notContain;
|
||||
/**
|
||||
* 指定字段以指定字符串开头的条件映射(字段名 -> 开头值)
|
||||
*/
|
||||
private Map<String, String> startWith;
|
||||
/**
|
||||
* 指定字段不以指定字符串开头的条件映射(字段名 -> 不开头值)
|
||||
*/
|
||||
private Map<String, String> notStartWith;
|
||||
/**
|
||||
* 指定字段以指定字符串结尾的条件映射(字段名 -> 结尾值)
|
||||
*/
|
||||
private Map<String, String> endWith;
|
||||
/**
|
||||
* 指定字段不以指定字符串结尾的条件映射(字段名 -> 不结尾值)
|
||||
*/
|
||||
private Map<String, String> notEndWith;
|
||||
/**
|
||||
* 指定字段大于条件的映射(字段名 -> 值)
|
||||
*/
|
||||
private Map<String, Object> great;
|
||||
/**
|
||||
* 指定字段小于条件的映射(字段名 -> 值)
|
||||
*/
|
||||
private Map<String, Object> less;
|
||||
/**
|
||||
* 指定字段大于等于条件的映射(字段名 -> 值)
|
||||
*/
|
||||
private Map<String, Object> greatEqual;
|
||||
/**
|
||||
* 指定字段小于等于条件的映射(字段名 -> 值)
|
||||
*/
|
||||
private Map<String, Object> lessEqual;
|
||||
/**
|
||||
* 指定字段值在指定范围内的条件映射(字段名 -> 值列表)
|
||||
*/
|
||||
private Map<String, List<Object>> inside;
|
||||
/**
|
||||
* 指定字段值不在指定范围内的条件映射(字段名 -> 值列表)
|
||||
*/
|
||||
private Map<String, List<Object>> notInside;
|
||||
/**
|
||||
* 指定字段值在指定区间内的条件映射(字段名 -> 区间范围)
|
||||
*/
|
||||
private Map<String, Between> between;
|
||||
/**
|
||||
* 指定字段值不在指定区间内的条件映射(字段名 -> 区间范围)
|
||||
*/
|
||||
private Map<String, Between> notBetween;
|
||||
|
||||
/**
|
||||
* 区间范围类,用于表示起始值和结束值
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@ToString
|
||||
public static class Between {
|
||||
/**
|
||||
* 起始值
|
||||
*/
|
||||
private Object start;
|
||||
/**
|
||||
* 结束值
|
||||
*/
|
||||
private Object end;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 可排序条件类,用于指定排序字段和排序方向
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@ToString
|
||||
public static class Sortable {
|
||||
/**
|
||||
* 排序字段名
|
||||
*/
|
||||
private String column;
|
||||
/**
|
||||
* 排序方向
|
||||
*/
|
||||
private Direction direction;
|
||||
|
||||
/**
|
||||
* 排序方向枚举
|
||||
*/
|
||||
public enum Direction {
|
||||
/**
|
||||
* 升序排列
|
||||
*/
|
||||
ASC,
|
||||
/**
|
||||
* 降序排列
|
||||
*/
|
||||
DESC,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 可分页条件类,用于指定分页参数
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@ToString
|
||||
public static class Pageable {
|
||||
/**
|
||||
* 页码索引(从0开始)
|
||||
*/
|
||||
private Integer index;
|
||||
/**
|
||||
* 每页大小
|
||||
*/
|
||||
private Integer size;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.controller;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.common.controller.GlobalResponse;
|
||||
import com.lanyuanxiaoyao.service.template.common.controller.SimpleController;
|
||||
import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.service.SimpleServiceSupport;
|
||||
@@ -158,14 +160,14 @@ public abstract class SimpleControllerSupport<ENTITY extends SimpleEntity, SAVE_
|
||||
@Transactional(readOnly = true)
|
||||
@PostMapping(LIST)
|
||||
@Override
|
||||
public GlobalResponse<Map<String, Object>> list(@RequestBody Query query) throws Exception {
|
||||
public GlobalResponse<Map<String, Object>> list(@RequestBody com.lanyuanxiaoyao.service.template.common.controller.Query query) throws Exception {
|
||||
if (ObjectHelper.isNull(query)) {
|
||||
return GlobalResponse.responseCrudData(List.of(), 0);
|
||||
}
|
||||
var mapper = listItemMapper();
|
||||
var result = service.list(query);
|
||||
return GlobalResponse.responseCrudData(
|
||||
result.get()
|
||||
result.items()
|
||||
.map(entity -> {
|
||||
try {
|
||||
return mapper.apply(entity);
|
||||
@@ -174,7 +176,7 @@ public abstract class SimpleControllerSupport<ENTITY extends SimpleEntity, SAVE_
|
||||
}
|
||||
})
|
||||
.toList(),
|
||||
result.getTotalElements()
|
||||
result.total()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.service;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.common.controller.Query;
|
||||
import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.controller.Query;
|
||||
import com.lanyuanxiaoyao.service.template.common.service.Page;
|
||||
import com.lanyuanxiaoyao.service.template.common.service.SimpleService;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.IdOnlyEntity;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.repository.SimpleRepository;
|
||||
@@ -20,7 +22,6 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.mapstruct.Named;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
|
||||
@@ -267,148 +268,148 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
|
||||
if (ObjectHelper.isNull(queryable)) {
|
||||
return null;
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getNullEqual())) {
|
||||
queryable.getNullEqual().forEach(column -> predicates.add(builder.isNull(column(root, column))));
|
||||
if (ObjectHelper.isNotEmpty(queryable.nullEqual())) {
|
||||
queryable.nullEqual().forEach(column -> predicates.add(builder.isNull(column(root, column))));
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getNotNullEqual())) {
|
||||
queryable.getNotNullEqual().forEach(column -> predicates.add(builder.isNotNull(column(root, column))));
|
||||
if (ObjectHelper.isNotEmpty(queryable.notNullEqual())) {
|
||||
queryable.notNullEqual().forEach(column -> predicates.add(builder.isNotNull(column(root, column))));
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getEmpty())) {
|
||||
queryable.getEmpty().forEach(column -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.empty())) {
|
||||
queryable.empty().forEach(column -> {
|
||||
var path = this.<Collection<Object>>column(root, column);
|
||||
checkCollection(path, column);
|
||||
predicates.add(builder.isEmpty(path));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getNotEmpty())) {
|
||||
queryable.getNotEmpty().forEach(column -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.notEmpty())) {
|
||||
queryable.notEmpty().forEach(column -> {
|
||||
var path = this.<Collection<Object>>column(root, column);
|
||||
checkCollection(path, column);
|
||||
predicates.add(builder.isNotEmpty(path));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getEqual())) {
|
||||
queryable.getEqual().forEach((column, value) -> {
|
||||
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.getNotEqual())) {
|
||||
queryable.getNotEqual().forEach((column, 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.getLike())) {
|
||||
queryable.getLike().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.like())) {
|
||||
queryable.like().forEach((column, value) -> {
|
||||
var path = this.<String>column(root, column);
|
||||
checkString(path, value, column);
|
||||
predicates.add(builder.like(path, value));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getNotLike())) {
|
||||
queryable.getNotLike().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.notLike())) {
|
||||
queryable.notLike().forEach((column, value) -> {
|
||||
var path = this.<String>column(root, column);
|
||||
checkString(path, value, column);
|
||||
predicates.add(builder.notLike(path, value));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getContain())) {
|
||||
queryable.getContain().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.contain())) {
|
||||
queryable.contain().forEach((column, value) -> {
|
||||
var path = this.<String>column(root, column);
|
||||
checkString(path, value, column);
|
||||
predicates.add(builder.like(path, "%" + value + "%"));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getNotContain())) {
|
||||
queryable.getNotContain().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.notContain())) {
|
||||
queryable.notContain().forEach((column, value) -> {
|
||||
var path = this.<String>column(root, column);
|
||||
checkString(path, value, column);
|
||||
predicates.add(builder.notLike(path, "%" + value + "%"));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getStartWith())) {
|
||||
queryable.getStartWith().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.startWith())) {
|
||||
queryable.startWith().forEach((column, value) -> {
|
||||
var path = this.<String>column(root, column);
|
||||
checkString(path, value, column);
|
||||
predicates.add(builder.like(path, value + "%"));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getNotStartWith())) {
|
||||
queryable.getNotStartWith().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.notStartWith())) {
|
||||
queryable.notStartWith().forEach((column, value) -> {
|
||||
var path = this.<String>column(root, column);
|
||||
checkString(path, value, column);
|
||||
predicates.add(builder.notLike(path, value + "%"));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getEndWith())) {
|
||||
queryable.getEndWith().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.endWith())) {
|
||||
queryable.endWith().forEach((column, value) -> {
|
||||
var path = this.<String>column(root, column);
|
||||
checkString(path, value, column);
|
||||
predicates.add(builder.like(path, "%" + value));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getNotEndWith())) {
|
||||
queryable.getNotEndWith().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.notEndWith())) {
|
||||
queryable.notEndWith().forEach((column, value) -> {
|
||||
var path = this.<String>column(root, column);
|
||||
checkString(path, value, column);
|
||||
predicates.add(builder.notLike(path, "%" + value));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getGreat())) {
|
||||
queryable.getGreat().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.great())) {
|
||||
queryable.great().forEach((column, value) -> {
|
||||
var path = this.<Comparable<Object>>column(root, column);
|
||||
checkComparable(path, value, column);
|
||||
predicates.add(builder.greaterThan(path, (Comparable<Object>) value(path, value)));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getLess())) {
|
||||
queryable.getLess().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.less())) {
|
||||
queryable.less().forEach((column, value) -> {
|
||||
var path = this.<Comparable<Object>>column(root, column);
|
||||
checkComparable(path, value, column);
|
||||
predicates.add(builder.lessThan(path, (Comparable<Object>) value(path, value)));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getGreatEqual())) {
|
||||
queryable.getGreatEqual().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.greatEqual())) {
|
||||
queryable.greatEqual().forEach((column, value) -> {
|
||||
var path = this.<Comparable<Object>>column(root, column);
|
||||
checkComparable(path, value, column);
|
||||
predicates.add(builder.greaterThanOrEqualTo(path, (Comparable<Object>) value(path, value)));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getLessEqual())) {
|
||||
queryable.getLessEqual().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.lessEqual())) {
|
||||
queryable.lessEqual().forEach((column, value) -> {
|
||||
var path = this.<Comparable<Object>>column(root, column);
|
||||
checkComparable(path, value, column);
|
||||
predicates.add(builder.lessThanOrEqualTo(path, (Comparable<Object>) value(path, value)));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getInside())) {
|
||||
queryable.getInside()
|
||||
if (ObjectHelper.isNotEmpty(queryable.inside())) {
|
||||
queryable.inside()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> ObjectHelper.isNotEmpty(entry.getValue()))
|
||||
.forEach(entry -> predicates.add(builder.in(column(root, entry.getKey())).value(entry.getValue())));
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getNotInside())) {
|
||||
queryable.getNotInside()
|
||||
if (ObjectHelper.isNotEmpty(queryable.notInside())) {
|
||||
queryable.notInside()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> ObjectHelper.isNotEmpty(entry.getValue()))
|
||||
.forEach(entry -> predicates.add(builder.in(column(root, entry.getKey())).value(entry.getValue()).not()));
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getBetween())) {
|
||||
queryable.getBetween().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.between())) {
|
||||
queryable.between().forEach((column, value) -> {
|
||||
var path = this.<Comparable<Object>>column(root, column);
|
||||
checkComparable(path, value, column);
|
||||
predicates.add(builder.between(path, (Comparable<Object>) value(path, value.getStart()), (Comparable<Object>) value(path, value.getEnd())));
|
||||
predicates.add(builder.between(path, (Comparable<Object>) value(path, value.start()), (Comparable<Object>) value(path, value.end())));
|
||||
});
|
||||
}
|
||||
if (ObjectHelper.isNotEmpty(queryable.getNotBetween())) {
|
||||
queryable.getNotBetween().forEach((column, value) -> {
|
||||
if (ObjectHelper.isNotEmpty(queryable.notBetween())) {
|
||||
queryable.notBetween().forEach((column, value) -> {
|
||||
var path = this.<Comparable<Object>>column(root, column);
|
||||
checkComparable(path, value, column);
|
||||
predicates.add(builder.between(path, (Comparable<Object>) value(path, value.getStart()), (Comparable<Object>) value(path, value.getEnd())).not());
|
||||
predicates.add(builder.between(path, (Comparable<Object>) value(path, value.start()), (Comparable<Object>) value(path, value.end())).not());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -438,8 +439,8 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
|
||||
* @throws NotComparableException 当区间值不可比较时抛出
|
||||
*/
|
||||
private void checkComparable(Path<?> path, Query.Queryable.Between value, String column) {
|
||||
checkComparable(path, value.getStart(), column);
|
||||
checkComparable(path, value.getEnd(), column);
|
||||
checkComparable(path, value.start(), column);
|
||||
checkComparable(path, value.end(), column);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -510,30 +511,31 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
|
||||
@Override
|
||||
public Page<ENTITY> list(Query listQuery) {
|
||||
var pageRequest = PageRequest.of(DEFAULT_PAGE_INDEX - 1, DEFAULT_PAGE_SIZE, Sort.by(SimpleEntity.Fields.createdTime).descending());
|
||||
if (ObjectHelper.isNotNull(listQuery.getPage())) {
|
||||
var index = Math.max(ObjectHelper.defaultIfNull(listQuery.getPage().getIndex(), DEFAULT_PAGE_INDEX) - 1, 0);
|
||||
var size = Math.max(ObjectHelper.defaultIfNull(listQuery.getPage().getSize(), DEFAULT_PAGE_SIZE), 1);
|
||||
if (ObjectHelper.isNotEmpty(listQuery.getSort())) {
|
||||
if (ObjectHelper.isNotNull(listQuery.page())) {
|
||||
var index = Math.max(ObjectHelper.defaultIfNull(listQuery.page().index(), DEFAULT_PAGE_INDEX) - 1, 0);
|
||||
var size = Math.max(ObjectHelper.defaultIfNull(listQuery.page().size(), DEFAULT_PAGE_SIZE), 1);
|
||||
if (ObjectHelper.isNotEmpty(listQuery.sort())) {
|
||||
pageRequest = PageRequest.of(index, size, Sort.by(
|
||||
listQuery.getSort()
|
||||
listQuery.sort()
|
||||
.stream()
|
||||
.map(sort -> new Sort.Order(Sort.Direction.fromString(sort.getDirection().name()), sort.getColumn()))
|
||||
.map(sort -> new Sort.Order(Sort.Direction.fromString(sort.direction().name()), sort.column()))
|
||||
.toList()
|
||||
));
|
||||
} else {
|
||||
pageRequest = PageRequest.of(index, size, Sort.by(SimpleEntity.Fields.createdTime).descending());
|
||||
}
|
||||
}
|
||||
return repository.findAll(
|
||||
var result = repository.findAll(
|
||||
(root, query, builder) -> {
|
||||
var predicate = listPredicate(root, query, builder);
|
||||
var queryPredicate = queryPredicates(listQuery.getQuery(), root, query, builder);
|
||||
var queryPredicate = queryPredicates(listQuery.query(), root, query, builder);
|
||||
return ObjectHelper.isNull(predicate)
|
||||
? queryPredicate
|
||||
: builder.and(predicate, queryPredicate);
|
||||
},
|
||||
pageRequest
|
||||
);
|
||||
return new Page<>(result.get(), result.getTotalElements());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
30
spring-boot-service-template-web/pom.xml
Normal file
30
spring-boot-service-template-web/pom.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.lanyuanxiaoyao</groupId>
|
||||
<artifactId>spring-boot-service-template</artifactId>
|
||||
<version>1.1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-boot-service-template-web</artifactId>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
Reference in New Issue
Block a user