当前位置: 首页 > news >正文

广州 做网站回忆网站模板

广州 做网站,回忆网站模板,济南建站方案,安徽省工程建设信息网网站场景:把复杂的 CommonCondition 条件树以 JSON 形式存入 PostgreSQL,并要求:子条件顺序、valueList 重复值、展示用字段(如别名)不影响“相同业务逻辑”的判定。本文给出一条 Java → PostgreSQL 的端到端可复制方案。…

场景:把复杂的 CommonCondition 条件树以 JSON 形式存入 PostgreSQL,并要求:

  • 子条件顺序、

  • valueList 重复值、

  • 展示用字段(如别名)
    不影响“相同业务逻辑”的判定。
    本文给出一条 Java → PostgreSQL 的端到端可复制方案。


1. 数据库层设计(PostgreSQL)

CREATE TABLE report_condition (id        bigserial PRIMARY KEY,condition jsonb        NOT NULL,signature char(64)     NOT NULL,   -- SHA-256 长度created_at timestamptz DEFAULT now()
);-- 查询时直接按 signature 去重
CREATE UNIQUE INDEX uk_signature ON report_condition(signature);

触发器可选:如果希望完全由 DB 计算签名,可用 plpython3u 调用 Python 归一化脚本;
下文演示 Java 端计算签名后写入,逻辑更清晰。


2. Java 端核心实现

2.1 枚举:白名单字段规则

package com.example.condition;import java.util.List;/** 不同业务场景下保留的字段集合 */
public enum ConditionNormalizeRule {DEFAULT(List.of("table","field","fieldType","type","logicalOperator","operator","valueList","commonConditions")),REPORT (List.of("table","field","type","operator","valueList","commonConditions")), // 去掉 fieldTypeAUDIT  (List.of("table","field","fieldType","type","operator","valueList","commonConditions"));private final List<String> whiteList;ConditionNormalizeRule(List<String> whiteList) { this.whiteList = whiteList; }public List<String> getWhiteList() { return whiteList; }
}

2.2 工具类 ConditionHash

package com.example.condition;import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import org.apache.commons.codec.digest.DigestUtils;import java.util.*;
import java.util.stream.Collectors;public final class ConditionHash {/** 全局 ObjectMapper,线程安全 */private static final ObjectMapper MAPPER = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL) // 忽略 null.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true); // 键排序/*** 计算业务等价哈希* @param root  待计算的 CommonCondition 树* @param rule  决定保留哪些字段的枚举* @return      SHA-256 十六进制字符串(64 位)*/public static String sha256(CommonCondition root, ConditionNormalizeRule rule) {try {JsonNode tree = normalize(MAPPER.valueToTree(root), rule);byte[] bytes  = MAPPER.writeValueAsBytes(tree);return DigestUtils.sha256Hex(bytes);} catch (Exception e) {throw new IllegalStateException("compute hash failed", e);}}/* ---------- 私有归一化逻辑 ---------- *//** 递归归一化:保留白名单字段 + 去重排序 */private static JsonNode normalize(JsonNode node, ConditionNormalizeRule rule) {if (node == null || !node.isObject()) return node;ObjectNode obj = MAPPER.createObjectNode();List<String> white = rule.getWhiteList();white.forEach(key -> {if (node.has(key)) {JsonNode val = node.get(key);switch (key) {case "valueList":obj.set(key, normalizeValueList(val));         // 去重+排序break;case "commonConditions":obj.set(key, normalizeChildren(val, rule));    // 递归+排序break;default:obj.set(key, val);                             // 直接保留}}});return obj;}/** valueList 去重+字典序排序 */private static JsonNode normalizeValueList(JsonNode listNode) {if (listNode == null || !listNode.isArray()) return MAPPER.createArrayNode();List<String> list = MAPPER.convertValue(listNode, new TypeReference<>() {});list = list.stream().distinct().sorted().collect(Collectors.toList());return MAPPER.valueToTree(list);}/** commonConditions 递归归一化后按字符串排序 */private static JsonNode normalizeChildren(JsonNode childrenNode, ConditionNormalizeRule rule) {if (childrenNode == null || !childrenNode.isArray()) return MAPPER.createArrayNode();List<CommonCondition> children = MAPPER.convertValue(childrenNode, new TypeReference<>() {});List<JsonNode> sorted = children.stream().map(c -> normalize(MAPPER.valueToTree(c), rule)).sorted(Comparator.comparing(JsonNode::toString)) // 稳定排序.collect(Collectors.toList());return MAPPER.valueToTree(sorted);}private ConditionHash() {}
}

