Skip to content

Commit

Permalink
Replace CriteriaUtils with QueryHelper across services and entities
Browse files Browse the repository at this point in the history
Update service classes and entities to use the new `QueryHelper` utility methods instead of the deprecated `CriteriaUtils`. This change streamlines query construction and ensures consistency in handling query parameters and pagination.

The commit includes modifications to multiple files, replacing instances of `CriteriaUtils` method calls with their `QueryHelper` equivalents and adjusting import statements accordingly. Additionally, it renames related classes like `ParamSql` to `QueryFragment` to reflect the updated utility usage.
  • Loading branch information
vnobo committed Sep 5, 2024
1 parent 0ee3511 commit 6a25c65
Show file tree
Hide file tree
Showing 16 changed files with 137 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.plate.boot.commons.utils.ContextUtils;
import com.plate.boot.commons.utils.query.CriteriaUtils;
import com.plate.boot.commons.utils.query.QueryHelper;
import org.springframework.data.domain.Persistable;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.util.ObjectUtils;
Expand Down Expand Up @@ -60,6 +60,6 @@ default boolean isNew() {
*/
default Criteria criteria(Collection<String> skipKeys) {
// 调用CriteriaUtils的静态方法build来创建Criteria对象,并传入当前对象和要忽略的属性键集合。
return CriteriaUtils.build(this, skipKeys);
return QueryHelper.build(this, skipKeys);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@
* @param params A {@link Map} mapping parameter names to their respective values,
* which are intended to replace placeholders in the SQL query.
*/
public record ParamSql(StringJoiner sql, Map<String, Object> params) implements Serializable {
public record QueryFragment(StringJoiner sql, Map<String, Object> params) implements Serializable {

/**
* Creates a new instance of {@link ParamSql} with the provided conditional SQL
* Creates a new instance of {@link QueryFragment} with the provided conditional SQL
* fragment and parameters map.
*
* @param sql A {@link StringJoiner} object containing the dynamically
* constructed WHERE clause segments of a SQL query, concatenated by 'and'.
* @param params A {@link Map} of parameter names to values, which will be
* substituted for placeholders within the SQL query to prevent SQL injection.
* @return A new {@link ParamSql} instance encapsulating the given SQL fragment
* @return A new {@link QueryFragment} instance encapsulating the given SQL fragment
* and parameters map, ready for use in preparing a parameterized SQL statement.
*/
public static ParamSql of(StringJoiner sql, Map<String, Object> params) {
return new ParamSql(sql, params);
public static QueryFragment of(StringJoiner sql, Map<String, Object> params) {
return new QueryFragment(sql, params);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* This is particularly useful for dynamically constructing SQL queries
* with bind variables in a structured manner.
*/
public final class CriteriaUtils {
public final class QueryHelper {

public static final Set<String> SKIP_CRITERIA_KEYS = Set.of("extend", "createdTime", "updatedTime");

Expand Down Expand Up @@ -64,7 +64,7 @@ public static String applySort(Sort sort, String prefix) {
if (sort == null || sort.isUnsorted()) {
return " order by id desc ";
}
sort = QueryJson.sortJson(sort, prefix);
sort = QueryJsonHelper.transformSortForJson(sort, prefix);
StringJoiner sortSql = new StringJoiner(", ");
for (Sort.Order order : sort) {
String sortedPropertyName = order.getProperty();
Expand Down Expand Up @@ -97,15 +97,15 @@ public static String applySort(Sort sort, String prefix) {
* (joined by 'and') and a map of parameters for prepared statement binding.
*/
@SuppressWarnings("unchecked")
public static ParamSql buildParamSql(Object object, Collection<String> skipKeys, String prefix) {
public static QueryFragment buildParamSql(Object object, Collection<String> skipKeys, String prefix) {

Map<String, Object> objectMap = BeanUtils.beanToMap(object, false, true);
if (ObjectUtils.isEmpty(objectMap)) {
return ParamSql.of(new StringJoiner(" and "), Maps.newHashMap());
return QueryFragment.of(new StringJoiner(" and "), Maps.newHashMap());
}
ParamSql jsonParamSql = QueryJson.queryJson((Map<String, Object>) objectMap.get("query"), prefix);
Map<String, Object> params = jsonParamSql.params();
StringJoiner sql = jsonParamSql.sql();
QueryFragment jsonQueryFragment = QueryJsonHelper.queryJson((Map<String, Object>) objectMap.get("query"), prefix);
Map<String, Object> params = jsonQueryFragment.params();
StringJoiner sql = jsonQueryFragment.sql();
String securityCodeKey = "securityCode";
if (!skipKeys.contains(securityCodeKey) && !ObjectUtils.isEmpty(objectMap.get(securityCodeKey))) {
String key = "tenant_code";
Expand All @@ -124,10 +124,10 @@ public static ParamSql buildParamSql(Object object, Collection<String> skipKeys,
}

objectMap = Maps.filterKeys(objectMap, key -> !removeKeys.contains(key));
ParamSql entityParamSql = buildParamSql(objectMap, prefix);
params.putAll(entityParamSql.params());
sql.merge(entityParamSql.sql());
return ParamSql.of(sql, params);
QueryFragment entityQueryFragment = buildParamSql(objectMap, prefix);
params.putAll(entityQueryFragment.params());
sql.merge(entityQueryFragment.sql());
return QueryFragment.of(sql, params);
}

/**
Expand All @@ -147,7 +147,7 @@ public static ParamSql buildParamSql(Object object, Collection<String> skipKeys,
* statement binding, where keys correspond to named parameters
* and values are the user-provided filter values.
*/
public static ParamSql buildParamSql(Map<String, Object> objectMap, String prefix) {
public static QueryFragment buildParamSql(Map<String, Object> objectMap, String prefix) {
StringJoiner whereSql = new StringJoiner(" and ");
for (Map.Entry<String, Object> entry : objectMap.entrySet()) {
String column = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entry.getKey());
Expand All @@ -166,7 +166,7 @@ public static ParamSql buildParamSql(Map<String, Object> objectMap, String prefi
whereSql.add(column + " = " + paramName);
}
}
return ParamSql.of(whereSql, objectMap);
return QueryFragment.of(whereSql, objectMap);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,48 @@
import java.util.*;

/**
* Searches for a keyword within the provided key and returns the keyword along with its SQL equivalent.
* If no keyword match is found, returns null.
* Utility class providing helper methods to facilitate querying and sorting JSON data within SQL statements.
* This class maps operation keywords to their SQL equivalents and offers functionality to translate
* query parameters and sorting instructions into SQL-compatible formats, especially handy when working
* with JSON data stored in relational databases.
*/
public class QueryJson {
public final class QueryJsonHelper {

private final static Map<String, String> KEYWORDS = Maps.newHashMap();
private final static Map<String, String> SQL_OPERATION_MAPPING = Maps.newHashMap();

static {
KEYWORDS.put("EQ", "=");
KEYWORDS.put("Equal", "=");
KEYWORDS.put("After", ">");
KEYWORDS.put("GreaterThanEqual", ">=");
KEYWORDS.put("GTE", ">=");
KEYWORDS.put("GreaterThan", ">");
KEYWORDS.put("GT", ">");
KEYWORDS.put("Before", "<");
KEYWORDS.put("LessThanEqual", "<=");
KEYWORDS.put("LTE", "<=");
KEYWORDS.put("LessThan", "<");
KEYWORDS.put("LT", "<");
KEYWORDS.put("Between", "between");
KEYWORDS.put("NotBetween", "not between");
KEYWORDS.put("NotIn", "not in");
KEYWORDS.put("In", "in");
KEYWORDS.put("IsNotNull", "is not null");
KEYWORDS.put("NotNull", "is not null");
KEYWORDS.put("IsNull", "is null");
KEYWORDS.put("Null", "is null");
KEYWORDS.put("NotLike", "not like");
KEYWORDS.put("Like", "like");
KEYWORDS.put("StartingWith", "like");
KEYWORDS.put("EndingWith", "like");
KEYWORDS.put("IsNotLike", "not like");
KEYWORDS.put("Containing", "like");
KEYWORDS.put("NotContaining", "not like");
KEYWORDS.put("Not", "!=");
KEYWORDS.put("IsTrue", "is true");
KEYWORDS.put("True", "is true");
KEYWORDS.put("IsFalse", "is false");
KEYWORDS.put("False", "is false");
SQL_OPERATION_MAPPING.put("EQ", "=");
SQL_OPERATION_MAPPING.put("Equal", "=");
SQL_OPERATION_MAPPING.put("After", ">");
SQL_OPERATION_MAPPING.put("GreaterThanEqual", ">=");
SQL_OPERATION_MAPPING.put("GTE", ">=");
SQL_OPERATION_MAPPING.put("GreaterThan", ">");
SQL_OPERATION_MAPPING.put("GT", ">");
SQL_OPERATION_MAPPING.put("Before", "<");
SQL_OPERATION_MAPPING.put("LessThanEqual", "<=");
SQL_OPERATION_MAPPING.put("LTE", "<=");
SQL_OPERATION_MAPPING.put("LessThan", "<");
SQL_OPERATION_MAPPING.put("LT", "<");
SQL_OPERATION_MAPPING.put("Between", "between");
SQL_OPERATION_MAPPING.put("NotBetween", "not between");
SQL_OPERATION_MAPPING.put("NotIn", "not in");
SQL_OPERATION_MAPPING.put("In", "in");
SQL_OPERATION_MAPPING.put("IsNotNull", "is not null");
SQL_OPERATION_MAPPING.put("NotNull", "is not null");
SQL_OPERATION_MAPPING.put("IsNull", "is null");
SQL_OPERATION_MAPPING.put("Null", "is null");
SQL_OPERATION_MAPPING.put("NotLike", "not like");
SQL_OPERATION_MAPPING.put("Like", "like");
SQL_OPERATION_MAPPING.put("StartingWith", "like");
SQL_OPERATION_MAPPING.put("EndingWith", "like");
SQL_OPERATION_MAPPING.put("IsNotLike", "not like");
SQL_OPERATION_MAPPING.put("Containing", "like");
SQL_OPERATION_MAPPING.put("NotContaining", "not like");
SQL_OPERATION_MAPPING.put("Not", "!=");
SQL_OPERATION_MAPPING.put("IsTrue", "is true");
SQL_OPERATION_MAPPING.put("True", "is true");
SQL_OPERATION_MAPPING.put("IsFalse", "is false");
SQL_OPERATION_MAPPING.put("False", "is false");
}

/**
Expand All @@ -65,7 +67,7 @@ public class QueryJson {
* @param prefix An optional prefix to prepend to each sorting property, useful for aliasing in SQL queries.
* @return A new Sort object with transformed sorting properties, ready for sorting queries that involve JSON columns.
*/
public static Sort sortJson(Sort sort, String prefix) {
public static Sort transformSortForJson(Sort sort, String prefix) {
if (sort == null || sort.isEmpty()) {
return Sort.unsorted();
}
Expand Down Expand Up @@ -99,15 +101,15 @@ public static Sort sortJson(Sort sort, String prefix) {
* @param params A map where each key represents a JSON path to a value that should be used in query conditions.
* The value associated with each key is the target value for comparison or range (for Between/NotBetween).
* @param prefix An optional prefix to prepend to column names, useful when querying nested or aliased tables/views.
* @return A {@link ParamSql} object containing a {@link StringJoiner} with concatenated WHERE clause conditions
* @return A {@link QueryFragment} object containing a {@link StringJoiner} with concatenated WHERE clause conditions
* and a map of bind parameters to be used in a prepared statement.
*/
public static ParamSql queryJson(Map<String, Object> params, String prefix) {
public static QueryFragment queryJson(Map<String, Object> params, String prefix) {
Map<String, Object> bindParams = Maps.newHashMap();
StringJoiner whereSql = new StringJoiner(" and ");

if (ObjectUtils.isEmpty(params)) {
return ParamSql.of(whereSql, bindParams);
return QueryFragment.of(whereSql, bindParams);
}

for (Map.Entry<String, Object> entry : params.entrySet()) {
Expand All @@ -122,7 +124,7 @@ public static ParamSql queryJson(Map<String, Object> params, String prefix) {
bindParams.put(exps.getValue().getFirst(), entry.getValue());
}
}
return ParamSql.of(whereSql, bindParams);
return QueryFragment.of(whereSql, bindParams);
}

/**
Expand Down Expand Up @@ -209,7 +211,7 @@ private static StringBuilder appendIntermediateKeys(String[] joinKeys) {
* or null if no match is found.
*/
private static Map.Entry<String, String> findKeyWord(String inputStr) {
return KEYWORDS.entrySet().stream()
return SQL_OPERATION_MAPPING.entrySet().stream()
.filter(entry -> StringUtils.endsWithIgnoreCase(inputStr, entry.getKey()))
.max((entry1, entry2) -> {
int entry1Length = entry1.getKey().length();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import com.fasterxml.jackson.databind.JsonNode;
import com.plate.boot.commons.utils.BeanUtils;
import com.plate.boot.commons.utils.query.CriteriaUtils;
import com.plate.boot.commons.utils.query.ParamSql;
import com.plate.boot.commons.utils.query.QueryFragment;
import com.plate.boot.commons.utils.query.QueryHelper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
Expand Down Expand Up @@ -42,8 +42,9 @@ public static LoggerRequest of(String tenantCode, String operator, String prefix
public Logger toLogger() {
return BeanUtils.copyProperties(this, Logger.class);
}
public ParamSql bindParamSql() {
return CriteriaUtils.buildParamSql(this, List.of(), null);

public QueryFragment bindParamSql() {
return QueryHelper.buildParamSql(this, List.of(), null);
}
public Criteria toCriteria() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.plate.boot.commons.base.AbstractDatabase;
import com.plate.boot.commons.utils.BeanUtils;
import com.plate.boot.commons.utils.query.CriteriaUtils;
import com.plate.boot.commons.utils.query.QueryHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.data.domain.Page;
Expand All @@ -28,7 +28,7 @@ public class LoggersService extends AbstractDatabase {
public Flux<Logger> search(LoggerRequest request, Pageable pageable) {
String querySql = "select * from se_loggers";
var paramSql = request.bindParamSql();
var query = this.databaseClient.sql(() -> querySql + paramSql.whereSql() + CriteriaUtils.applyPage(pageable))
var query = this.databaseClient.sql(() -> querySql + paramSql.whereSql() + QueryHelper.applyPage(pageable))
.bindValues(paramSql.params())
.map((row, rowMetadata) -> r2dbcConverter.read(Logger.class, row, rowMetadata)).all();
return this.queryWithCache(BeanUtils.cacheKey(request, pageable), query);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.plate.boot.security.core.group;

import com.plate.boot.commons.utils.BeanUtils;
import com.plate.boot.commons.utils.query.CriteriaUtils;
import com.plate.boot.commons.utils.query.ParamSql;
import com.plate.boot.commons.utils.query.QueryFragment;
import com.plate.boot.commons.utils.query.QueryHelper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
Expand Down Expand Up @@ -31,7 +31,7 @@ public Group toGroup() {
return BeanUtils.copyProperties(this, Group.class);
}

public ParamSql bindParamSql() {
return CriteriaUtils.buildParamSql(this, List.of(), null);
public QueryFragment bindParamSql() {
return QueryHelper.buildParamSql(this, List.of(), null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import com.plate.boot.commons.base.AbstractDatabase;
import com.plate.boot.commons.utils.BeanUtils;
import com.plate.boot.commons.utils.query.CriteriaUtils;
import com.plate.boot.commons.utils.query.ParamSql;
import com.plate.boot.commons.utils.query.QueryFragment;
import com.plate.boot.commons.utils.query.QueryHelper;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
Expand All @@ -22,16 +22,16 @@ public class GroupsService extends AbstractDatabase {
private final GroupsRepository groupsRepository;

public Flux<Group> search(GroupRequest request, Pageable pageable) {
ParamSql paramSql = request.bindParamSql();
String query = "select * from se_groups" + paramSql.whereSql() + CriteriaUtils.applyPage(pageable);
return super.queryWithCache(BeanUtils.cacheKey(request, pageable), query, paramSql.params(), Group.class);
QueryFragment QueryFragment = request.bindParamSql();
String query = "select * from se_groups" + QueryFragment.whereSql() + QueryHelper.applyPage(pageable);
return super.queryWithCache(BeanUtils.cacheKey(request, pageable), query, QueryFragment.params(), Group.class);
}

public Mono<Page<Group>> page(GroupRequest request, Pageable pageable) {
var searchMono = this.search(request, pageable).collectList();
ParamSql paramSql = request.bindParamSql();
String query = "select count(*) from se_groups" + paramSql.whereSql();
var countMono = this.countWithCache(BeanUtils.cacheKey(request), query, paramSql.params());
QueryFragment QueryFragment = request.bindParamSql();
String query = "select count(*) from se_groups" + QueryFragment.whereSql();
var countMono = this.countWithCache(BeanUtils.cacheKey(request), query, QueryFragment.params());

return searchMono.zipWith(countMono)
.map(tuple2 -> new PageImpl<>(tuple2.getT1(), pageable, tuple2.getT2()));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.plate.boot.security.core.group.member;

import com.plate.boot.commons.utils.BeanUtils;
import com.plate.boot.commons.utils.query.CriteriaUtils;
import com.plate.boot.commons.utils.query.ParamSql;
import com.plate.boot.commons.utils.query.QueryFragment;
import com.plate.boot.commons.utils.query.QueryHelper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
Expand Down Expand Up @@ -35,11 +35,11 @@ public Criteria toCriteria() {
return criteria(Set.of("users", "username"));
}

public ParamSql toParamSql() {
ParamSql paramSql = CriteriaUtils.buildParamSql(this, List.of("users", "username"), "a");
public QueryFragment toParamSql() {
QueryFragment QueryFragment = QueryHelper.buildParamSql(this, List.of("users", "username"), "a");

StringJoiner criteria = paramSql.sql();
Map<String, Object> params = paramSql.params();
StringJoiner criteria = QueryFragment.sql();
Map<String, Object> params = QueryFragment.params();

if (!ObjectUtils.isEmpty(this.getUsers())) {
criteria.add("a.user_code in :users");
Expand All @@ -51,7 +51,7 @@ public ParamSql toParamSql() {
params.put("username", this.getUsername());
}

return ParamSql.of(criteria, params);
return QueryFragment.of(criteria, params);
}

}
Loading

0 comments on commit 6a25c65

Please sign in to comment.