Browse Source

feat: 引入jpa多租户

多租户查询时,使用aop处理;新增,修改使用Hibernate Filter处理
tiger 1 year ago
parent
commit
5b577e3b99

+ 17 - 2
iot-common/iot-common-dao/iot-common-model/src/main/java/cc/iotkit/model/system/SysDept.java

@@ -1,10 +1,16 @@
 package cc.iotkit.model.system;
 
+import cc.iotkit.common.tenant.dao.TenantAware;
+import cc.iotkit.common.tenant.listener.TenantListener;
+import cc.iotkit.model.BaseModel;
 import cc.iotkit.model.Id;
-import cc.iotkit.model.TenantModel;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.hibernate.annotations.Filter;
+import org.hibernate.annotations.FilterDef;
+import org.hibernate.annotations.ParamDef;
 
+import javax.persistence.EntityListeners;
 import java.io.Serializable;
 import java.util.Date;
 
@@ -15,7 +21,10 @@ import java.util.Date;
  */
 @EqualsAndHashCode(callSuper = true)
 @Data
-public class SysDept extends TenantModel implements Id<Long>, Serializable {
+@FilterDef(name = "tenantFilter", parameters = {@ParamDef(name = "tenantId", type = "string")})
+@Filter(name = "tenantFilter", condition = "tenant_id = :tenantId")
+@EntityListeners(TenantListener.class)
+public class SysDept extends BaseModel implements Id<Long>, Serializable, TenantAware {
     private static final long serialVersionUID = 1L;
 
     /**
@@ -73,4 +82,10 @@ public class SysDept extends TenantModel implements Id<Long>, Serializable {
      */
     private Date createTime;
 
+    /**
+     * 租户编号
+     */
+    private String tenantId;
+
+
 }

+ 10 - 5
iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbSysConfig.java

@@ -1,16 +1,18 @@
 package cc.iotkit.data.model;
 
+import cc.iotkit.common.tenant.dao.TenantAware;
+import cc.iotkit.common.tenant.listener.TenantListener;
 import cc.iotkit.model.system.SysConfig;
 import io.github.linpeilie.annotations.AutoMapper;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.hibernate.annotations.Filter;
+import org.hibernate.annotations.FilterDef;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.ParamDef;
 
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
 
 /**
  * 参数配置表 sys_config
@@ -23,7 +25,10 @@ import javax.persistence.Table;
 @Entity
 @Table(name = "sys_config")
 @AutoMapper(target = SysConfig.class)
-public class TbSysConfig extends BaseEntity {
+@FilterDef(name = "tenantFilter", parameters = {@ParamDef(name = "tenantId", type = "string")})
+@Filter(name = "tenantFilter", condition = "tenant_id = :tenantId")
+@EntityListeners(TenantListener.class)
+public class TbSysConfig extends BaseEntity implements TenantAware {
 
     /**
      * 参数主键

+ 10 - 5
iot-common/iot-common-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/model/TbSysDept.java

@@ -1,18 +1,20 @@
 package cc.iotkit.data.model;
 
 import cc.iotkit.common.constant.UserConstants;
+import cc.iotkit.common.tenant.dao.TenantAware;
+import cc.iotkit.common.tenant.listener.TenantListener;
 import cc.iotkit.model.system.SysDept;
 import io.github.linpeilie.annotations.AutoMapper;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.hibernate.annotations.Filter;
+import org.hibernate.annotations.FilterDef;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.ParamDef;
 
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
 
 /**
  * 部门表 sys_dept
@@ -26,7 +28,10 @@ import javax.persistence.Table;
 @Table(name = "sys_dept")
 @AutoMapper(target = SysDept.class)
 @ApiModel(value = "部门表")
-public class TbSysDept extends BaseEntity {
+@FilterDef(name = "tenantFilter", parameters = {@ParamDef(name = "tenantId", type = "string")})
+@Filter(name = "tenantFilter", condition = "tenant_id = :tenantId")
+@EntityListeners(TenantListener.class)
+public class TbSysDept extends BaseEntity implements TenantAware {
     private static final long serialVersionUID = 1L;
 
     /**

+ 1 - 0
iot-common/iot-common-tenant/src/main/java/cc/iotkit/common/tenant/dao/TenantAware.java

@@ -1,5 +1,6 @@
 package cc.iotkit.common.tenant.dao;
 
+
 public interface TenantAware {
     void setTenantId(String tenantId);
 }

+ 82 - 0
iot-common/iot-common-tenant/src/main/java/cc/iotkit/common/tenant/entiry/BaseTenantEntity.java

@@ -0,0 +1,82 @@
+package cc.iotkit.common.tenant.entiry;
+
+import cc.iotkit.common.tenant.dao.TenantAware;
+import cc.iotkit.common.tenant.listener.TenantListener;
+import lombok.Data;
+import org.hibernate.annotations.Filter;
+import org.hibernate.annotations.FilterDef;
+import org.hibernate.annotations.ParamDef;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.annotation.LastModifiedDate;
+
+import javax.persistence.Column;
+import javax.persistence.EntityListeners;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 类描述...
+ *
+ * @author Tiger Chen
+ * created on 2023/7/15 20:53
+ */
+
+
+@MappedSuperclass
+@Data
+@FilterDef(name = "tenantFilter", parameters = {@ParamDef(name = "tenantId", type = "string")})
+@Filter(name = "tenantFilter", condition = "tenant_id = :tenantId")
+@EntityListeners(TenantListener.class)
+public abstract class BaseTenantEntity implements TenantAware, Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    private Long id;
+
+    @Size(max = 30)
+    @Column(name = "tenant_id")
+    private String tenantId;
+
+    /**
+     * 创建部门
+     */
+    private Long createDept;
+
+    /**
+     * 创建者
+     */
+    @CreatedBy
+    @Column(name = "create_by", updatable = false)
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    @CreatedDate
+    @Column(name = "create_time", updatable = false)
+    private Date createTime;
+
+    /**
+     * 更新者
+     */
+    @LastModifiedBy
+    @Column(name = "update_by")
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    @LastModifiedDate
+    @Column(name = "update_time")
+    private Date updateTime;
+
+    public BaseTenantEntity(String tenantId) {
+        this.tenantId = tenantId;
+    }
+
+}

