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 java.util.Map;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
@Setter
|
public record GlobalResponse<T>(
|
||||||
@Getter
|
Integer status,
|
||||||
@ToString
|
String message,
|
||||||
public class GlobalResponse<T> {
|
T data
|
||||||
|
) {
|
||||||
private static final int SUCCESS_STATUS = 0;
|
private static final int SUCCESS_STATUS = 0;
|
||||||
private static final int ERROR_STATUS = 500;
|
private static final int ERROR_STATUS = 500;
|
||||||
private static final String SUCCESS_MESSAGE = "OK";
|
private static final String SUCCESS_MESSAGE = "OK";
|
||||||
private static final String ERROR_MESSAGE = "ERROR";
|
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() {
|
public static GlobalResponse<Object> responseError() {
|
||||||
return responseError(ERROR_MESSAGE);
|
return responseError(ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GlobalResponse<Object> responseError(String 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() {
|
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;
|
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 {
|
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.common.controller.Query;
|
||||||
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
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;
|
Long save(ENTITY entity) throws Exception;
|
||||||
|
|
||||||
void save(Iterable<ENTITY> entities) 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;
|
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.common.helper.ObjectHelper;
|
||||||
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
|
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
|
||||||
import com.lanyuanxiaoyao.service.template.jpa.service.SimpleServiceSupport;
|
import com.lanyuanxiaoyao.service.template.jpa.service.SimpleServiceSupport;
|
||||||
@@ -158,14 +160,14 @@ public abstract class SimpleControllerSupport<ENTITY extends SimpleEntity, SAVE_
|
|||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
@PostMapping(LIST)
|
@PostMapping(LIST)
|
||||||
@Override
|
@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)) {
|
if (ObjectHelper.isNull(query)) {
|
||||||
return GlobalResponse.responseCrudData(List.of(), 0);
|
return GlobalResponse.responseCrudData(List.of(), 0);
|
||||||
}
|
}
|
||||||
var mapper = listItemMapper();
|
var mapper = listItemMapper();
|
||||||
var result = service.list(query);
|
var result = service.list(query);
|
||||||
return GlobalResponse.responseCrudData(
|
return GlobalResponse.responseCrudData(
|
||||||
result.get()
|
result.items()
|
||||||
.map(entity -> {
|
.map(entity -> {
|
||||||
try {
|
try {
|
||||||
return mapper.apply(entity);
|
return mapper.apply(entity);
|
||||||
@@ -174,7 +176,7 @@ public abstract class SimpleControllerSupport<ENTITY extends SimpleEntity, SAVE_
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.toList(),
|
.toList(),
|
||||||
result.getTotalElements()
|
result.total()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.lanyuanxiaoyao.service.template.jpa.service;
|
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.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.IdOnlyEntity;
|
||||||
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
|
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
|
||||||
import com.lanyuanxiaoyao.service.template.jpa.repository.SimpleRepository;
|
import com.lanyuanxiaoyao.service.template.jpa.repository.SimpleRepository;
|
||||||
@@ -20,7 +22,6 @@ import java.util.Optional;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.mapstruct.Named;
|
import org.mapstruct.Named;
|
||||||
import org.springframework.data.domain.Page;
|
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
|
|
||||||
@@ -267,148 +268,148 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
|
|||||||
if (ObjectHelper.isNull(queryable)) {
|
if (ObjectHelper.isNull(queryable)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getNullEqual())) {
|
if (ObjectHelper.isNotEmpty(queryable.nullEqual())) {
|
||||||
queryable.getNullEqual().forEach(column -> predicates.add(builder.isNull(column(root, column))));
|
queryable.nullEqual().forEach(column -> predicates.add(builder.isNull(column(root, column))));
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getNotNullEqual())) {
|
if (ObjectHelper.isNotEmpty(queryable.notNullEqual())) {
|
||||||
queryable.getNotNullEqual().forEach(column -> predicates.add(builder.isNotNull(column(root, column))));
|
queryable.notNullEqual().forEach(column -> predicates.add(builder.isNotNull(column(root, column))));
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getEmpty())) {
|
if (ObjectHelper.isNotEmpty(queryable.empty())) {
|
||||||
queryable.getEmpty().forEach(column -> {
|
queryable.empty().forEach(column -> {
|
||||||
var path = this.<Collection<Object>>column(root, column);
|
var path = this.<Collection<Object>>column(root, column);
|
||||||
checkCollection(path, column);
|
checkCollection(path, column);
|
||||||
predicates.add(builder.isEmpty(path));
|
predicates.add(builder.isEmpty(path));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getNotEmpty())) {
|
if (ObjectHelper.isNotEmpty(queryable.notEmpty())) {
|
||||||
queryable.getNotEmpty().forEach(column -> {
|
queryable.notEmpty().forEach(column -> {
|
||||||
var path = this.<Collection<Object>>column(root, column);
|
var path = this.<Collection<Object>>column(root, column);
|
||||||
checkCollection(path, column);
|
checkCollection(path, column);
|
||||||
predicates.add(builder.isNotEmpty(path));
|
predicates.add(builder.isNotEmpty(path));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getEqual())) {
|
if (ObjectHelper.isNotEmpty(queryable.equal())) {
|
||||||
queryable.getEqual().forEach((column, value) -> {
|
queryable.equal().forEach((column, value) -> {
|
||||||
var path = column(root, column);
|
var path = column(root, column);
|
||||||
predicates.add(builder.equal(path, value(path, value)));
|
predicates.add(builder.equal(path, value(path, value)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getNotEqual())) {
|
if (ObjectHelper.isNotEmpty(queryable.notEqual())) {
|
||||||
queryable.getNotEqual().forEach((column, value) -> {
|
queryable.notEqual().forEach((column, value) -> {
|
||||||
var path = column(root, column);
|
var path = column(root, column);
|
||||||
predicates.add(builder.notEqual(path, value(path, value)));
|
predicates.add(builder.notEqual(path, value(path, value)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getLike())) {
|
if (ObjectHelper.isNotEmpty(queryable.like())) {
|
||||||
queryable.getLike().forEach((column, value) -> {
|
queryable.like().forEach((column, value) -> {
|
||||||
var path = this.<String>column(root, column);
|
var path = this.<String>column(root, column);
|
||||||
checkString(path, value, column);
|
checkString(path, value, column);
|
||||||
predicates.add(builder.like(path, value));
|
predicates.add(builder.like(path, value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getNotLike())) {
|
if (ObjectHelper.isNotEmpty(queryable.notLike())) {
|
||||||
queryable.getNotLike().forEach((column, value) -> {
|
queryable.notLike().forEach((column, value) -> {
|
||||||
var path = this.<String>column(root, column);
|
var path = this.<String>column(root, column);
|
||||||
checkString(path, value, column);
|
checkString(path, value, column);
|
||||||
predicates.add(builder.notLike(path, value));
|
predicates.add(builder.notLike(path, value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getContain())) {
|
if (ObjectHelper.isNotEmpty(queryable.contain())) {
|
||||||
queryable.getContain().forEach((column, value) -> {
|
queryable.contain().forEach((column, value) -> {
|
||||||
var path = this.<String>column(root, column);
|
var path = this.<String>column(root, column);
|
||||||
checkString(path, value, column);
|
checkString(path, value, column);
|
||||||
predicates.add(builder.like(path, "%" + value + "%"));
|
predicates.add(builder.like(path, "%" + value + "%"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getNotContain())) {
|
if (ObjectHelper.isNotEmpty(queryable.notContain())) {
|
||||||
queryable.getNotContain().forEach((column, value) -> {
|
queryable.notContain().forEach((column, value) -> {
|
||||||
var path = this.<String>column(root, column);
|
var path = this.<String>column(root, column);
|
||||||
checkString(path, value, column);
|
checkString(path, value, column);
|
||||||
predicates.add(builder.notLike(path, "%" + value + "%"));
|
predicates.add(builder.notLike(path, "%" + value + "%"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getStartWith())) {
|
if (ObjectHelper.isNotEmpty(queryable.startWith())) {
|
||||||
queryable.getStartWith().forEach((column, value) -> {
|
queryable.startWith().forEach((column, value) -> {
|
||||||
var path = this.<String>column(root, column);
|
var path = this.<String>column(root, column);
|
||||||
checkString(path, value, column);
|
checkString(path, value, column);
|
||||||
predicates.add(builder.like(path, value + "%"));
|
predicates.add(builder.like(path, value + "%"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getNotStartWith())) {
|
if (ObjectHelper.isNotEmpty(queryable.notStartWith())) {
|
||||||
queryable.getNotStartWith().forEach((column, value) -> {
|
queryable.notStartWith().forEach((column, value) -> {
|
||||||
var path = this.<String>column(root, column);
|
var path = this.<String>column(root, column);
|
||||||
checkString(path, value, column);
|
checkString(path, value, column);
|
||||||
predicates.add(builder.notLike(path, value + "%"));
|
predicates.add(builder.notLike(path, value + "%"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getEndWith())) {
|
if (ObjectHelper.isNotEmpty(queryable.endWith())) {
|
||||||
queryable.getEndWith().forEach((column, value) -> {
|
queryable.endWith().forEach((column, value) -> {
|
||||||
var path = this.<String>column(root, column);
|
var path = this.<String>column(root, column);
|
||||||
checkString(path, value, column);
|
checkString(path, value, column);
|
||||||
predicates.add(builder.like(path, "%" + value));
|
predicates.add(builder.like(path, "%" + value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getNotEndWith())) {
|
if (ObjectHelper.isNotEmpty(queryable.notEndWith())) {
|
||||||
queryable.getNotEndWith().forEach((column, value) -> {
|
queryable.notEndWith().forEach((column, value) -> {
|
||||||
var path = this.<String>column(root, column);
|
var path = this.<String>column(root, column);
|
||||||
checkString(path, value, column);
|
checkString(path, value, column);
|
||||||
predicates.add(builder.notLike(path, "%" + value));
|
predicates.add(builder.notLike(path, "%" + value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getGreat())) {
|
if (ObjectHelper.isNotEmpty(queryable.great())) {
|
||||||
queryable.getGreat().forEach((column, value) -> {
|
queryable.great().forEach((column, value) -> {
|
||||||
var path = this.<Comparable<Object>>column(root, column);
|
var path = this.<Comparable<Object>>column(root, column);
|
||||||
checkComparable(path, value, column);
|
checkComparable(path, value, column);
|
||||||
predicates.add(builder.greaterThan(path, (Comparable<Object>) value(path, value)));
|
predicates.add(builder.greaterThan(path, (Comparable<Object>) value(path, value)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getLess())) {
|
if (ObjectHelper.isNotEmpty(queryable.less())) {
|
||||||
queryable.getLess().forEach((column, value) -> {
|
queryable.less().forEach((column, value) -> {
|
||||||
var path = this.<Comparable<Object>>column(root, column);
|
var path = this.<Comparable<Object>>column(root, column);
|
||||||
checkComparable(path, value, column);
|
checkComparable(path, value, column);
|
||||||
predicates.add(builder.lessThan(path, (Comparable<Object>) value(path, value)));
|
predicates.add(builder.lessThan(path, (Comparable<Object>) value(path, value)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getGreatEqual())) {
|
if (ObjectHelper.isNotEmpty(queryable.greatEqual())) {
|
||||||
queryable.getGreatEqual().forEach((column, value) -> {
|
queryable.greatEqual().forEach((column, value) -> {
|
||||||
var path = this.<Comparable<Object>>column(root, column);
|
var path = this.<Comparable<Object>>column(root, column);
|
||||||
checkComparable(path, value, column);
|
checkComparable(path, value, column);
|
||||||
predicates.add(builder.greaterThanOrEqualTo(path, (Comparable<Object>) value(path, value)));
|
predicates.add(builder.greaterThanOrEqualTo(path, (Comparable<Object>) value(path, value)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getLessEqual())) {
|
if (ObjectHelper.isNotEmpty(queryable.lessEqual())) {
|
||||||
queryable.getLessEqual().forEach((column, value) -> {
|
queryable.lessEqual().forEach((column, value) -> {
|
||||||
var path = this.<Comparable<Object>>column(root, column);
|
var path = this.<Comparable<Object>>column(root, column);
|
||||||
checkComparable(path, value, column);
|
checkComparable(path, value, column);
|
||||||
predicates.add(builder.lessThanOrEqualTo(path, (Comparable<Object>) value(path, value)));
|
predicates.add(builder.lessThanOrEqualTo(path, (Comparable<Object>) value(path, value)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getInside())) {
|
if (ObjectHelper.isNotEmpty(queryable.inside())) {
|
||||||
queryable.getInside()
|
queryable.inside()
|
||||||
.entrySet()
|
.entrySet()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(entry -> ObjectHelper.isNotEmpty(entry.getValue()))
|
.filter(entry -> ObjectHelper.isNotEmpty(entry.getValue()))
|
||||||
.forEach(entry -> predicates.add(builder.in(column(root, entry.getKey())).value(entry.getValue())));
|
.forEach(entry -> predicates.add(builder.in(column(root, entry.getKey())).value(entry.getValue())));
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getNotInside())) {
|
if (ObjectHelper.isNotEmpty(queryable.notInside())) {
|
||||||
queryable.getNotInside()
|
queryable.notInside()
|
||||||
.entrySet()
|
.entrySet()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(entry -> ObjectHelper.isNotEmpty(entry.getValue()))
|
.filter(entry -> ObjectHelper.isNotEmpty(entry.getValue()))
|
||||||
.forEach(entry -> predicates.add(builder.in(column(root, entry.getKey())).value(entry.getValue()).not()));
|
.forEach(entry -> predicates.add(builder.in(column(root, entry.getKey())).value(entry.getValue()).not()));
|
||||||
}
|
}
|
||||||
if (ObjectHelper.isNotEmpty(queryable.getBetween())) {
|
if (ObjectHelper.isNotEmpty(queryable.between())) {
|
||||||
queryable.getBetween().forEach((column, value) -> {
|
queryable.between().forEach((column, value) -> {
|
||||||
var path = this.<Comparable<Object>>column(root, column);
|
var path = this.<Comparable<Object>>column(root, column);
|
||||||
checkComparable(path, value, 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())) {
|
if (ObjectHelper.isNotEmpty(queryable.notBetween())) {
|
||||||
queryable.getNotBetween().forEach((column, value) -> {
|
queryable.notBetween().forEach((column, value) -> {
|
||||||
var path = this.<Comparable<Object>>column(root, column);
|
var path = this.<Comparable<Object>>column(root, column);
|
||||||
checkComparable(path, value, 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 当区间值不可比较时抛出
|
* @throws NotComparableException 当区间值不可比较时抛出
|
||||||
*/
|
*/
|
||||||
private void checkComparable(Path<?> path, Query.Queryable.Between value, String column) {
|
private void checkComparable(Path<?> path, Query.Queryable.Between value, String column) {
|
||||||
checkComparable(path, value.getStart(), column);
|
checkComparable(path, value.start(), column);
|
||||||
checkComparable(path, value.getEnd(), column);
|
checkComparable(path, value.end(), column);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -510,30 +511,31 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
|
|||||||
@Override
|
@Override
|
||||||
public Page<ENTITY> list(Query listQuery) {
|
public Page<ENTITY> list(Query listQuery) {
|
||||||
var pageRequest = PageRequest.of(DEFAULT_PAGE_INDEX - 1, DEFAULT_PAGE_SIZE, Sort.by(SimpleEntity.Fields.createdTime).descending());
|
var pageRequest = PageRequest.of(DEFAULT_PAGE_INDEX - 1, DEFAULT_PAGE_SIZE, Sort.by(SimpleEntity.Fields.createdTime).descending());
|
||||||
if (ObjectHelper.isNotNull(listQuery.getPage())) {
|
if (ObjectHelper.isNotNull(listQuery.page())) {
|
||||||
var index = Math.max(ObjectHelper.defaultIfNull(listQuery.getPage().getIndex(), DEFAULT_PAGE_INDEX) - 1, 0);
|
var index = Math.max(ObjectHelper.defaultIfNull(listQuery.page().index(), DEFAULT_PAGE_INDEX) - 1, 0);
|
||||||
var size = Math.max(ObjectHelper.defaultIfNull(listQuery.getPage().getSize(), DEFAULT_PAGE_SIZE), 1);
|
var size = Math.max(ObjectHelper.defaultIfNull(listQuery.page().size(), DEFAULT_PAGE_SIZE), 1);
|
||||||
if (ObjectHelper.isNotEmpty(listQuery.getSort())) {
|
if (ObjectHelper.isNotEmpty(listQuery.sort())) {
|
||||||
pageRequest = PageRequest.of(index, size, Sort.by(
|
pageRequest = PageRequest.of(index, size, Sort.by(
|
||||||
listQuery.getSort()
|
listQuery.sort()
|
||||||
.stream()
|
.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()
|
.toList()
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
pageRequest = PageRequest.of(index, size, Sort.by(SimpleEntity.Fields.createdTime).descending());
|
pageRequest = PageRequest.of(index, size, Sort.by(SimpleEntity.Fields.createdTime).descending());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return repository.findAll(
|
var result = repository.findAll(
|
||||||
(root, query, builder) -> {
|
(root, query, builder) -> {
|
||||||
var predicate = listPredicate(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)
|
return ObjectHelper.isNull(predicate)
|
||||||
? queryPredicate
|
? queryPredicate
|
||||||
: builder.and(predicate, queryPredicate);
|
: builder.and(predicate, queryPredicate);
|
||||||
},
|
},
|
||||||
pageRequest
|
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