From b02ba1da5aa2f7d19c306b34f48f3719c35c0cd0 Mon Sep 17 00:00:00 2001 From: Zjp <1215582715@qq.com> Date: Mon, 8 May 2023 18:20:35 +0800 Subject: [PATCH 1/5] update; --- .../tree/hierarchy/HierarchyIterator.java | 2 +- .../tree/hierarchy/HierarchyIteratorImpl.java | 2 +- .../core/tree/hierarchy/HierarchyUtil.java | 8 +- .../tree/hierarchy/HierarchyUtilTest.java | 112 +++++++++--------- 4 files changed, 59 insertions(+), 65 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/tree/hierarchy/HierarchyIterator.java b/hutool-core/src/main/java/org/dromara/hutool/core/tree/hierarchy/HierarchyIterator.java index 0d7b41bad..738f27b54 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/tree/hierarchy/HierarchyIterator.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/tree/hierarchy/HierarchyIterator.java @@ -43,7 +43,7 @@ public interface HierarchyIterator { * * @param result 结果 * @param hierarchy 当前层级 - * @return 向容器中添加元素的方法 + * @return 下一需要遍历的层级 */ Collection nextHierarchies(R result, H hierarchy); diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/tree/hierarchy/HierarchyIteratorImpl.java b/hutool-core/src/main/java/org/dromara/hutool/core/tree/hierarchy/HierarchyIteratorImpl.java index 0362e0e9d..078402dad 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/tree/hierarchy/HierarchyIteratorImpl.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/tree/hierarchy/HierarchyIteratorImpl.java @@ -50,7 +50,7 @@ public class HierarchyIteratorImpl implements HierarchyIterator { * * @param result 结果 * @param hierarchy 当前层级 - * @return 向容器中添加元素的方法 + * @return 下一需要遍历的层级 */ @Override public Collection nextHierarchies(final R result, final H hierarchy) { diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/tree/hierarchy/HierarchyUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/tree/hierarchy/HierarchyUtil.java index 4e3a15561..8472075ad 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/tree/hierarchy/HierarchyUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/tree/hierarchy/HierarchyUtil.java @@ -35,11 +35,11 @@ import java.util.function.Predicate; * Node root = Tree.build(); * // 从树结构中通过深度优先查找某个节点 * Node target = HierarchyUtil.traverseByDepthFirst( - * root, HierarchyUtil.finder(Node::getChildren, node -> Objects.equals(node.getId(), "target") ? node : null) + * root, HierarchyIteratorUtil.find(Node::getChildren, node -> Objects.equals(node.getId(), "target") ? node : null) * ); * // 从树结构中通过广度优先获取其所有的子节点 * List nodes = HierarchyUtil.traverseByBreadthFirst( - * root, HierarchyUtil.collector(Node::getChildren) + * root, HierarchyIteratorUtil.collect(Node::getChildren) * ); * } * @@ -123,17 +123,15 @@ public class HierarchyUtil { Objects.requireNonNull(hierarchyIterator); // 遍历层级结构 - final Predicate hierarchyFilter = filter.negate(); final LinkedList queue = new LinkedList<>(); final Set accessed = new HashSet<>(); queue.add(hierarchy); while (!queue.isEmpty()) { // 跳过已经访问过或者被过滤的层级结构 final H curr = queue.removeFirst(); - if (accessed.contains(curr) || hierarchyFilter.test(curr)) { + if (!accessed.add(curr) || !filter.test(curr)) { continue; } - accessed.add(curr); // 若迭代器返回true,则结束遍历 if (hierarchyIterator.isBreak(curr)) { diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/tree/hierarchy/HierarchyUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/tree/hierarchy/HierarchyUtilTest.java index 262b11f00..2d2e2c2fa 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/tree/hierarchy/HierarchyUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/tree/hierarchy/HierarchyUtilTest.java @@ -12,13 +12,12 @@ package org.dromara.hutool.core.tree.hierarchy; +import lombok.Data; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; /** * test for {@link HierarchyUtil} @@ -27,63 +26,72 @@ import java.util.stream.Collectors; */ class HierarchyUtilTest { - private Map tree; + @Data + static class Node { + private String parent; + private String value; + private List children; + + public Node(String parent, String value) { + this.parent = parent; + this.value = value; + } + } + + private Node root; @BeforeEach void init() { - tree = new LinkedHashMap<>(); - // 根节点 - tree.put("0", null); + root = new Node(null, "0"); - // 第一层 - tree.put("0-1", "0"); - tree.put("0-2", "0"); - tree.put("0-3", "0"); + // 第二层 + Node first1 = new Node(root.value, "0-1"); + Node first2 = new Node(root.value, "0-2"); + Node first3 = new Node(root.value, "0-3"); + root.setChildren(Arrays.asList(first1, first2, first3)); // 第三层 - tree.put("0-1-1", "0-1"); - tree.put("0-1-2", "0-1"); - tree.put("0-1-3", "0-1"); + Node second11 = new Node(first1.value, "0-1-1"); + Node second12 = new Node(first1.value, "0-1-2"); + Node second13 = new Node(first1.value, "0-1-3"); + first1.setChildren(Arrays.asList(second11, second12, second13)); - tree.put("0-2-1", "0-2"); - tree.put("0-2-2", "0-2"); - tree.put("0-2-3", "0-2"); + Node second21 = new Node(first2.value, "0-2-1"); + Node second22 = new Node(first2.value, "0-2-2"); + Node second23 = new Node(first2.value, "0-2-3"); + first2.setChildren(Arrays.asList(second21, second22, second23)); - tree.put("0-3-1", "0-3"); - tree.put("0-3-2", "0-3"); - tree.put("0-3-3", "0-3"); + Node second31 = new Node(first3.value, "0-3-1"); + Node second32 = new Node(first3.value, "0-3-2"); + Node second33 = new Node(first3.value, "0-3-3"); + first3.setChildren(Arrays.asList(second31, second32, second33)); } @Test void testTraverseByBreadthFirst() { - // 按广度优先遍历所有节点 - final Set nodes = new LinkedHashSet<>(); - HierarchyUtil.traverseByBreadthFirst("0", HierarchyIteratorUtil.scan(t -> { - nodes.add(t); - return tree.entrySet().stream() - .filter(e -> Objects.equals(t, e.getValue())) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); + // // 按广度优先遍历所有节点 + final List nodes = new ArrayList<>(); + HierarchyUtil.traverseByBreadthFirst(root, HierarchyIteratorUtil.scan(t -> { + nodes.add(t.getValue()); + return t.getChildren(); })); Assertions.assertEquals(13, nodes.size()); Assertions.assertEquals( - new LinkedHashSet<>(Arrays.asList("0", "0-1", "0-2", "0-3", "0-1-1", "0-1-2", "0-1-3", "0-2-1", "0-2-2", "0-2-3", "0-3-1", "0-3-2", "0-3-3")), - nodes + Arrays.asList("0", "0-1", "0-2", "0-3", "0-1-1", "0-1-2", "0-1-3", "0-2-1", "0-2-2", "0-2-3", "0-3-1", "0-3-2", "0-3-3"), + nodes ); // 按广度优先寻找 0-2-3 - final String target = HierarchyUtil.traverseByBreadthFirst("0", HierarchyIteratorUtil.find(parentFinder(), - t -> Objects.equals(t, "0-2-3") ? t : null + final String target = HierarchyUtil.traverseByBreadthFirst(root, HierarchyIteratorUtil.find(Node::getChildren, + t -> Objects.equals(t.getValue(), "0-2-3") ? t.getValue() : null )); Assertions.assertEquals("0-2-3", target); // 按广度优先获取 0-2 的所有子节点 - final List children = HierarchyUtil.traverseByBreadthFirst( - "0", HierarchyIteratorUtil.collect(parentFinder(), - t -> Objects.equals(tree.get(t), "0-2") ? t : null - ) - ); + final List children = HierarchyUtil.traverseByBreadthFirst(root, HierarchyIteratorUtil.collect(Node::getChildren, + t -> Objects.equals(t.getParent(), "0-2") ? t.getValue() : null + )); Assertions.assertEquals(3, children.size()); Assertions.assertEquals(new ArrayList<>(Arrays.asList("0-2-1", "0-2-2", "0-2-3")), children); } @@ -92,40 +100,28 @@ class HierarchyUtilTest { void testTraverseByDepthFirst() { // 按深度优先遍历所有节点 final Set nodes = new LinkedHashSet<>(); - HierarchyUtil.traverseByDepthFirst("0", HierarchyIteratorUtil.scan(t -> { - nodes.add(t); - return tree.entrySet().stream() - .filter(e -> Objects.equals(t, e.getValue())) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); + HierarchyUtil.traverseByDepthFirst(root, HierarchyIteratorUtil.scan(t -> { + nodes.add(t.getValue()); + return t.getChildren(); })); Assertions.assertEquals(13, nodes.size()); Assertions.assertEquals( - new LinkedHashSet<>(Arrays.asList("0", "0-1", "0-1-1", "0-1-2", "0-1-3", "0-2", "0-2-1", "0-2-2", "0-2-3", "0-3", "0-3-1", "0-3-2", "0-3-3")), - nodes + new LinkedHashSet<>(Arrays.asList("0", "0-1", "0-1-1", "0-1-2", "0-1-3", "0-2", "0-2-1", "0-2-2", "0-2-3", "0-3", "0-3-1", "0-3-2", "0-3-3")), + nodes ); // 按深度优先寻找 0-2-3 - final String target = HierarchyUtil.traverseByDepthFirst("0", HierarchyIteratorUtil.find(parentFinder(), - t -> Objects.equals(t, "0-2-3") ? t : null + final String target = HierarchyUtil.traverseByDepthFirst(root, HierarchyIteratorUtil.find(Node::getChildren, + t -> Objects.equals(t.getValue(), "0-2-3") ? t.getValue() : null )); Assertions.assertEquals("0-2-3", target); // 按深度优先获取 0-2 的所有子节点 - final List children = HierarchyUtil.traverseByDepthFirst( - "0", HierarchyIteratorUtil.collect(parentFinder(), - t -> Objects.equals(tree.get(t), "0-2") ? t : null - ) - ); + final List children = HierarchyUtil.traverseByDepthFirst(root, HierarchyIteratorUtil.collect(Node::getChildren, + t -> Objects.equals(t.getParent(), "0-2") ? t.getValue() : null + )); Assertions.assertEquals(3, children.size()); Assertions.assertEquals(new ArrayList<>(Arrays.asList("0-2-1", "0-2-2", "0-2-3")), children); } - private Function> parentFinder() { - return t -> tree.entrySet() - .stream() - .filter(e -> Objects.equals(t, e.getValue())) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - } } From 17357d29b5b5e689eed67d6766f7b3ab7f3504dc Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 9 May 2023 10:10:37 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E4=BC=98=E5=8C=96count=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E5=85=BC=E5=AE=B9informix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- .../src/main/java/org/dromara/hutool/db/dialect/Dialect.java | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fed88f98..26a9d5409 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 6.0.0.M1 (2023-04-23) +# 6.0.0.M4 (2023-05-09) ### 计划实现 * 【poi 】 Markdown相关(如HTML转换等),基于commonmark-java @@ -14,5 +14,6 @@ ### ❌不兼容特性 ### 🐣新特性 +* 【db 】 优化count查询兼容informix(issue#I713XQ@Gitee) ### 🐞Bug修复 \ No newline at end of file diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/Dialect.java b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/Dialect.java index 4e44f2e90..df8c15c74 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/Dialect.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/Dialect.java @@ -160,8 +160,10 @@ public interface Dialect extends Serializable { * @since 5.7.2 */ default PreparedStatement psForCount(final Connection conn, SqlBuilder sqlBuilder) throws SQLException { + // https://gitee.com/dromara/hutool/issues/I713XQ + // 为了兼容informix等数据库,此处使用count(*)而非count(1) sqlBuilder = sqlBuilder - .insertPreFragment("SELECT count(1) from(") + .insertPreFragment("SELECT count(*) from(") // issue#I3IJ8X@Gitee,在子查询时需设置单独别名,此处为了防止和用户的表名冲突,使用自定义的较长别名 .append(") hutool_alias_count_"); return psForPage(conn, sqlBuilder, null); From 2fd1d5db705efd7d95917190f8a2e2985f9ee9f7 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 9 May 2023 10:13:33 +0800 Subject: [PATCH 3/5] fix test --- .../tree/hierarchy/HierarchyUtilTest.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/tree/hierarchy/HierarchyUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/tree/hierarchy/HierarchyUtilTest.java index 2d2e2c2fa..81dc97ee4 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/tree/hierarchy/HierarchyUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/tree/hierarchy/HierarchyUtilTest.java @@ -32,7 +32,7 @@ class HierarchyUtilTest { private String value; private List children; - public Node(String parent, String value) { + public Node(final String parent, final String value) { this.parent = parent; this.value = value; } @@ -46,25 +46,25 @@ class HierarchyUtilTest { root = new Node(null, "0"); // 第二层 - Node first1 = new Node(root.value, "0-1"); - Node first2 = new Node(root.value, "0-2"); - Node first3 = new Node(root.value, "0-3"); + final Node first1 = new Node(root.value, "0-1"); + final Node first2 = new Node(root.value, "0-2"); + final Node first3 = new Node(root.value, "0-3"); root.setChildren(Arrays.asList(first1, first2, first3)); // 第三层 - Node second11 = new Node(first1.value, "0-1-1"); - Node second12 = new Node(first1.value, "0-1-2"); - Node second13 = new Node(first1.value, "0-1-3"); + final Node second11 = new Node(first1.value, "0-1-1"); + final Node second12 = new Node(first1.value, "0-1-2"); + final Node second13 = new Node(first1.value, "0-1-3"); first1.setChildren(Arrays.asList(second11, second12, second13)); - Node second21 = new Node(first2.value, "0-2-1"); - Node second22 = new Node(first2.value, "0-2-2"); - Node second23 = new Node(first2.value, "0-2-3"); + final Node second21 = new Node(first2.value, "0-2-1"); + final Node second22 = new Node(first2.value, "0-2-2"); + final Node second23 = new Node(first2.value, "0-2-3"); first2.setChildren(Arrays.asList(second21, second22, second23)); - Node second31 = new Node(first3.value, "0-3-1"); - Node second32 = new Node(first3.value, "0-3-2"); - Node second33 = new Node(first3.value, "0-3-3"); + final Node second31 = new Node(first3.value, "0-3-1"); + final Node second32 = new Node(first3.value, "0-3-2"); + final Node second33 = new Node(first3.value, "0-3-3"); first3.setChildren(Arrays.asList(second31, second32, second33)); } From 9dadfed42ee8d5bf8da7c29c816e0713ec0da624 Mon Sep 17 00:00:00 2001 From: handy Date: Tue, 9 May 2023 13:48:56 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E8=B0=83=E6=95=B4=E9=94=81=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=E5=92=8C=20=E4=B8=8D=E5=BF=85=E8=A6=81=E7=9A=84int?= =?UTF-8?q?=E6=8B=86=E7=AE=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/cache/impl/ReentrantCache.java | 2 +- .../java/org/dromara/hutool/core/net/Ipv4Util.java | 2 +- .../hutool/crypto/symmetric/SymmetricCrypto.java | 11 ++++------- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/ReentrantCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/ReentrantCache.java index 4886c4964..3c9b01b60 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/ReentrantCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/ReentrantCache.java @@ -144,8 +144,8 @@ public abstract class ReentrantCache extends AbstractCache { * @param withMissCount 是否计数丢失数 */ private void remove(final K key, final boolean withMissCount) { - lock.lock(); CacheObj co; + lock.lock(); try { co = removeWithoutLock(key, withMissCount); } finally { diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/net/Ipv4Util.java b/hutool-core/src/main/java/org/dromara/hutool/core/net/Ipv4Util.java index 07ba4cf78..f05ea3965 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/net/Ipv4Util.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/net/Ipv4Util.java @@ -365,7 +365,7 @@ public class Ipv4Util implements Ipv4Pool { * @return 掩码位,例如 24 * @throws IllegalArgumentException 子网掩码非法 */ - public static int getMaskBitByMask(final String mask) { + public static Integer getMaskBitByMask(final String mask) { final Integer maskBit = MaskBit.getMaskBit(mask); Assert.notNull(maskBit, "Invalid netmask:{}", mask); return maskBit; diff --git a/hutool-crypto/src/main/java/org/dromara/hutool/crypto/symmetric/SymmetricCrypto.java b/hutool-crypto/src/main/java/org/dromara/hutool/crypto/symmetric/SymmetricCrypto.java index a71829dcb..4f843f933 100644 --- a/hutool-crypto/src/main/java/org/dromara/hutool/crypto/symmetric/SymmetricCrypto.java +++ b/hutool-crypto/src/main/java/org/dromara/hutool/crypto/symmetric/SymmetricCrypto.java @@ -302,9 +302,8 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor, * @since 6.0.0 */ public byte[] encrypt(final byte[] data, final byte[] salt) { - lock.lock(); - byte[] result; + lock.lock(); try { final Cipher cipher = initMode(Cipher.ENCRYPT_MODE, salt); result = cipher.doFinal(paddingDataWithZero(data, cipher.getBlockSize())); @@ -318,9 +317,8 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor, @Override public void encrypt(final InputStream data, final OutputStream out, final boolean isClose) throws IORuntimeException { - lock.lock(); - CipherOutputStream cipherOutputStream = null; + lock.lock(); try { final Cipher cipher = initMode(Cipher.ENCRYPT_MODE, null); cipherOutputStream = new CipherOutputStream(out, cipher); @@ -358,10 +356,9 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor, public byte[] decrypt(final byte[] bytes) { final int blockSize; final byte[] decryptData; - lock.lock(); - final byte[] salt = SaltMagic.getSalt(bytes); try { + final byte[] salt = SaltMagic.getSalt(bytes); final Cipher cipher = initMode(Cipher.DECRYPT_MODE, salt); blockSize = cipher.getBlockSize(); decryptData = cipher.doFinal(SaltMagic.getData(bytes)); @@ -376,8 +373,8 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor, @Override public void decrypt(final InputStream data, final OutputStream out, final boolean isClose) throws IORuntimeException { - lock.lock(); CipherInputStream cipherInputStream = null; + lock.lock(); try { final Cipher cipher = initMode(Cipher.DECRYPT_MODE, null); cipherInputStream = new CipherInputStream(data, cipher); From 9b0f9f43cd22be5216bd5c626749850950c034f6 Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 10 May 2023 12:28:19 +0800 Subject: [PATCH 5/5] fix code --- .../src/main/java/org/dromara/hutool/core/net/Ipv4Util.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/net/Ipv4Util.java b/hutool-core/src/main/java/org/dromara/hutool/core/net/Ipv4Util.java index f05ea3965..07ba4cf78 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/net/Ipv4Util.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/net/Ipv4Util.java @@ -365,7 +365,7 @@ public class Ipv4Util implements Ipv4Pool { * @return 掩码位,例如 24 * @throws IllegalArgumentException 子网掩码非法 */ - public static Integer getMaskBitByMask(final String mask) { + public static int getMaskBitByMask(final String mask) { final Integer maskBit = MaskBit.getMaskBit(mask); Assert.notNull(maskBit, "Invalid netmask:{}", mask); return maskBit;