Browse Source

Merge branch '3.0.x' of https://github.com/hs-web/hsweb-framework into 3.0.x

Jia_RG 5 years ago
parent
commit
15ce83b684

+ 10 - 10
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/EasyOrmSqlBuilder.java

@@ -106,11 +106,11 @@ public class EasyOrmSqlBuilder {
         return javaType;
         return javaType;
     }
     }
 
 
-    private final RDBDatabaseMetaData mysql = new MysqlMeta();
-    private final RDBDatabaseMetaData oracle = new OracleMeta();
-    private final RDBDatabaseMetaData h2 = new H2Meta();
-    private final RDBDatabaseMetaData postgresql = new PGMeta();
-    private final RDBDatabaseMetaData mssql = new MSSQLMeta();
+    public static final RDBDatabaseMetaData mysql = new MysqlMeta();
+    public static final RDBDatabaseMetaData oracle = new OracleMeta();
+    public static final RDBDatabaseMetaData h2 = new H2Meta();
+    public static final RDBDatabaseMetaData postgresql = new PGMeta();
+    public static final RDBDatabaseMetaData mssql = new MSSQLMeta();
 
 
     private final ConcurrentMap<RDBDatabaseMetaData, Map<String, RDBTableMetaData>> metaCache = new ConcurrentHashMap<>();
     private final ConcurrentMap<RDBDatabaseMetaData, Map<String, RDBTableMetaData>> metaCache = new ConcurrentHashMap<>();
 
 
@@ -427,7 +427,7 @@ public class EasyOrmSqlBuilder {
         return appender.toString();
         return appender.toString();
     }
     }
 
 
