From 6b89b84423edda31b911b1e71e171be09e64d0eb Mon Sep 17 00:00:00 2001 From: AlexBob Date: Sun, 22 Dec 2024 14:18:50 +0800 Subject: [PATCH] Refactor: Update QueryFragment API to use method chaining for better readability and consistency --- .../commons/utils/query/QueryFragment.java | 105 +++++++----------- .../boot/commons/utils/query/QueryHelper.java | 18 +-- .../commons/utils/query/QueryJsonHelper.java | 8 +- .../plate/boot/security/SecurityManager.java | 28 ++--- .../core/group/member/GroupMemberReq.java | 4 +- .../tenant/member/TenantMemberRequest.java | 6 +- .../tenant/member/TenantMembersService.java | 4 +- 7 files changed, 77 insertions(+), 96 deletions(-) diff --git a/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryFragment.java b/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryFragment.java index 40b9f12..df8ffc1 100644 --- a/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryFragment.java +++ b/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryFragment.java @@ -20,11 +20,11 @@ *
  * {@code
  * QueryFragment queryFragment = QueryFragment.withNew()
- *     .addColumn("id", "name", "email")
- *     .addQuery("users")
- *     .addWhere("age > :age", 18)
- *     .addOrder("name ASC")
- *     .addOrder("email DESC");
+ *     .columns("id", "name", "email")
+ *     .query("users")
+ *     .where("age > :age", 18)
+ *     .orderBy("name ASC")
+ *     .orderBy("email DESC");
  *
  * // Bind parameters
  * queryFragment.put("age", 18);
@@ -48,7 +48,7 @@ public class QueryFragment extends HashMap {
      * Example usage:
      * 
      * {@code
-     * queryFragment.addColumn("id", "name", "email");
+     * queryFragment.columns("id", "name", "email");
      * }
      * 
*/ @@ -59,18 +59,18 @@ public class QueryFragment extends HashMap { * Example usage: *
      * {@code
-     * queryFragment.addQuery("users");
+     * queryFragment.query("users");
      * }
      * 
*/ - private final StringJoiner select = new StringJoiner(" "); + private final StringJoiner from = new StringJoiner(" "); /** * A StringJoiner to accumulate WHERE conditions. * Example usage: *
      * {@code
-     * queryFragment.addWhere("age > :age");
+     * queryFragment.where("age > :age");
      * }
      * 
*/ @@ -81,7 +81,7 @@ public class QueryFragment extends HashMap { * Example usage: *
      * {@code
-     * queryFragment.addOrder("name ASC");
+     * queryFragment.orderBy("name ASC");
      * }
      * 
*/ @@ -92,26 +92,30 @@ public class QueryFragment extends HashMap { /** * The maximum number of rows to return (LIMIT clause). */ - private final int size; + private int size = 25; /** * The number of rows to skip before starting to return rows (OFFSET clause). */ - private final long offset; + private long offset = 0; - public QueryFragment(int size, long offset, QueryFragment params) { - super(16); - this.size = size; - this.offset = offset; - this.mergeWhere(params.getWhere()); - this.putAll(params); + public QueryFragment(QueryFragment fragment) { + super(fragment); + this.size = fragment.size; + this.offset = fragment.offset; + this.columns.merge(fragment.getColumns()); + this.from.merge(fragment.getFrom()); + this.orderBy.merge(fragment.getOrderBy()); + this.where.merge(fragment.getWhere()); } - public QueryFragment(int size, long offset, Map params) { - super(16); - this.size = size; - this.offset = offset; - this.putAll(params); + /** + * Creates a new QueryFragment instance with the specified parameters. + * + * @param params the parameters to initialize the QueryFragment with + */ + public QueryFragment(Map params) { + super(params); } public static QueryFragment withNew() { @@ -119,11 +123,11 @@ public static QueryFragment withNew() { } public static QueryFragment withMap(Map params) { - return new QueryFragment(Integer.MAX_VALUE, 0, params); + return new QueryFragment(params); } public static QueryFragment withMap(int size, long offset, Map params) { - return new QueryFragment(size, offset, params); + return withMap(params).limit(size, offset); } public static QueryFragment of(QueryFragment params) { @@ -131,25 +135,25 @@ public static QueryFragment of(QueryFragment params) { } public static QueryFragment of(int size, long offset, QueryFragment params) { - return new QueryFragment(size, offset, params); + return of(params).limit(size, offset); } - public QueryFragment addColumn(CharSequence... columns) { + public QueryFragment columns(CharSequence... columns) { for (CharSequence column : columns) { this.columns.add(column); } return this; } - public QueryFragment addQuery(CharSequence... queries) { - this.select.setEmptyValue(""); + public QueryFragment query(CharSequence... queries) { + this.from.setEmptyValue(""); for (CharSequence query : queries) { - this.select.add(query); + this.from.add(query); } return this; } - public QueryFragment addWhere(CharSequence where) { + public QueryFragment where(CharSequence where) { this.where.add(where); return this; } @@ -160,40 +164,17 @@ public QueryFragment addWhere(CharSequence where) { * @param order the order * @return this */ - public QueryFragment addOrder(CharSequence order) { + public QueryFragment orderBy(CharSequence order) { this.orderBy.add(order); return this; } - /** - * Merges the given where clause with the existing one. - * - * @param where the where - * @return this - */ - public QueryFragment mergeWhere(StringJoiner where) { - this.where.merge(where); - return this; - } - - /** - * Merges the given order clause with the existing one. - * - * @param order the order - * @return this - */ - public QueryFragment mergeOrder(StringJoiner order) { - this.orderBy.merge(order); + public QueryFragment limit(int size, long offset) { + this.size = size; + this.offset = offset; return this; } - /** - * Generates the WHERE clause part of a SQL query based on the stored conditions. - * If conditions have been accumulated, it prefixes the conditions with the 'WHERE' keyword; - * otherwise, it returns an empty string to indicate no conditions. - * - * @return A String forming the WHERE clause of the SQL query, or an empty string if no conditions are present. - */ public String whereSql() { if (this.where.length() > 0) { return " WHERE " + this.where; @@ -220,9 +201,9 @@ public String orderSql() { * @throws QueryException if the querySql is null, indicating that the query structure is incomplete. */ public String querySql() { - if (this.select.length() > 0) { + if (this.from.length() > 0) { return String.format("SELECT %s FROM %s %s %s LIMIT %d OFFSET %d", - this.columns, this.select, whereSql(), orderSql(), this.size, this.offset); + this.columns, this.from, whereSql(), orderSql(), this.size, this.offset); } throw QueryException.withError("This querySql is null, please use whereSql() method!", new IllegalArgumentException("This querySql is null, please use whereSql() method")); @@ -240,8 +221,8 @@ public String querySql() { * @throws QueryException if the countSql is null, indicating that the query structure is incomplete. */ public String countSql() { - if (this.select.length() > 0) { - return "SELECT COUNT(*) FROM (" + String.format("SELECT %s FROM %s", this.columns, this.select) + if (this.from.length() > 0) { + return "SELECT COUNT(*) FROM (" + String.format("SELECT %s FROM %s", this.columns, this.from) + whereSql() + ") t"; } throw QueryException.withError("This countSql is null, please use whereSql() method!", diff --git a/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryHelper.java b/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryHelper.java index a489f48..1e87a4a 100644 --- a/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryHelper.java +++ b/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryHelper.java @@ -241,7 +241,7 @@ private static void processQueryKey(QueryFragment queryFragment, Map) objectMap.get("query"); var jsonQueryFragment = QueryJsonHelper.queryJson(jsonMap, prefix); - queryFragment.mergeWhere(jsonQueryFragment.getWhere()); + queryFragment.getWhere().merge(jsonQueryFragment.getWhere()); queryFragment.putAll(jsonQueryFragment); } } @@ -257,7 +257,7 @@ private static void processQueryKey(QueryFragment queryFragment, Map objectMap, Collection skipKeys, String prefix) { if (!skipKeys.contains("securityCode") && objectMap.containsKey("securityCode")) { var column = StringUtils.hasLength(prefix) ? prefix + ".tenant_code" : "tenant_code"; - queryFragment.addWhere(column + " LIKE :securityCode"); + queryFragment.where(column + " LIKE :securityCode"); queryFragment.put("securityCode", objectMap.get("securityCode")); } } @@ -273,9 +273,9 @@ private static void processSearchKey(QueryFragment queryFragment, Map entry : queryFragment.entrySet()) { String conditionSql = buildConditionSql(entry, prefix); - queryFragment.addWhere(conditionSql); + queryFragment.where(conditionSql); } } @@ -352,8 +352,8 @@ public static void applyQuerySql(QueryFragment queryFragment, Object object) { } String tableName = StringUtils.hasLength(table.value()) ? table.value() : objectClass.getName(); - queryFragment.addColumn("*"); - queryFragment.addQuery(tableName); + queryFragment.columns("*"); + queryFragment.query(tableName); } /** diff --git a/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryJsonHelper.java b/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryJsonHelper.java index 8b3f1d1..a1cf3d5 100644 --- a/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryJsonHelper.java +++ b/boot/platform/src/main/java/com/plate/boot/commons/utils/query/QueryJsonHelper.java @@ -165,7 +165,7 @@ public static QueryFragment queryJson(Map params, String prefix) QueryFragment queryFragment = QueryFragment.withNew(); for (Map.Entry entry : params.entrySet()) { var condition = buildJsonCondition(entry, prefix); - queryFragment.mergeWhere(condition.getWhere()); + queryFragment.getWhere().merge(condition.getWhere()); queryFragment.putAll(condition); } return queryFragment; @@ -232,7 +232,7 @@ private static QueryFragment buildJsonCondition(Map.Entry entry, //处理最后键 QueryFragment lastCondition = buildLastCondition(keys, entry.getValue()); conditionBuilder.append(lastCondition.getWhere()); - return QueryFragment.withMap(lastCondition).addWhere(conditionBuilder.toString()); + return QueryFragment.withMap(lastCondition).where(conditionBuilder.toString()); } /** @@ -260,7 +260,7 @@ private static QueryFragment buildLastCondition(String[] keys, Object value) { Map.Entry exps = queryKeywordMapper(lastKey); if (exps == null) { conditionSql.append(lastKey).append("' = :").append(paramName); - return QueryFragment.withMap(Map.of(paramName, value)).addWhere(conditionSql.toString()); + return QueryFragment.withMap(Map.of(paramName, value)).where(conditionSql.toString()); } String key = lastKey.substring(0, lastKey.length() - exps.getKey().length()); @@ -280,7 +280,7 @@ private static QueryFragment buildLastCondition(String[] keys, Object value) { conditionSql.append(exps.getValue()).append(" :").append(paramName); params = Map.of(paramName, value); } - return QueryFragment.withMap(params).addWhere(conditionSql.toString()); + return QueryFragment.withMap(params).where(conditionSql.toString()); } /** diff --git a/boot/platform/src/main/java/com/plate/boot/security/SecurityManager.java b/boot/platform/src/main/java/com/plate/boot/security/SecurityManager.java index 9a306a4..3bb3407 100644 --- a/boot/platform/src/main/java/com/plate/boot/security/SecurityManager.java +++ b/boot/platform/src/main/java/com/plate/boot/security/SecurityManager.java @@ -64,24 +64,24 @@ public class SecurityManager extends AbstractDatabase implements ReactiveUserDetailsService, ReactiveUserDetailsPasswordService { private final static QueryFragment QUERY_GROUP_MEMBERS_FRAGMENT = QueryFragment.withNew() - .addColumn("a.*", "b.name", "b.extend") - .addQuery("se_group_members a", "join se_groups b on a.group_code=b.code") - .addWhere("a.user_code like :userCode"); + .columns("a.*", "b.name", "b.extend") + .query("se_group_members a", "join se_groups b on a.group_code=b.code") + .where("a.user_code like :userCode"); private final static QueryFragment QUERY_TENANT_MEMBERS_FRAGMENT = QueryFragment.withNew() - .addColumn("a.*", "b.name", "b.extend") - .addQuery("se_tenant_members a", "join se_tenants b on a.tenant_code=b.code") - .addWhere("a.user_code like :userCode"); + .columns("a.*", "b.name", "b.extend") + .query("se_tenant_members a", "join se_tenants b on a.tenant_code=b.code") + .where("a.user_code like :userCode"); private final static QueryFragment QUERY_USER_AUTHORITY_FRAGMENT = QueryFragment.withNew() - .addColumn("*") - .addQuery("se_authorities") - .addWhere("user_code = :userCode"); + .columns("*") + .query("se_authorities") + .where("user_code = :userCode"); private final static QueryFragment QUERY_GROUP_AUTHORITY_FRAGMENT = QueryFragment.withNew() - .addColumn("ga.*") - .addQuery("se_group_authorities ga", + .columns("ga.*") + .query("se_group_authorities ga", "join se_group_members gm on ga.group_code = gm.group_code", "join se_users su on gm.user_code = su.code", "join se_groups sg on gm.group_code = sg.code and sg.tenant_code = su.tenant_code") - .addWhere("gm.user_code = :userCode"); + .where("gm.user_code = :userCode"); /** * Represents the service layer for handling user-related operations. @@ -133,8 +133,8 @@ public Mono registerOrModifyUser(UserRequest request) { * @return A Mono emitting the User if found, or an empty Mono if no user matches the given OAuth2 binding data. */ public Mono loadByOauth2(String bindType, String openid) { - QueryFragment queryFragment = QueryFragment.withNew().addColumn("*").addQuery("se_users") - .addWhere("extend->'oauth2'->:bindType->>'openid'::varchar = :openid"); + QueryFragment queryFragment = QueryFragment.withNew().columns("*").query("se_users") + .where("extend->'oauth2'->:bindType->>'openid'::varchar = :openid"); queryFragment.put("bindType", bindType); queryFragment.put("openid", openid); var userMono = this.databaseClient.sql(queryFragment::querySql).bindValues(queryFragment) diff --git a/boot/platform/src/main/java/com/plate/boot/security/core/group/member/GroupMemberReq.java b/boot/platform/src/main/java/com/plate/boot/security/core/group/member/GroupMemberReq.java index 1c6bad7..a4c5d30 100644 --- a/boot/platform/src/main/java/com/plate/boot/security/core/group/member/GroupMemberReq.java +++ b/boot/platform/src/main/java/com/plate/boot/security/core/group/member/GroupMemberReq.java @@ -36,12 +36,12 @@ public Criteria toCriteria() { public QueryFragment toParamSql() { QueryFragment queryFragment = QueryHelper.query(this, List.of("users", "username"), "a"); if (!ObjectUtils.isEmpty(this.getUsers())) { - queryFragment.addWhere("a.user_code in :users"); + queryFragment.where("a.user_code in :users"); queryFragment.put("users", this.getUsers()); } if (StringUtils.hasLength(this.getUsername())) { - queryFragment.addWhere("c.username = :username"); + queryFragment.where("c.username = :username"); queryFragment.put("username", this.getUsername()); } diff --git a/boot/platform/src/main/java/com/plate/boot/security/core/tenant/member/TenantMemberRequest.java b/boot/platform/src/main/java/com/plate/boot/security/core/tenant/member/TenantMemberRequest.java index add814d..275cc9d 100644 --- a/boot/platform/src/main/java/com/plate/boot/security/core/tenant/member/TenantMemberRequest.java +++ b/boot/platform/src/main/java/com/plate/boot/security/core/tenant/member/TenantMemberRequest.java @@ -44,17 +44,17 @@ public QueryFragment toParamSql() { QueryFragment fragment = QueryHelper.query(this, List.of("users", "securityCode", "username"), "a"); if (!ObjectUtils.isEmpty(this.getUsers())) { - fragment.addWhere("a.user_code in (:users)"); + fragment.where("a.user_code in (:users)"); fragment.put("users", StringUtils.collectionToCommaDelimitedString(this.getUsers())); } if (StringUtils.hasLength(this.getSecurityCode())) { - fragment.addWhere("a.tenant_code like :securityCode"); + fragment.where("a.tenant_code like :securityCode"); fragment.put("securityCode", this.getSecurityCode()); } if (StringUtils.hasLength(this.getUsername())) { - fragment.addWhere("c.username = :username"); + fragment.where("c.username = :username"); fragment.put("username", this.getUsername()); } diff --git a/boot/platform/src/main/java/com/plate/boot/security/core/tenant/member/TenantMembersService.java b/boot/platform/src/main/java/com/plate/boot/security/core/tenant/member/TenantMembersService.java index f19a2f0..fd5be86 100644 --- a/boot/platform/src/main/java/com/plate/boot/security/core/tenant/member/TenantMembersService.java +++ b/boot/platform/src/main/java/com/plate/boot/security/core/tenant/member/TenantMembersService.java @@ -28,9 +28,9 @@ public class TenantMembersService extends AbstractDatabase { public Flux search(TenantMemberRequest request, Pageable pageable) { QueryFragment fragment = request.toParamSql(); QueryFragment queryFragment = QueryFragment.of(pageable.getPageSize(), pageable.getOffset(), fragment) - .addColumn("a.*", "b.name as tenant_name", + .columns("a.*", "b.name as tenant_name", "b.extend as tenant_extend", "c.name as login_name", "c.username") - .addQuery("se_tenant_members a", + .query("se_tenant_members a", "inner join se_tenants b on a.tenant_code = b.code", "inner join se_users c on c.code = a.user_code"); QueryHelper.applySort(queryFragment, pageable.getSort(), "a");