+ 0 - 20
iot-common/iot-common-tenant/src/main/java/cc/iotkit/common/tenant/exception/TenantException.java

@@ -1,20 +0,0 @@
-package cc.iotkit.common.tenant.exception;
-
-
-import cc.iotkit.common.exception.BizException;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 租户异常类
- *
- * @author Lion Li
- */
-@EqualsAndHashCode(callSuper = true)
-@Data
-public class TenantException extends BizException {
-
-    public TenantException(Integer code, String message) {
-        super("tenant", code, message);
-    }
-}

+ 5 - 0
iot-common/iot-common-tenant/src/main/java/cc/iotkit/common/tenant/listener/TenantListener.java

@@ -3,7 +3,9 @@ package cc.iotkit.common.tenant.listener;
 
 import cc.iotkit.common.satoken.utils.LoginHelper;
 import cc.iotkit.common.tenant.dao.TenantAware;
+import lombok.extern.slf4j.Slf4j;
 
+import javax.persistence.PostLoad;
 import javax.persistence.PrePersist;
 import javax.persistence.PreRemove;
 import javax.persistence.PreUpdate;
@@ -15,14 +17,17 @@ import javax.persistence.PreUpdate;
  * created on 2023/7/14 20:50
  */
 
+@Slf4j
 public class TenantListener {
 
     @PreUpdate
     @PreRemove
     @PrePersist
+    @PostLoad
     public void setTenant(TenantAware entity) {
 
         final String tenantId = LoginHelper.getTenantId();
+        log.info("Hibernate 监听器,设置租户ID:{}", tenantId);
         entity.setTenantId(tenantId);
     }
 }