-    class MysqlMeta extends MysqlRDBDatabaseMetaData {
+    static class MysqlMeta extends MysqlRDBDatabaseMetaData {
         MysqlMeta() {
         MysqlMeta() {
             super();
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
@@ -440,7 +440,7 @@ public class EasyOrmSqlBuilder {
         }
         }
     }
     }
 
 
-    class OracleMeta extends OracleRDBDatabaseMetaData {
+    static class OracleMeta extends OracleRDBDatabaseMetaData {
         OracleMeta() {
         OracleMeta() {
             super();
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
@@ -453,7 +453,7 @@ public class EasyOrmSqlBuilder {
         }
         }
     }
     }
 
 
-    class H2Meta extends H2RDBDatabaseMetaData {
+    static class H2Meta extends H2RDBDatabaseMetaData {
         H2Meta() {
         H2Meta() {
             super();
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
@@ -466,7 +466,7 @@ public class EasyOrmSqlBuilder {
         }
         }
     }
     }
 
 
-    class PGMeta extends PGRDBDatabaseMetaData {
+    static class PGMeta extends PGRDBDatabaseMetaData {
         PGMeta() {
         PGMeta() {
             super();
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
@@ -479,7 +479,7 @@ public class EasyOrmSqlBuilder {
         }
         }
     }
     }
 
 
-    class MSSQLMeta extends MSSQLRDBDatabaseMetaData {
+    static class MSSQLMeta extends MSSQLRDBDatabaseMetaData {
         MSSQLMeta() {
         MSSQLMeta() {
             super();
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());

+ 3 - 2
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/TreeStructureSqlTermCustomizer.java

@@ -19,13 +19,14 @@ import java.util.stream.Collectors;
  */
  */
 @Slf4j
 @Slf4j
 public abstract class TreeStructureSqlTermCustomizer extends AbstractSqlTermCustomizer {
 public abstract class TreeStructureSqlTermCustomizer extends AbstractSqlTermCustomizer {
-    boolean not = false;
+    protected boolean not;
 
 
-    boolean parent = false;
+    protected boolean parent;
 
 
     public TreeStructureSqlTermCustomizer(String termType, boolean not, boolean parent) {
     public TreeStructureSqlTermCustomizer(String termType, boolean not, boolean parent) {
         super(termType);
         super(termType);
         this.not = not;
         this.not = not;
+        this.parent = parent;
     }
     }
 
 
     protected abstract String getTableName();
     protected abstract String getTableName();

+ 87 - 51
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/TreeSupportEntity.java

@@ -19,15 +19,16 @@
 package org.hswebframework.web.commons.entity;
 package org.hswebframework.web.commons.entity;
 
 
 
 
-import org.hswebframework.web.id.IDGenerator;
 import org.hswebframework.utils.RandomUtil;
 import org.hswebframework.utils.RandomUtil;
+import org.hswebframework.web.id.IDGenerator;
+import org.springframework.util.CollectionUtils;
 
 
-import java.math.BigDecimal;
 import java.util.*;
 import java.util.*;
 import java.util.function.*;
 import java.util.function.*;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.stream.Stream;
 
 
+@SuppressWarnings("all")
 public interface TreeSupportEntity<PK> extends GenericEntity<PK> {
 public interface TreeSupportEntity<PK> extends GenericEntity<PK> {
 
 
     String id = "id";
     String id = "id";
@@ -64,68 +65,103 @@ public interface TreeSupportEntity<PK> extends GenericEntity<PK> {
     }
     }
 
 
     static <T extends TreeSupportEntity> void forEach(Collection<T> list, Consumer<T> consumer) {
     static <T extends TreeSupportEntity> void forEach(Collection<T> list, Consumer<T> consumer) {
-        list.forEach(node -> {
+        Queue<T> queue = new LinkedList<>(list);
+        Set<Long> all = new HashSet<>();
+        for (T node = queue.poll(); node != null; node = queue.poll()) {
+            long hash = System.identityHashCode(node);
+            if (all.contains(hash)) {
+                continue;
+            }
+            all.add(hash);
             consumer.accept(node);
             consumer.accept(node);
-            if (node.getChildren() != null) {
-                forEach(node.getChildren(), consumer);
+            if (!CollectionUtils.isEmpty(node.getChildren())) {
+                queue.addAll(node.getChildren());
             }
             }
-        });
+        }
     }
     }
 
 
     static <T extends TreeSupportEntity<PK>, PK> void expandTree2List(T parent, List<T> target, IDGenerator<PK> idGenerator) {
     static <T extends TreeSupportEntity<PK>, PK> void expandTree2List(T parent, List<T> target, IDGenerator<PK> idGenerator) {
-        expandTree2List(parent,target,idGenerator,null);
+        expandTree2List(parent, target, idGenerator, null);
     }
     }
-        /**
-         * 将树形结构转为列表结构,并填充对应的数据。<br>
-         * 如树结构数据: {name:'父节点',children:[{name:'子节点1'},{name:'子节点2'}]}<br>
-         * 解析后:[{id:'id1',name:'父节点',path:'<b>aoSt</b>'},{id:'id2',name:'子节点1',path:'<b>aoSt</b>-oS5a'},{id:'id3',name:'子节点2',path:'<b>aoSt</b>-uGpM'}]
-         *
-         * @param parent      树结构的根节点
-         * @param target      目标集合,转换后的数据将直接添加({@link List#add(Object)})到这个集合.
-         * @param <T>         继承{@link TreeSupportEntity}的类型
-         * @param idGenerator ID生成策略
-         * @param <PK>        主键类型
-         */
-    static <T extends TreeSupportEntity<PK>, PK> void expandTree2List(T parent, List<T> target, IDGenerator<PK> idGenerator, BiConsumer<T, List<T>> childConsumer) {
 
 
-        List<T> children = parent.getChildren();
-        if(childConsumer!=null){
-            childConsumer.accept(parent,new ArrayList<>());
+
+    /**
+     * 将树形结构转为列表结构,并填充对应的数据。<br>
+     * 如树结构数据: {name:'父节点',children:[{name:'子节点1'},{name:'子节点2'}]}<br>
+     * 解析后:[{id:'id1',name:'父节点',path:'<b>aoSt</b>'},{id:'id2',name:'子节点1',path:'<b>aoSt</b>-oS5a'},{id:'id3',name:'子节点2',path:'<b>aoSt</b>-uGpM'}]
+     *
+     * @param root        树结构的根节点
+     * @param target      目标集合,转换后的数据将直接添加({@link List#add(Object)})到这个集合.
+     * @param <T>         继承{@link TreeSupportEntity}的类型
+     * @param idGenerator ID生成策略
+     * @param <PK>        主键类型
+     */
+    static <T extends TreeSupportEntity<PK>, PK> void expandTree2List(T root, List<T> target, IDGenerator<PK> idGenerator, BiConsumer<T, List<T>> childConsumer) {
+
+        if (CollectionUtils.isEmpty(root.getChildren())) {
+            target.add(root);
+            return;
         }
         }
-        target.add(parent);
-        if (parent.getPath() == null) {
-            parent.setPath(RandomUtil.randomChar(4));
-            if (parent.getPath() != null) {
-                parent.setLevel(parent.getPath().split("-").length);
-            }
-            if (parent instanceof SortSupportEntity) {
-                Long index = ((SortSupportEntity) parent).getSortIndex();
-                if (null == index) {
-                    ((SortSupportEntity) parent).setSortIndex(1L);
-                }
+
+        //尝试设置id
+        PK parentId = root.getId();
+        if (parentId == null) {
+            parentId = idGenerator.generate();
+            root.setId(parentId);
+        }
+        //尝试设置树路径path
+        if (root.getPath() == null) {
+            root.setPath(RandomUtil.randomChar(4));
+        }
+        if (root.getPath() != null) {
+            root.setLevel(root.getPath().split("[-]").length);
+        }
+        //尝试设置排序
+        if (root instanceof SortSupportEntity) {
+            SortSupportEntity sortableRoot = ((SortSupportEntity) root);
+            Long index = sortableRoot.getSortIndex();
+            if (null == index) {
+                sortableRoot.setSortIndex(1L);
             }
             }
         }
         }
-        if (children != null) {
-            PK pid = parent.getId();
-            if (pid == null) {
-                pid = idGenerator.generate();
-                parent.setId(pid);
+
+        //所有节点处理队列
+        Queue<T> queue = new LinkedList<>();
+        queue.add(root);
+        //已经处理过的节点过滤器
+        Set<Long> filter = new HashSet<>();
+
+        for (T parent = queue.poll(); parent != null; parent = queue.poll()) {
+            long hash = System.identityHashCode(parent);
+            if (filter.contains(hash)) {
+                continue;
             }
             }
-            for (int i = 0; i < children.size(); i++) {
-                T child = children.get(i);
-                if (child instanceof SortSupportEntity && parent instanceof SortSupportEntity) {
-                    Long index = ((SortSupportEntity) parent).getSortIndex();
-                    if (null == index) {
-                        ((SortSupportEntity) parent).setSortIndex(index = 1L);
+            filter.add(hash);
+
+            //处理子节点
+            if (!CollectionUtils.isEmpty(parent.getChildren())) {
+                long index = 1;
+                for (TreeSupportEntity<PK> child : parent.getChildren()) {
+                    if (child.getId() == null) {
+                        child.setId(idGenerator.generate());
                     }
                     }
-                    ((SortSupportEntity) child).setSortIndex(new BigDecimal(index + "0" + (i + 1)).longValue());
+                    child.setParentId(parent.getId());
+                    child.setPath(parent.getPath() + "-" + RandomUtil.randomChar(4));
+                    child.setLevel(child.getPath().split("[-]").length);
+
+                    //子节点排序
+                    if (child instanceof SortSupportEntity && parent instanceof SortSupportEntity) {
+                        SortSupportEntity sortableParent = ((SortSupportEntity) parent);
+                        SortSupportEntity sortableChild = ((SortSupportEntity) child);
+                        sortableChild.setSortIndex(sortableParent.getSortIndex() * 100 + index++);
+                    }
+                    queue.add((T) child);
                 }
                 }
-                child.setParentId(pid);
-                child.setPath(parent.getPath() + "-" + RandomUtil.randomChar(4));
-                child.setLevel(child.getPath().split("-").length);
-
-                expandTree2List(child, target, idGenerator,childConsumer);
             }
             }
+            if (childConsumer != null) {
+                childConsumer.accept(parent, new ArrayList<>());
+            }
+            target.add(parent);
         }
         }
     }
     }
 
 
@@ -165,7 +201,7 @@ public interface TreeSupportEntity<PK> extends GenericEntity<PK> {
         Objects.requireNonNull(childConsumer, "child consumer can not be null");
         Objects.requireNonNull(childConsumer, "child consumer can not be null");
         Objects.requireNonNull(predicateFunction, "root predicate function can not be null");
         Objects.requireNonNull(predicateFunction, "root predicate function can not be null");
 
 
-        Supplier<Stream<N>> streamSupplier = () -> dataList.size() < 1000 ? dataList.stream() : dataList.parallelStream();
+        Supplier<Stream<N>> streamSupplier = () -> dataList.size() < 50000 ? dataList.stream() : dataList.parallelStream();
         // id,node
         // id,node
         Map<PK, N> cache = new HashMap<>();
         Map<PK, N> cache = new HashMap<>();
         // parentId,children
         // parentId,children

+ 8 - 3
hsweb-commons/hsweb-commons-entity/src/test/java/org/hswebframework/web/commons/entity/TreeSupportEntityTests.java

@@ -2,19 +2,18 @@ package org.hswebframework.web.commons.entity;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.alibaba.fastjson.serializer.SerializerFeature;
-import org.hswebframework.web.id.IDGenerator;
 import org.junit.Assert;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.Test;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.List;
 import java.util.List;
+import java.util.concurrent.atomic.LongAdder;
 import java.util.function.Predicate;
 import java.util.function.Predicate;
 
 
-import static org.junit.Assert.*;
-
 public class TreeSupportEntityTests {
 public class TreeSupportEntityTests {
 
 
+
     @Test
     @Test
     public void test() {
     public void test() {
         MenuEntity parent = MenuEntity.builder().build();
         MenuEntity parent = MenuEntity.builder().build();
@@ -48,6 +47,12 @@ public class TreeSupportEntityTests {
 
 
         System.out.println(JSON.toJSONString(tree, SerializerFeature.PrettyFormat));
         System.out.println(JSON.toJSONString(tree, SerializerFeature.PrettyFormat));
 
 
+        LongAdder adder=new LongAdder();
+        TreeSupportEntity.forEach(tree,menu->{
+            adder.increment();
+        });
+        Assert.assertEquals(adder.intValue(),4);
+
         List<MenuEntity> list = new ArrayList<>();
         List<MenuEntity> list = new ArrayList<>();
 
 
         //将树形结构展平为list
         //将树形结构展平为list

+ 11 - 0
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/SystemInitializeAutoConfiguration.java

@@ -30,6 +30,7 @@ import org.hswebframework.web.ScriptScope;
 import org.hswebframework.web.datasource.DataSourceHolder;
 import org.hswebframework.web.datasource.DataSourceHolder;
 import org.hswebframework.web.datasource.DatabaseType;
 import org.hswebframework.web.datasource.DatabaseType;
 import org.hswebframework.web.service.Service;
 import org.hswebframework.web.service.Service;
+import org.hswebframework.web.starter.event.SystemInitializeEvent;
 import org.hswebframework.web.starter.init.SystemInitialize;
 import org.hswebframework.web.starter.init.SystemInitialize;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -37,6 +38,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.Ordered;
 import org.springframework.core.Ordered;
 import org.springframework.core.annotation.AnnotationUtils;
 import org.springframework.core.annotation.AnnotationUtils;
@@ -75,6 +77,9 @@ public class SystemInitializeAutoConfiguration implements CommandLineRunner, Bea
     @Autowired
     @Autowired
     private ApplicationContext applicationContext;
     private ApplicationContext applicationContext;
 
 
+    @Autowired
+    private ApplicationEventPublisher eventPublisher;
+
     private List<DynamicScriptEngine> engines;
     private List<DynamicScriptEngine> engines;
 
 
     @Autowired
     @Autowired
@@ -158,6 +163,12 @@ public class SystemInitializeAutoConfiguration implements CommandLineRunner, Bea
 
 
         SimpleDatabase database = new SimpleDatabase(metaData, sqlExecutor);
         SimpleDatabase database = new SimpleDatabase(metaData, sqlExecutor);
         database.setAutoParse(true);
         database.setAutoParse(true);
+
+        SystemInitializeEvent event = new SystemInitializeEvent(database);
+        eventPublisher.publishEvent(event);
+        if (event.isIgnore()) {
+            return;
+        }
         SystemInitialize initialize = new SystemInitialize(sqlExecutor, database, version);
         SystemInitialize initialize = new SystemInitialize(sqlExecutor, database, version);
 
 
         initialize.addScriptContext("db", jdbcUserName);
         initialize.addScriptContext("db", jdbcUserName);

+ 21 - 0
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/event/SystemInitializeEvent.java

@@ -0,0 +1,21 @@
+package org.hswebframework.web.starter.event;
+
+import lombok.Getter;
+import org.hswebframework.ezorm.rdb.RDBDatabase;
+
+@Getter
+public class SystemInitializeEvent {
+
+    public SystemInitializeEvent(RDBDatabase database){
+        this.database=database;
+    }
+
+    private RDBDatabase database;
+
+    private boolean ignore;
+
+    public void setIgnore(boolean ignore) {
+        this.ignore = ignore;
+    }
+
+}