From 559be98b29d5c9a02414996ff9b8a561e31dfe5f Mon Sep 17 00:00:00 2001 From: lihongjie0209 Date: Sun, 17 Mar 2024 12:46:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=A0=91=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coal/department/dto/DepartmentDto.java | 2 + .../department/dto/DepartmentTreeDto.java | 1 + .../department/entity/DepartmentEntity.java | 3 + .../spring/config/MyPostgreSQLDialect.java | 8 ++ .../resources/db/migration/V33__functions.sql | 97 +++++++++++++++++++ 5 files changed, 111 insertions(+) create mode 100644 src/main/resources/db/migration/V33__functions.sql diff --git a/src/main/java/cn/lihongjie/coal/department/dto/DepartmentDto.java b/src/main/java/cn/lihongjie/coal/department/dto/DepartmentDto.java index 9c1906af..d409df83 100644 --- a/src/main/java/cn/lihongjie/coal/department/dto/DepartmentDto.java +++ b/src/main/java/cn/lihongjie/coal/department/dto/DepartmentDto.java @@ -7,4 +7,6 @@ import lombok.Data; @Data public class DepartmentDto extends OrgCommonDto { private String parent; + + private Integer empCount; } diff --git a/src/main/java/cn/lihongjie/coal/department/dto/DepartmentTreeDto.java b/src/main/java/cn/lihongjie/coal/department/dto/DepartmentTreeDto.java index 2e1ef22f..858d2596 100644 --- a/src/main/java/cn/lihongjie/coal/department/dto/DepartmentTreeDto.java +++ b/src/main/java/cn/lihongjie/coal/department/dto/DepartmentTreeDto.java @@ -8,6 +8,7 @@ import java.util.List; @Data public class DepartmentTreeDto extends OrgCommonDto { + private Integer empCount; private String parent; private List children; } diff --git a/src/main/java/cn/lihongjie/coal/department/entity/DepartmentEntity.java b/src/main/java/cn/lihongjie/coal/department/entity/DepartmentEntity.java index b9b1e2e9..582f4c7d 100644 --- a/src/main/java/cn/lihongjie/coal/department/entity/DepartmentEntity.java +++ b/src/main/java/cn/lihongjie/coal/department/entity/DepartmentEntity.java @@ -11,6 +11,7 @@ import lombok.Getter; import lombok.Setter; import org.hibernate.annotations.Comment; +import org.hibernate.annotations.Formula; import java.util.List; @@ -20,6 +21,8 @@ import java.util.List; @Setter public class DepartmentEntity extends OrgCommonEntity { + @Formula("(select count(*) from t_employee e where e.department_id = any(self_and_children_ids('t_department', id)))") + private Integer empCount; @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL) private List children; diff --git a/src/main/java/cn/lihongjie/coal/spring/config/MyPostgreSQLDialect.java b/src/main/java/cn/lihongjie/coal/spring/config/MyPostgreSQLDialect.java index 7813e6e1..ddfe37a3 100644 --- a/src/main/java/cn/lihongjie/coal/spring/config/MyPostgreSQLDialect.java +++ b/src/main/java/cn/lihongjie/coal/spring/config/MyPostgreSQLDialect.java @@ -3,6 +3,7 @@ package cn.lihongjie.coal.spring.config; import cn.lihongjie.coal.annotation.HyperTable; import org.hibernate.boot.Metadata; +import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.dialect.PostgreSQLDialect; import org.hibernate.mapping.PersistentClass; @@ -16,6 +17,13 @@ import java.util.stream.Collectors; public class MyPostgreSQLDialect extends PostgreSQLDialect { + @Override + public void initializeFunctionRegistry(FunctionContributions functionContributions) { + super.initializeFunctionRegistry(functionContributions); + functionContributions.getFunctionRegistry().registerNamed("self_and_children_ids"); + functionContributions.getFunctionRegistry().registerNamed("self_and_parent_ids"); + } + @Override protected String columnType(int sqlTypeCode) { if (sqlTypeCode == SqlTypes.VARCHAR) { diff --git a/src/main/resources/db/migration/V33__functions.sql b/src/main/resources/db/migration/V33__functions.sql new file mode 100644 index 00000000..3fc76571 --- /dev/null +++ b/src/main/resources/db/migration/V33__functions.sql @@ -0,0 +1,97 @@ + +drop function if exists selfAndChildrenIds; +drop function if exists selfAndParentIds; + +create or replace function self_and_children_ids(tb text, id text, includeSelf bool = true) returns text[] AS +$$ + +declare + + ans text[]; + sql text; + text1 text; +begin + -- logic + + if includeSelf then + text1 = 'id' ; + else + text1 = 'parent_id' ; + end if; + + sql = 'with recursive tmp as (select id + from ' || + tb || + ' + where ' || + text1 || + ' = $1 + union all + select ' || + tb || + '.id + from ' || + tb || + ' + inner join tmp on ' || + tb || + '.parent_id = tmp.id) + +select array_agg(id) +from tmp'; + + execute sql into ans using id; + + + return ans; +end +$$ language plpgsql +; + + + +create or replace function self_and_parent_ids(tb text, id text, includeSelf bool = true) returns text[] AS +$$ + +declare + + ans text[]; + sql text; +begin + -- logic + + + + sql = 'with recursive tmp as (select id,parent_id + from ' || + tb || + ' + where ' || + + 'id = $1 + union all + select ' || + tb || + '.id, ' || tb || '.parent_id + from ' || + tb || + ' + inner join tmp on ' || + tb || + '.id = tmp.parent_id) + +select array_agg(id) +from tmp '; + + if not includeSelf + then + sql = sql || ' where id != $1'; + end if; + + execute sql into ans using id; + + + return ans; +end +$$ language plpgsql +; \ No newline at end of file