+ 4 - 4
iot-module/iot-system/src/main/java/cc/iotkit/system/controller/SysOssConfigController.java

@@ -14,11 +14,9 @@ import cc.iotkit.system.service.ISysOssConfigService;
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Controller;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
@@ -32,6 +30,8 @@ import java.util.List;
 @Validated
 @RequiredArgsConstructor
 @RestController
+@Controller
+@ResponseBody
 @RequestMapping("/resource/oss/config")
 public class SysOssConfigController extends BaseController {
 

+ 31 - 0
iot-starter/pom.xml

@@ -213,7 +213,26 @@
       <groupId>cn.hutool</groupId>
       <artifactId>hutool-core</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.aspectj</groupId>
+      <artifactId>aspectjrt</artifactId>
+
+    </dependency>
+    <dependency>
+      <groupId>org.aspectj</groupId>
+      <artifactId>aspectjtools</artifactId>
+
+    </dependency>
+    <dependency>
+      <groupId>org.aspectj</groupId>
+      <artifactId>aspectjweaver</artifactId>
 
+    </dependency>
+    <dependency>
+      <groupId>org.assertj</groupId>
+      <artifactId>assertj-core</artifactId>
+
+    </dependency>
 
   </dependencies>
 
@@ -269,6 +288,18 @@
           </execution>
         </executions>
       </plugin>
+
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+        <configuration>
+          <agents>
+            <agent>${project.build.directory}/spring-instrument-${spring-framework.version}.jar</agent>
+            <agent>${project.build.directory}/aspectjweaver-${aspectj.version}.jar</agent>
+          </agents>
+        </configuration>
+      </plugin>
+
     </plugins>
   </build>
 

+ 4 - 1
iot-starter/src/main/java/cc/iotkit/Application.java

@@ -14,7 +14,9 @@ import cc.iotkit.config.EmbeddedRedisConfig;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
 import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.EnableLoadTimeWeaving;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 
@@ -23,7 +25,8 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 @EnableTransactionManagement
 @EnableWebMvc
 @EnableFeignClients(basePackages = {"cc.iotkit.baetyl.feign"})
-public class Application {
+@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
+public class Application extends SpringBootServletInitializer {
 
     public static void main(String[] args) {
         System.setProperty("disabledEmbeddedEs", "true");

+ 12 - 0
iot-starter/src/main/resources/META-INF/aop.xml

@@ -0,0 +1,12 @@
+<aspectj>
+
+    <weaver options="-Xreweavable -Xset:weaveJavaxPackages=true">
+        <include within="cc.iotkit.common.tenant.aspect.TenantFilterAspect"/>
+        <include within="org.hibernate.internal.SessionFactoryImpl.SessionBuilderImpl"/>
+    </weaver>
+
+    <aspects>
+        <aspect name="cc.iotkit.common.tenant.aspect.TenantFilterAspect"/>
+    </aspects>
+
+</aspectj>

+ 10 - 1
pom.xml

@@ -3,11 +3,20 @@
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.7.11</version>
+        <relativePath/>
+    </parent>
+
     <groupId>cc.iotkit</groupId>
     <artifactId>iotkit-parent</artifactId>
     <version>${revision}</version>
     <name>${project.artifactId}</name>
-    <description>奇特物联是一个开源的物联网基础开发平台,提供了物联网及相关业务开发的常见基础功能, 能帮助你快速搭建自己的物联网相关业务平台。</description>
+    <description>奇特物联是一个开源的物联网基础开发平台,提供了物联网及相关业务开发的常见基础功能,
+        能帮助你快速搭建自己的物联网相关业务平台。
+    </description>
     <url>https://gitee.com/iotkit-open-source/iotkit-parent</url>
     <packaging>pom</packaging>