3. 使用示例

3.1 构造两个“业务等价”的对象

CommonCondition condA = CommonCondition.builder().type("logical").logicalOperator("AND").commonConditions(List.of(CommonCondition.builder().type("base").table("user").field("age").operator("GT").valueList(List.of("18", "18", "20"))  // 重复值.build(),CommonCondition.builder().type("base").table("user").field("status").operator("IN").valueList(List.of("ACTIVE", "LOCKED")).build())).build();/* 把子条件顺序颠倒,再加一个别名字段,但业务含义不变 */
CommonCondition condB = CommonCondition.builder().type("logical").logicalOperator("AND").tableNameAlias("u")            // 展示用,不参与哈希.commonConditions(List.of(CommonCondition.builder().type("base").table("user").field("status").operator("IN").valueList(List.of("LOCKED", "ACTIVE", "ACTIVE")) // 重复+乱序.build(),CommonCondition.builder().type("base").table("user").field("age").operator("GT").valueList(List.of("20", "18"))   // 乱序.build())).build();

3.2 计算哈希并判重

String sigA = ConditionHash.sha256(condA, ConditionNormalizeRule.DEFAULT);
String sigB = ConditionHash.sha256(condB, ConditionNormalizeRule.DEFAULT);System.out.println("sigA = " + sigA);
System.out.println("sigB = " + sigB);
System.out.println("same = " + sigA.equals(sigB));   // true

3.3 插入 PostgreSQL

String sql = """INSERT INTO report_condition(condition, signature)VALUES (?::jsonb, ?)ON CONFLICT (signature) DO NOTHING""";
try (PreparedStatement ps = conn.prepareStatement(sql)) {ps.setString(1, new ObjectMapper().writeValueAsString(condA));ps.setString(2, sigA);ps.executeUpdate();
}

ON CONFLICT (signature) DO NOTHING 利用唯一索引实现幂等写入,天然判重。


4. 性能 & 扩展

子条件规模耗时(MacBook M2)建议
< 100< 1 ms无需优化
100~1 0001~8 ms缓存哈希
> 1 000> 10 ms并行流 + 缓存

缓存示例(Lombok):

@Getter(lazy = true)
private final String hash = ConditionHash.sha256(this, ConditionNormalizeRule.DEFAULT);

5. 小结

  1. 数据库:JSONB + 唯一索引 signature,一行 SQL 完成判重。

  2. JavaConditionHash.sha256(root, rule) 统一出口,顺序、重复、别名全部抹平。

  3. 枚举:新增业务场景只需再加一个 ConditionNormalizeRule 值,零侵入。

http://www.dtcms.com/a/397746.html

相关文章:

  • 网站备案 英文该网站无备案
  • 国外网站关键词免费线上培训平台
  • 汕头住房和城乡建设厅网站购物网站怎么经营
  • 网站建设资料百度云公司网站后台上传不了图片
  • 跨境电商开店安徽网站建设SEO优化制作设计公司
  • 有没有帮别人做创意的网站在线学习网站开发
  • 音乐自助建站龙岩到永定汽车时刻表
  • 网站建设佰金手指科杰十八活动软文怎么写
  • 做网站起什么名字比较好优惠券推广网站怎么做
  • wordpress网站用户注册深汕特别合作区属于深圳吗
  • 云南省住房和城乡建设厅网站首页网站注册需要多少钱
  • 安卓网站开发前景优化设计
  • 用旧手机做网站服务器wordpress带轮播企业站主题
  • 软件网站建设基本流程品牌设计包括哪些内容
  • 企业开发网站建设html网页制作用什么语言
  • 廊坊手机网站制作百度竞价推广有哪些优势
  • 青岛网站seo国家网站集约化建设试点方案
  • 网站建设经营服务合同买好域名后怎么做网站
  • 个人博客网站下载做eso哪家网站好
  • 织梦网站做图床网站后台需要多少
  • 做网站自己公司车辆管理系统软件
  • 枣阳建网站cf租号网站怎么做的
  • 如何通过网站获取qqphpcms手机网站模板
  • 在线营销网站建设电子商务网站推广的主要方式
  • pc手机一体网站企业培训机构网站源码
  • 网站开发属于什么职位类别wordpress首页主标题移到后面
  • 建设银行粤通卡网站亚马逊雨林在地图上的位置
  • 企业网站建设的误区主要有棋牌网站建设源码
  • 专业的集团网站建设科技公司php网站模版
  • 广州网站制作系统wordpress路径增加discuz